Construye con Javascript una blockchain basica. Parte 3

registrando mineros y creando nuevos bloques

En este punto, ya tienes una red P2P básica y puedes conectarse a los peers en la red, creando un bloque de génesis y envíando y recibiendo bloques. El siguiente paso es poder generar nuevos bloques. Como viste en un post anterior, la prueba de trabajo se basa en la solucion de un problema matemático, recompensando al minero que encuentra primero la solución al problema. Sin embargo, en este post, adoptaremos un enfoque Prueba de participacion (PoS) en el que confíamos en cada minero para generar sus bloques. Cada peer se registrará como minero y tomará un turno para minar un bloque. Puedes ver una descripción general de cada minero generando un bloque abajo:

La blockchain maneja el minado usando un simple mecanismo PoS

Ahora vamos a registrar a sus peers como mineros y crearemos nuevos bloques. Para automatizar el proceso de generar un bloque cada x número de minutos, puedes usar una biblioteca Node.js llamada cron, que es similar a la de Linux que automatiza tareas. Para instalar la libreria cron de código abierto, ejecute el siguiente comando:

> npm install cron --save

A continuación, en su archivo p2p.js, creará dos variables para realizar un seguimiento de los mineros registrados, así como quién extrajo el último bloque para que pueda asignar el
siguiente bloque al siguiente minero.

let registeredMiners = [];
let lastBlockMinedBy = null;

También agregará dos tipos de mensajes:

• REQUEST_ALL_REGISTER_MINERS
• REGISTER_MINER

let MessageType = {
 REQUEST_BLOCK: 'requestBlock',
 RECEIVE_NEXT_BLOCK: 'receiveNextBlock',
 RECEIVE_NEW_BLOCK: 'receiveNewBlock',
 REQUEST_ALL_REGISTER_MINERS: 'requestAllRegisterMiners',
 REGISTER_MINER: 'registerMiner'
};

Antes de registrar a sus peers como mineros, solicitaremos recibir todos los mineros registrados existentes en la red, y luego agregaremos su peercomo un minero en un objeto registeredMiners. Lo haces ejecutando un temporizador para actualizar sus mineros cada cinco segundos.

setTimeout(function(){
writeMessageToPeers(MessageType.REQUEST_ALL_REGISTER_MINERS,
null);
}, 5000);

Ahora, esto apunta a un controlador para actualizar la lista de mineros registrados, también puede automatizar un comando para registra a tu peer como minero:

setTimeout(function(){
 registeredMiners.push(myPeerId.toString('hex'));
 console.log('----------Register my miner --------------');
 console.log(registeredMiners);
 writeMessageToPeers(MessageType.REGISTER_MINER,
registeredMiners);
 console.log('---------- Register my miner --------------');
}, 7000);

En el comando switch, deseamos modificar el código para poder configurar los handlers para mensajes entrantes relacionados con los registros de mineros. Deseas realizar un seguimiento de los mineros registrados, así como manejar un mensaje una vez se extrae un nuevo bloque.

case MessageType.REQUEST_ALL_REGISTER_MINERS:
 console.log('-----------REQUEST_ALL_REGISTER_
MINERS------------- ' + message.to);
 writeMessageToPeers(MessageType.REGISTER_MINER,
registeredMiners);
 registeredMiners = JSON.parse(JSON.stringify(message.
data));
 console.log('-----------REQUEST_ALL_REGISTER_
MINERS------------- ' + message.to);
 break;
 case MessageType.REGISTER_MINER:
 console.log('-----------REGISTER_MINER------------- ' +
message.to);
 let miners = JSON.stringify(message.data);
 registeredMiners = JSON.parse(miners);
 console.log(registeredMiners);
 console.log('-----------REGISTER_MINER------------- ' +
message.to);
 break;
console.log(`Connection ${seq} closed, peerId: ${peerId}`);
 if (peers[peerId].seq === seq) {
 delete peers[peerId];
 console.log('--- registeredMiners before: ' + JSON.
stringify(registeredMiners));
 let index = registeredMiners.indexOf(peerId);
 if (index > -1)
 registeredMiners.splice(index, 1);
 console.log('--- registeredMiners end: ' + JSON.
stringify(registeredMiners));
 }
});

