Construye con Javascript una blockchain basica. Parte 2

creando el bloque genesis y compartiendo bloques

En el siguiente post, crearemos bloques que podremos compartir entre los demas nodos. Pero antes de hacer eso, echemos un vistazo más de cerca al objeto Bloque. El objeto Block no es el mismo para todas las blockchains. Diferentes blockchains utilizan diferentes tipos de objetos Block; Usaremos un objeto Block similar a bitcoin; Para comprender mejor la arquitectura, echemos un vistazo al UML del bloque y el blockHeader que utilizaremos , como se muestra en la imagen:

Diagrama UML del bloque y del header

La estructura de nuestro bloque se rige por los siguientes campos:

  • index: El bloque genesis es el bloque inicial de nuestra blockchain. Le asignamos el indice 0
  • txns: Esta es la transaccion en nuestro bloque. No solo se puede enfocar en criptomonedas sino que podemos usar otro tipo de datos si se requiere.

En el blockheader, que es un subojeto de Block contiene las siguientes propiedades:

  • version: En el momento de escribir este post, en Bitcoin hay cuatro vesiones de bloque. La versión 1 es el bloque génesis (2009), y la versión 2 es un fork suave de bitcoin-core 0.7.0 (2012). la versión 3 es un fork suave de bitcoin-core 0.10.0 (2015). Los bloques de la versión 4 son BIP65 en bitcoin core 0.11.2 (2015).
  • Previous block header hash: Esto es una función SHA-256 del header del bloque anterior. Asegura que el bloque anterior no se puede cambiar ya que este bloque debe ser cambiado también.
  • merkle root hash: El arbol de Merkle de todas las transacciones del bloque
  • Time: Este es el tiempo epoch UNIX de cuando el minero ha creado el bloque
  • nounce: El nonce en un bloque de bitcoin es de 32 bits (4 bytes) cuyo valor es ajustado por los mineros para que el hash del bloque será menor o igual al objetivo de la red.
  • nbits: Esto se refiere al objetivo. El objetivo es un numero de 256 bits y es inversamente proporcional a la dificultad. Es recalculado cada 2.016 bloques.

En términos de comunicación P2P, el flujo de bloques entre cada nodo en la red P2P consiste en solicitar el último bloque a un peer en el red y luego recibir la solicitud de bloque. Abajo se muestra el proceso:

Diagrama de flujo de la comunicación p2p requiriendo el último bloque de la cadena y recibiendolo

Ahora que ya comprendes la arquitectura y el flujo de bloques en el Red P2P, ahora estaremos enviando y solicitando bloques.

Nuestra blockchain consta de dos archivos: block.js y chain.js. El archivo Block.js contendrá la clase bloque y chain.js será el pegamento con métodos para manejar el
interacciones con los bloques. En términos del objeto Block, crearemos propiedades similares a las propiedades que posee el núcleo de bitcoin. Vemos que el archivo block.js incluye los objetos Block y BlockHeader. Este es el código de block.js

exports.BlockHeader = class BlockHeader {
 constructor(version, previousBlockHeader, merkleRoot, time)
{
 this.version = version;
 this.previousBlockHeader = previousBlockHeader;
 this.merkleRoot = merkleRoot;
 this.time = time;
 }
};
exports.Block = class Block {
 constructor(blockHeader, index, txns) {
 this.blockHeader = blockHeader;
 this.index = index;
 this.txns = txns;
 }
}

Como puede verse abajo, chain.js contiene el primer bloque, que se llama genesis block, así como un método para recibir el objeto blockchain completo, agregar un bloque,
y recuperar un bloque. Tenga en cuenta que vamos a agregar una biblioteca llamada moment para guardar el tiempo en un formato de hora Unix en su biblioteca chain.js. Para hacerlo, instale

> npm install moment --save 

Y ahora el código de chain.js

let Block = require("./block.js").Block,
     BlockHeader = require("./block.js").BlockHeader,
     moment = require("moment");
let getGenesisBlock = () => {
   let blockHeader = new BlockHeader(1, null, "0x1bc33000000000
   00000000000000000000000000000000000", moment().unix());
   return new Block(blockHeader, 0, null);
};
let getLatestBlock = () => blockchain[blockchain.length-1];
let addBlock = (newBlock) => {
   let prevBlock = getLatestBlock();
   if (prevBlock.index < newBlock.index && newBlock.
blockHeader.previousBlockHeader === prevBlock.blockHeader.
merkleRoot) {
      blockchain.push(newBlock);
 }
}
let getBlock = (index) => {
 if (blockchain.length-1 >= index)
 return blockchain[index];
 else
 return null;
}
const blockchain = [getGenesisBlock()];
if (typeof exports != 'undefined' ) {
 exports.addBlock = addBlock;
 exports.getBlock = getBlock;
 exports.blockchain = blockchain;
 exports.getLatestBlock = getLatestBlock;
}

Ahora tienes un objeto Block que está incluido en chain.js. Tu libreria puede
crear un bloque génesis y agregue un bloque a un objeto blockchain. Tu también podrás enviar y solicitar bloques.
A continuación, en el archivo p2p.js, puedes usar el archivo chain.js que creaste. Primero necesitas importar la clase chain.js.

const chain = require("./chain");

Luego, puedes definir un tipo de mensaje para solicitar y recibir el último bloque. Cuando envía mensajes en tu red P2P, debe poder saber el propósito de los mensajes. Al utilizar una propiedad MessageType, puedes definir un mecanismo de conmutación para que se utilicen diferentes tipos de mensajes para diferentes funciones.

let MessageType = {
 REQUEST_LATEST_BLOCK: 'requestLatestBlock',
 LATEST_BLOCK: 'latestBlock'
};

Una vez que se recibe un mensaje de evento de datos de conexión, puede crear tu código para manejar los diferentes tipos de solicitudes, como se muestra abajo:

switch (message.type) {
 case MessageType.REQUEST_BLOCK:
 console.log('-----------REQUEST_BLOCK-------------');
 let requestedIndex = (JSON.parse(JSON.stringify(message.
data))).index;
 let requestedBlock = chain.getBlock(requestedIndex);
 if (requestedBlock)
 writeMessageToPeerToId(peerId.toString('hex'),
MessageType.RECEIVE_NEXT_BLOCK, requestedBlock);
 else
 console.log('No block found @ index: ' + requestedIndex);
 console.log('-----------REQUEST_BLOCK-------------');
 break;
 case MessageType.RECEIVE_NEXT_BLOCK:
 console.log('-----------RECEIVE_NEXT_BLOCK-------------');
 chain.addBlock(JSON.parse(JSON.stringify(message.data)));
 console.log(JSON.stringify(chain.blockchain));
 let nextBlockIndex = chain.getLatestBlock().index+1;
 console.log('-- request next block @ index: ' +
nextBlockIndex);
 writeMessageToPeers(MessageType.REQUEST_BLOCK, {index:
nextBlockIndex});
 console.log('-----------RECEIVE_NEXT_BLOCK-------------');
 break;
}

Por último, estableceremos una solicitud de tiempo de espera que enviará una solicitud para recuperar el último bloque cada 5.000 milisegundos (5 segundos).

setTimeout(function(){
writeMessageToPeers(MessageType.REQUEST_BLOCK, {index: chain.
getLatestBlock().index+1});
}, 5000);

Deja una respuesta

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 )

Foto de Facebook

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

Conectando a %s