Archive for the 'Aplicaciones Distribuidas' Category

Armando una Blockchain (9)

Tuesday, May 17th, 2016

Anterior Post
Siguiente Post

Ya estuve publicando detalles de mi proyecto personal de blockchain escrito en C#:

https://github.com/ajlopez/BlockchainSharp

Esta semana comencé otra implementación, esta vez usando JavaScript/NodeJS:

https://github.com/ajlopez/SimpleBlockchain

Es interesante comparar las dos implementaciones, una en un lenguaje tipado y otra en un lenguaje dinámico.

Al igual que en C#, los conceptos bases a implementar son: bloques, transacciones, una blockchain, etc…. Estoy escribiendo el código usando el flujo de trabajo de TDD (Test-Driven Development), como es habitual, para practicar esa disciplina cada dia. La idea es implementar esas entidades de base, y entonces, escribir código de un servidor que pueda comunicarse con otros servidores en una red. Quiero usar mensajes JSON en este proyecto (en C# pienso usar corrientes de bytes sobre sockets). Igual el formato es una decisión que puede cambiar, y sin mayor costo o esfuerzo. Por ahora, necesito implementar la conducta de base, cubierta por los correspondientes tests.

Estos son, por ejemplo, algunos tests de creación de bloques:

exports['create genesis block'] = function (test) {
    var block = blocks.block();
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 0);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, '0x000....000000');
}

exports['create child block'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block(genesis);
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 1);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, genesis.hash);
}

exports['create child block with initial data'] = function (test) {
    var genesis = blocks.block();
    var block = blocks.block({ extra: 'hello' }, genesis);
    
    test.ok(block);
    test.equal(typeof block, 'object');
    test.equal(block.number, 1);
    test.ok(isHash(block.hash));
    test.ok(isHash(block.parentHash));
    test.equal(block.parentHash, genesis.hash);
    test.equal(block.extra, 'hello');
}

Escribo esos tests, uno por uno, y luego de cada test, escribo el código de producción más simple que hace que el test pase. De esa manera, voy avanzando siempre sobre una solución simple a la conducta esperada. Y si luego se me ocurre una mejor implementación, puedo refactorizar y hasta rediseñar, sabiendo que la conducta no cambia ejecutando los tests. Tanto la simplicidad obtenida como la facilidad para el cambio me parecen grandes aportes de seguir este flujo de trabajo.

Despues de las entidades de base, necesito algunas entidades auxiliares, especialmente para permitir el proceso eficiente de bloques y transacciones. Una de esas entidades ayudantes es un almacén de bloques: un lugar donde guardar y recuperar bloques, por hash, hash padre, número. Siguiendo el principio de simplicidad, por ahora tengo una implementación en memoria, vean algunos tests:

exports['create store'] = function (test) {
    var store = stores.blockstore();
    
    test.ok(store);
    test.equal(typeof store, 'object');
};

exports['retrieve unknown block by hash'] = function (test) {
    var store = stores.blockstore();
    
    var block = store.getByHash(utils.hash());
    
    test.equal(block, null);
};

exports['save block and retrieve it by hash'] = function (test) {
    var store = stores.blockstore();
    var hash = utils.hash();
    var block = { hash: hash };
    
    store.save(block);
    
    var result = store.getByHash(hash);
    
    test.ok(result);
    test.equal(result.hash, hash);
};

Voy a seguir trabajando en ambos proyectos: el de C# necesita mejorar el proceso de bloques, y algo de implementación de servidor de red. Con el de JavaScript posiblemente llegue primero a implementar nodos corriendo en red, sin transacciones, bloques vacios intercambiándose entre pares, formando una blockchain por consenso. Algo lindo de la implementación de JavaScript es que no tengo que preocuparme por la concurrencia de varios threads. Puedo, por ejemplo, cambiar la estructura de la blockchain sin preocuparme que otros threads esten ingresando al mismo tiempo a consultarla o actualizarla.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Programando para Internet of Things

Sunday, February 8th, 2015

Como saben, siempre practico programar todos los días, especialmente aplicando TDD (Test-Driven Development). Y si bien hay proyectos no públicos, la mayor parte de esa práctica la pueden ver en mi cuenta pública de GitHub. Y como escribí en el post de ayer, Node.js es una tecnología muy interesante, por su poder y simplicidad, para implementar muchas ideas que en otras tecnologías (Java, .NET, Scala, Ruby, Python, Clojure, Smalltalk) no me parece que sea tan fácil (aclaro lo de siempre: el precio a pagar por programar en el paraíso de Node.js son los “callbacks”).

Hay muchas ideas e implementaciones interesantes (en aplicaciones, proyectos, “startups”) dando vueltas. Pero un tema interesante que ya está entre nosotros, pero que va ir creciendo todavía más, es el tema Internet of Things. ¿Habrá lugar para que “startups” puedan luchar e imponerse en este campo? ¿será deglutido por Google, Apple, Microsoft? Veremos. Pero independientemente de eso, es época para programar e implementar ideas, en código abierto. Si se puede montar una “startup” encima de eso, mejor (pienso que para una “startup” lo principal es la EJECUCION: ideas hay a millones, e implementaciones hay a miles).

Mientras, algunas ideas (con alguna implementación incipiente en mis proyectos públicos de GitHub, ya vieron algunas ideas e implementaciones en mis charlas) (por supuesto, hay YA implementaciones, y también “startups”, pero siempre es interesante explorar por uno mismo un campo):

– Recolectar información de dispositivos, conectados a la red. Tener un repositorio de datos, enviados desde un SDK cliente para cada dispositivo. Luego, explotar esos datos.

– Aplicar Inteligencia Artificial (bueno, es un término amplio, lo admito, pero el mejor que tenemos por ahora) a todos esos datos, descubriendo patrones, aplicando “machine learning”, “deep learning”. Hábrán visto algunas implementaciones en JavaScript en mis proyectos

– Tomar decisiones, usando sistemas expertos u otros, y ejecutar comandos, acciones. De nuevo, habrán visto implementaciones mías en JavaScript/Node.js. Tener algo como IFTTT abierto, listo para usar, alimentado por eventos y datos colectados de Internet of Things.

– Aplicar para todo esto, computación distribuida, no solamente escalabilidad horizontal transparente en la nube. Hay mil estrategias para implementar, y Node.js es un vehículo interesante para experimentar. Luego, se puede pasar a un lenguaje y tecnología compilado, si hace falta ganar en rendimiento de serialización, por ejemplo.

Disculpen la auto-referencia a proyectos míos, pero quería pasar en limpio el panorama por el cual estoy haciendo esos proyectos.

Y además, me diviegto como logco! 🙂

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez