Tech roundup 1: a journal published by a bot

Read a tech roundup with this week’s news that our powerful bot has chosen: blockchain, AI, development, corporates and more.

Gooooooood morning, Y’all!!! Hey, this is not a test, this is a tech roundup. Time to rock it from the Delta to the DMZ.

AI, bots and robots

Blockchain and decentralization

Woman computer scientist of the week
Carolina Cruz-Neira is a Spanish-Venezuelan-American computer engineer, researcher, designer, educator, and a pioneer of virtual reality (VR) research and technology. She is known for inventing the CAVE automatic virtual environment. She previously worked at Iowa State University (ISU), University of Louisiana at Lafayette and is currently the director of the Emerging Analytics Center at the University of Arkansas at Little Rock.

Cloud and architecture

Development and languages

Quote of the week

The best code is no code at all.

Enterprises

Other news

[jetpack_subscription_form]

Get to the point with Solidity

As I explained in my previous post about coding for Ethereum, there are a lot of ways to learn Solidity. However, most of them are really humdrum if you already know how to code, almost if you know javascript. So, let’s get to the point with Solidity looking the simplest structures you need to start coding.

ethereum photo

Solidity is based on javascript, but it also owns structures from other functional languages like Haskell and from object-oriented languages like Java. To do Dapps you need more than knowing the language because you need to know about patterns, security, how to compile and publish, and what actions cost more gas than others. Also, Solidity owns more reserved words than the explained below and more complex structures like inserting assembly inline, but with a little base of javascript and reading the following script (just 242 lines) you will be ready to start the backend of your very own distributed application over the Ethereum Virtual Machine.

pragma solidity ^0.4.19; //Version of the compiler

import "./otherContractsFile.sol";