A diferencia de Bitcoin, que genera un bloque cada 10 minutos, su blockchain se mejorará y generará un bloque cada 30 segundos. Para lograrlo, ya instalamos la libreria cron de código abierto para Node.js. La libreria cron funciona igual que el cron de Linux. Puede utilizar cron para establecer con qué frecuencia llamar al mismo código nuevamente, que se utilizará para llamar sus mineros cada 30 segundos. Para hacerlo, primero incluya la libreria en la declaración de importación de su código encima de
el archivo p2p.js.

let CronJob = require('cron').CronJob;

A continuación, puede configurar su cronjob para que se ejecute cada 30 segundos, y el comando job.start () iniciará el trabajo, como se muestra en el soguiente código:

const job = new CronJob('30 ∗ ∗ ∗ ∗ ∗', function() {
 let index = 0; // first block
 if (lastBlockMinedBy) {
 let newIndex = registeredMiners.indexOf(lastBlockMinedBy);
 index = ( newIndex+1 > registeredMiners.length-1) ? 0 :
newIndex + 1;
 }
 lastBlockMinedBy = registeredMiners[index];
 console.log('-- REQUESTING NEW BLOCK FROM: ' +
registeredMiners[index] + ', index: ' + index);
 console.log(JSON.stringify(registeredMiners));
 if (registeredMiners[index] === myPeerId.toString('hex')) {
 console.log('-----------create next block -------------
----');
 let newBlock = chain.generateNextBlock(null);
 chain.addBlock(newBlock);
 console.log(JSON.stringify(newBlock));
 writeMessageToPeers(MessageType.RECEIVE_NEW_BLOCK,
newBlock);
 console.log(JSON.stringify(chain.blockchain));
 console.log('-----------create next block -------------
----');
 }
});
job.start();

Al revisar el código, observe que el índice del primer bloque es 0, por lo que después de que el primer bloque está minado, lastBlockMinedBy se establecerá y solicitará
el siguiente bloque de su próximo minero.

let newIndex = registeredMiners.indexOf(lastBlockMinedBy);
index = ( newIndex+1 > registeredMiners.length-1) ? 0 : newIndex
+ 1;

Para generar y agregar un nuevo bloque, estaremos llamando a la cadena generateNextBlock y addBlock. Por último, transmitiremos el nuevo
bloque a todos los peers conectados.

let newBlock = chain.generateNextBlock(null);
chain.addBlock(newBlock);
writeMessageToPeers(MessageType.RECEIVE_NEW_BLOCK, newBlock);

En su código, switch manejará los nuevos bloques entrantes.

case MessageType.RECEIVE_NEW_BLOCK:
 if ( message.to === myPeerId.toString('hex') && message.from
!== myPeerId.toString('hex')) {
 console.log('-----------RECEIVE_NEW_BLOCK------------- '
+ message.to);
 chain.addBlock(JSON.parse(JSON.stringify(message.data)));
 console.log(JSON.stringify(chain.blockchain));
 console.log('-----------RECEIVE_NEW_BLOCK------------- '
+ message.to);
 }
 break;

Para ver este código en acción, ejecute tres instancias de su código:

> node p2p.js

Puede ver los mensajes de registroa cada peer como minero, así como su código comenzando a extraer bloques cada 30 segundos en orden, como se muestra abajo:

En este post, pudo registrar a sus peers como mineros, generar nuevos bloques y compartir bloques con otros peers; usaste un PoS simple para el mecanismo de consenso y pudimos probar la funcionalidad creando tres peers. El mecanismo de consenso es simple y no tiene en cuenta cada caso de uso que pueda suceder. En el siguiente post, guardaremos los bloques en una base de datos LevelDB

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s