contract ContractName { //Declaration of the basic unit of code
   /***Variables and funtions***/
   bool boolVariable;
   uint unsignedIntVariable;
   int intVariable;
   int intVariableWithValue = 10;
   uint16 unsigned16BitInt;
   uint256 unsignedIntVariable2;
   ufixed unsignedFixedVariable;
   fixed128x19 fixedVariableWith128bitsAnd19DecimalPoints;
   string stringVariable = "It can store any UTF-8 encoded string";
   address addressVariable; //addresses are used to store user accounts and contracts identifiers
   var aVariable = intVariableWithValue; //aVariable is defined as an int variable
   uint constant lustrum = 5 years;

   /*State variables are permanently stored in the EVM
    *between external function calls for this contract. 
    */
   uint stateVariable;

   function doSomething(uint uintParam) {
      /*Variables declared inside functions
       *are stored in memory and they are reset 
       *between different calls to the function.
       */
      uint functionVariable;
      
      functionVariable++;
      stateVariable = stateVariable + functionVariable;
      /*functionVariable = 1
       *stateVariable = 1 the first time this function is executed,
       *2 the second time this functions is executed, 3 the third, ...
       */
   }

   /***Collections and your own types***/
   uint[2] fixedArray;
   uint[] dynamicArray;
   mapping (address => uint) mapFromAddressToUint;

   enum EnumType {
      FirstValue,
      SecondValue,
      ThirdValue
   }

   struct StructType {
      uint uintField;
      string stringField;
   }
   StructType structVariable;
   StructType structVariableWithValue = StructType(10, "something");
   StructType[] structArray;

   function manageStructArrayByValue() {
      /*This variable is asigned by value (a copy is done)*/
      StructType memory myStruct = structArray[0]; 
      myStruct.uintField = 10; //structArray[0].uintField = 0;
   }

   function manageStructArrayByReference() {
      /*This variable is asigned by reference (a pointer is created)*/
      StructType storage myStruct = structArray[0]; 
      myStruct.uintField = 10; //structArray[0].uintField = 10;
   }

   uint[] public publicArray; //A public array is read-only publicly accessible by other contracts
   mapping (uint => string) public publicMap;

   function workWithArrays() private {
      uint[] myArray;
      myArray.push(1); //myArray = [1]
      myArray.push(2); //myArray = [1,2]
      uint newLenth = myArray.push(1); //newLenth = 3, myArray = [1,2,1] 
   }

   /*Functions are public by default, so you need to set them private
    *in order to keep your contract secure. In other case, functions
    *can be called (and executed) by other contracts.
    */
   function doSomethingPrivate(uint uintParam) private {
      //some code
   }

   /*Internal functions are functions that can be called from
    *contracts that inherit from this one.
    */
   function doSomethingInternal(uint uintParam) internal {
       //some code
   }

   /*Public functions can be called from anywhere.*/
   function do(uint param) public {
      //some code
      doSomethingPrivate(param);
      doSomethingInternal(unsignedIntVariable);
      doSomethingPrivate(10); //Can't call to doSomethingExternal
   }

   /*External functions can be called from external contracts
    *but not from inside this contract.
    */
   function doSomethingExternal(uint param) external {
      //some code
   }

   function ContractName() public { //this is a constructor but be carefull using them, they are not executed in some special cases
      //do something
   }

   function return10() returns (uint) {
      return 10;
   }

   function returnMultipleValues() returns (uint value1, uint value2) {
      value1 = 10;
      value2 = 20;
   }

   function returnMultipleValues2() returns (uint, uint) {
      return(10, 20);
   }

   function useMultipleValues() {
      uint value1;
      uint value2;
      (value1, value2) = returnMultipleValues();

      uint value4;
      (,value4) = returnMultpleValues2();
   }

   /*function throwsAnError(int a) private returns (int8) {
    *   return a + 1;
    *}
    */

   function addAndConvert(int a) private returns (int8) {
      return int8(a) + 1; //uses the 8 less significant bits of a
   }

   function addAndConvertIfIsInt8(uint a) private returns (uint8) {
      require(a <= 2 ** 8); //Throws an error if false
      return uint8(a) + 1;
   }

   /***Events***/
   event sthOccurred(uint param);

   function throwEvent() private {
      sthOcurred(10);
   }

   /***Modifiers***/
   //"view" can be used to identify functions that are not changing any data
   function returnInt() public view returns (int) {
      return intVariable;
   }

   //"pure" can be used to identify functions that do not access any data in the contract
   function add(int a, int b) public pure returns (int) {
      return a + b;
   }

   //"payable" is needed in order to receive Ether with a call
   function aFunctionThatCost() public payable {
      //this contract will own the ether sended at the end of the execution
   }

   modifier myModifier() {
      //some code to be executed before the function
      _; //this is a placeholder that indicates the point where the code of the function will be executed
      //some code to be executed after the function
   }

   function functionWithModifier() public myModifier {
      //some code to be executed in the place where the placeholder is set inside modifier's code
   }

   function otherFunctionsAndValues() private {
      keccak256("qwerty"); //returns a 256-bit hexadecimal with a SHA3 hash of the param
      //"qwerty" == "QWERTY"; Solidity can't compare strings. Instead you can do
      keccak256("qwerty") != keccak256("QWERTY");

      uint currentUnixTimestamp = now;
      1 minutes == 60;
      1 hours == 3600;
      //you also have available "days", "weeks" and "years" units

      address currentBlocMiner = block.coinbase;
      uint currentBlockDifficulty = block.difficulty;
      uint currentBlockGasLimit = block.gaslimit;
      uint currentBlockNumber = block.number; 
      uint currentBlockUnixTimestamp = block.timestamp;
      bytes32 theHash = block.blockhash(block.number); //only works for 256 most recent blocks excluding current
      bytes completeCallData = msg.data;
      uint remainingGas = msg.gas;
      address callerWhoInitiatesThisExecution = msg.sender;
      bytes4 firstFourBytesOfMsgData = msg.sig;
      uint numberOfWei = msg.value;
      uint gasPriceOfTheTransaction = tx.gasprice;
      uint senderOfTheTransaction = tx.origin;

      assert(1==2); //like require but for internal errors
      revert(); //abort and revert changes
   }

}

/***Inheritance and rehusability***/
contract A {
   function aFunction {}
}

contract B is A {
   function bFunction {
      aFunction();
   }
}

/*If you want to use an external contract, you need to define an
 *interface with the definition of the methods that you want to
 *use.
 */
contract InterfaceOfExternalContract {
   function functionExternalDefinition(uint param) external return (uint);

   function functionPublicDefinition(uint param) public return (uint);
}

contract ContractWichUsesTheExternalContract {
   address externalContractAddress = 0x...;
   InterfaceOfExternalContract externalContract = InterfaceOfExternalContract(externalContractAddress);

   function aFunction() {
      uint value = externalContract.functionExternalDefinition(1);
   }
}

And now, what are you starting to code?

PoW vs PoS

Cuando hablamos del Cryptojacking y de la minería, pasamos de puntillas un concepto que afecta a como se valida cada uno de los bloques de un blockchain. Es la «prueba«, y aunque en la mayoría de blockchains se usa Proof of Work, son muchos los expertos que apuntan a la necesidad de pasar a blockchains que usen Proof of Stake. Veamos en que se diferencian y el porqué de la necesidad de este cambio.

military byzantine photo
Photo by Internet Archive Book Images

Aunque inicialmente pueda parecer algo super técnico, como habéis ido viendo en otros posts relacionados con el tema, los blockchains son sistemas realmente básicos, aunque se tiene que enfrentar a los problemas típicos de los sistemas distribuidos que ya vimos cuando tratamos los patrones cloud.

En concreto, estas pruebas son soluciones al problema de consenso que normalmente se ejemplifica con el problema de los generales bizantinos. En este problema se busca la coordinación de varios jefes militares que intentan atacar o retirarse de un modo conjunto. Su aplicación mediante estas «pruebas» a los blockchains, sirve para la toma de decisiones en un entorno distribuido como este.

La prueba de trabajo (Proof of Work), se basa en el cálculo de un hash que «cierre» el bloque. Por tanto, el sistema que encuentra el hash valido es el que tiene la última palabra en cuanto a las operaciones registradas en dicho bloque.

Pongamos que hay un blockchain en el que participan Alberto, Braulio, Carlos, Diego y Esteban. Cada uno le manda al siguiente en la lista una moneda, pero Carlos no se ha enterado de que Esteban le ha mandado una moneda a Alberto. A la hora de minar, todos se ponen a buscar un hash de un bloque que almacenará 5 operaciones, menos Carlos que sólo ha recibido información de 4. Si el primero en lograr su trabajo es Diego, el hash que encuentre será de las 5 operaciones y por tanto las 5 quedarán confirmadas. Por el contrario, si quien logra dicha labor es Carlos, sólo 4 operaciones quedarán confirmadas y el envío de Esteban a Alberto deberá volver a realizarse.

En este tipo de pruebas toma la decisión el primero que consigue realizar un trabajo más o menos complejo como es el cálculo de ese hash.

La prueba de participación (Proof of Stake), se basa en la participación de los distintos componentes en el sistema. Depende del blockchain se tienen unas normas u otras (aunque podéis entrar en detalle en como será Ethereum cuando pase a PoS), pero en general se presupone que los elementos más partícipes (porque tengan más dinero, hagan más operaciones, etc.) son los principales interesados en que todo funcione correctamente y se haga del modo más limpio. Por tanto, estos se convierten en validadores que pueden recibir el «honor» de dar por bueno un bloque ya sea de manera aleatoria, rotativa, por votación…

De nuevo pensemos en un blockchain, pero en este participan Alba, Barbara, Carla, Diana y Ester. Cada una tiene el doble de monedas que la anterior en este blockchain, que está «gobernado» por un PoS en el que determina el bloque quien más dinero tenga. Si en cada transacción cada una le envía a la anterior la mitad de sus monedas, el primer bloque lo decidirá Ester, pero el segundo lo decidirá Diana por ser la nueva mayor participante. Por tanto, primero Ester y después Diana serán quienes decidan que operaciones quedan confirmadas, asumiéndose que al ser las mayores poseedoras de esta criptomoneda, son también las principales interesadas en que funcione bien y sea un sistema de fiar.

Aunque los dos tipos de prueba tienen sus cosas buenas y malas, hay una en la que PoS gana de calle a PoW y que nadie podrá rebatir. Es el consumo de electricidad gastado para realizar estos trabajos. Con cada bloque de la cadena todos los mineros se ponen a buscar el hash que toque, pero sólo uno lo consigue, por lo que todo el tiempo de cálculo anterior ha sido completamente inútil para todos menos uno. Por ejemplo, si atendemos a los Bitcoins, el consumo energético de este blockchain es similar al de Nigeria, o la electricidad que se emplea para una sola transacción de Bitcoin serviría para proveer a una casa durante un mes.

Espero haberos explicado de un modo suficientemente claro estos conceptos y el porqué de este debate, como para que podáis entrar en él. ¿Hay algún concepto que creáis que es importante aclarar?

Cryptojacking: la minería de cryptomonedas como modelo de negocio

Estoy seguro de que muchos habéis pensado en usar el cryptojacking como modelo de negocio –las ideas suelen surgir simultáneamente en muchas cabezas a la vez- cuando hayáis visto noticias sobre cryptojacking, como el sonado caso de la CBS que durante un fin de semana tuvo incluido en su reproductor un script para minar cryptomonedas. ¿Pero es realmente factible? Entendámoslo y observemos sus implicaciones.

web coin photo
Photo by SMU Central University Libraries

El cryptojacking es un concepto más o menos novedoso, que se refiere a realizar minería de cryptomonedas usando para el computo los navegadores de visitantes a una web. Normalmente se supone poco ético, pero vayamos por partes que hay muchos conceptos:

  • Recordaréis cuando hablamos de blockchain, a las personas que se dedican a calcular los hash de los bloques se les llama mineros, porque el algoritmo les otorga una pequeña cantidad de cryptomoneda a quienes encuentran cada hash.
  • Para realizar esa minería, para buscar esos hash hay que realizar muchos cálculos invirtiendo en tiempo de procesador. Hay empresas que se dedican a la minería y que tienen montones de ordenadores (granjas) dedicados a realizar estos cálculos.
  • Una web, es una aplicación distribuida en la que parte del programa se ejecuta en el servidor, y otra parte se ejecuta en el navegador de los usuarios.
  • Cuando se usa la capacidad de computación de los visitantes a una web, para realizar minería, es cuando estamos hablando de cryptojacking.

En casi todos los casos en los que se habla de cryptojacking se trata (o al menos se supone) de webs que han sido crackeadas, en las que se ha incluido el código necesario para realizar la minería, pero ¿y si no siempre fuese así? ¿Y si una web de manera legítima implementara este sistema de minería para financiarse? ¿Qué podría pasar?

Esta técnica hace que se consuman recursos de los equipos de los visitantes, pero por norma general, la mayoría de los visitantes tienen recursos más que sobrados en sus sistemas que están muy infrautilizados. Al final es como los sistemas para compartir potencia para cálculos distribuidos, ya sea para encontrar una cura para el cancer o buscar vida fuera de nuestro planeta. Los usuarios le estarían cediendo sus recursos a una web durante el tiempo que se pasen consumiendo sus contenidos.

Si esto se usase como sustitutivo de los anuncios (que cada vez funcionan menos y peor en la web actual), no les supondría una gran carga adicional a los usuarios, puesto que los anuncios por si mismos ya están consumiendo recursos de sus máquinas. Además dejarían de estorbar visualmente.

También, se implementarían las webs para que tuviesen la menor cantidad de recargas, y para que se pase el mayor tiempo posible con ella abierta. Por ejemplo, en una web de noticias, esto es posible que provocase que se empezaría a dejar de lado el clickbait y empezar a crear contenidos realmente relevantes e interesantes.

Para saber si es algo rentable, tendríamos que tener en cuenta muchos factores, principalmente el valor puntual de la cryptomoneda que se esté empleando. También de cuanta cantidad de cryptomoneda se  lleva el minero que tenga éxito en encontrar el hash de un bloque. Por último, cuanto tiempo medio de visitante en la página se necesita para encontrar un hash. Podríamos meter más variables como el coste de adquisición de un usuario, lo que se deje de ingresar por publicidad o muchas otras cosas, pero sólo con estas tres variables ya se ve que hay que centrarse en un caso particular para determinar si es rentable o no.

Por ejemplo, cada vez que se encuentra un hash de un bloque de Bitcoin, el minero se lleva 12.5 Bitcoins (aunque se dividirá por dos en el futuro). El precio de los Bitcoin es muy variable, pero hace ya días que está por encima de los $5,500. Por tanto, estamos hablando de más de $70,000. Por ejemplo, atendiendo a las cuentas públicas de un medio que conozco bien, les bastaría con conseguir minar un hash a la semana para ser rentables y olvidarse de la guerra de la publicidad.

Lo difícil es saber como de factible es que un sistema distribuido como este consiga minar uno de estos hash, pero desgraciadamente de eso no hay muchos datos y tendremos que esperar a que algún medio con suficiente calado se anime a hacer pruebas legítimas y en condiciones, y que posteriormente se animen a compartir esa información.

¿Cómo lo veis como usuarios? ¿Os preocuparía que se usase vuestro equipo para esto si a cambio os libraseis de la fastidiosa publicidad?

Blockchain fácil fácil

Ya son varias las personas de distinto ámbito que me han pedido una explicación sencilla de lo que es Blockchain, así que supongo que es un tema que debo plasmar aquí, y dejar de contarlo entre cervezas. Voy a intentar que cualquier persona con una base técnica mínima pueda entenderlo, pero ante las dudas preguntad en los comentarios 😉

blockchain photo
Photo by btckeychain ©

Blockchain, como su propio nombre indica, es una cadena de bloques. En cada bloque se almacena una información y el hash del bloque anterior (¿os acordáis de la explicación sobre lo que es un hash de la semana pasada?).

De este modo, al almacenar cada bloque la «firma» del anterior, si se cambiase el contenido de un bloque se alteraría esa firma, con lo que habría que cambiar el contenido del siguiente bloque, y así sucesivamente hasta llegar al bloque más actual.

Eso, así de simple es un blockchain.

Ahora bien, seguro que habéis oído que este sistema se está usando en criptomonedas y en otras soluciones porque se supone que no se puede alterar los bloques ¿no?

En un blockchain que se almacenase en un solo lugar sería «trivial» alterar el contenido de un bloque random. Sin embargo, todos los sistemas que se están basando en esto son sistemas distribuidos, en los que hay muchos participantes que mantienen una copia de toda la cadena de bloques, por lo que para poder alterarla sin que todo el mundo se de cuenta, no sólo habría que modificar todos los bloques que maneje una máquina, si no que habría que hacerlo en todas las máquinas que almacenan una copia.

Vamos a poner un ejemplo práctico aplicado a algo que muchos habréis sufrido:

  • Imaginemos que tenemos un cuaderno en el que vamos a apuntar el acta de las reuniones de una comunidad de vecinos.
  • Para que no haya alteraciones, decidiremos que cada página tiene que empezar siempre con el «hash» de la página anterior.
  • El hash en este caso (para que sea fácil de calcular a mano), estará formado por la primera y última letra de cada fila y entre ambas el número de caracteres.
  • De este modo, si cambiásemos una página cambiaríamos su hash, que al ser la primera línea de la página siguiente, nos provocaría también cambiar su hash, etc. etc.
  • Un presidente maquiavélico podría comprarse un nuevo cuaderno para cambiar todas las actas y plasmar que a él se le eligió de por vida. Pero, si todos los propietarios tuviesen una copia del cuaderno, el presidente no podría hacerlo a no ser que pudiese entrar en todas las casas de todos los vecinos a pegar el cambiazo por un cuaderno modificado.

¿Queda claro?

Las aplicaciones de esto pueden ser muchas, aunque generalmente se usa para crear soluciones que eliminen intermediarios.

Por ejemplo, es la base de Bitcoin, la primera criptomoneda que se creo para poder hacer micropagos. El problema de los micropagos, era que al tener a los bancos como entidades intermediarias, las comisiones hacían imposible realizar estos micropagos. Al eliminar los intermediarios, los pagos pueden ser gratuitos, y hacerlos tan pequeños como se quiera.

Esa es la teoría, porque Bitcoin se ha expandido mucho por otros motivos derivados de la eliminación de intermediarios (anonimato, capacidad de especulación desmesurada, acceso universal, …), pero eso ya es otra historia que tendrá que ser contada en otro momento.

Explicación fácil de lo que es un «hash»

Si nos pusiéramos muy técnicos tendríamos que hablar de qué y cómo son las funciones hash, pero no es el día. Saber que son los hash es necesario si queremos hablar de Blockchain, de BigData, y de muchas otras moderneces con propiedad. Pero no es necesario entrar en detalles ni ponerse muy técnico para entender lo que son y como se usan. Vamos pues.

byte photo

Aquí ya hablamos de las tablas Hash, que son un patrón de diseño de sistemas distribuidos. Pero más allá de eso se usan en montones de estructuras de datos, de algoritmos y demás.

El hash es como se llama coloquialmente al resultado de una función hash, y estas son funciones que se encargan de transformar un conjunto de datos en una simple cadena de texto. Digamos que el hash es como una firma que resume a todo un conjunto de datos.

Por ejemplo, imaginemos que yo tengo un boli Bic azul comprado ayer mismo. Su hash podría ser (por ejemplo, el proporcionado por una función recién ejecutada en mi mente) BBA20170703005301058. Si aplicásemos la misma función a cualquier otro boli nos daría un valor distinto y si se la volviésemos a aplicar a ese mismo boli nos volvería a dar este valor.

¿Y esto para que sirve? Por ejemplo, si algún malvado villano me escondiese mi boli entre un millón de otros bolis similares (todos Bic azul), sólo tendría que aplicar esta función a cada boli hasta encontrar el que tiene esa firma para saber que es el mío. Otra función sería, si castigásemos a nuestro villano favorito a ordenar todos los bolis en un gran almacen, este podría ir apuntando la firma de cada boli con la estantería en la que lo guarda para luego poder encontrarlos de un modo rápido y fácil.

Estas, a bote pronto, son las funciones principales que se me ocurren (demostrar autenticidad y conseguir indexación), pero es muy posible que se usen estos códigos en muchos otros ámbitos que a mi ahora no me vienen a la cabeza. ¿Tenéis vosotros en mente otros ejemplos?

Lo normal, es que este tipo de funciones tengan en cuenta todo el conjunto de datos, o todas las características del objeto sobre el que se aplica, de tal modo que si el villano hubiese sido tan perverso de cambiar el capuchón de mi boli por el de otro, habría conseguido vencerme, pues la función hash que yo había ideado ya no proporcionaría el mismo valor.

Depende de para que se use, podemos encontrarnos con problemas, ya que puede ocurrir que haya colisiones y que, por una alineación de los astros, para dos objetos distintos se obtenga el mismo hash.

Sin embargo, a pesar de esas posibles colisiones, al ser (normalmente) el resultado de un algoritmo de compresión con pérdida, de un hash no se puede obtener el objeto original invirtiendo la función, así que será muy difícil encontrar para un hash un objeto o conjunto de datos válido que pueda sustituir al original como auténtico sin serlo. Esta es la clave, por ejemplo, de su uso dentro de los blockchains, pero eso ya es otra historia que deberá ser contada en otro momento.