El concepto básico de blockchain es bastante simple: una base de datos distribuida que mantiene una lista en continuo crecimiento de registros ordenados.Sin embargo, es fácil confundirse, ya que normalmente cuando hablamos de blockchains también hablamos de los problemas que estamos tratando de resolver con ellos. Este es el caso de los proyectos populares basados en blockchain como Bitcoin y Ethereum . El término “blockchain” suele estar fuertemente ligado a conceptos como transacciones , contratos inteligentes o criptomonedas .
Esto hace que la comprensión de las blockchains sea una tarea necesariamente más difícil de lo que debe ser. Especialmente código fuente sabiamente. Aquí pasaré por una cadena de bloques súper simple que se implementó en 200 líneas de Javascript llamada NaiveChain.
Estructura de bloque
El primer paso lógico es decidir la estructura del bloque. Para mantener las cosas lo más simples posible, incluimos solo lo más necesario: índice, marca de tiempo, datos, hash y hash anterior.
class Block {
constructor(index, previousHash, timestamp, data, hash) {
this.index = index;
this.previousHash = previousHash.toString();
this.timestamp = timestamp;
this.data = data;
this.hash = hash.toString();
}
}
Bloque de hash
El bloque debe tener un hash para mantener la integridad de los datos. Se toma un SHA-256 sobre el contenido del bloque. Cabe señalar que este hash no tiene nada que ver con la “minería”, ya que no hay ningún problema de Prueba de Trabajo que resolver.
var calculateHash = (index, previousHash, timestamp, data) => {
return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
Generando un bloque
Para generar un bloque debemos conocer el hash del bloque anterior y crear el resto del contenido requerido (índice, hash, datos y marca de tiempo). Los datos de bloque son algo que proporciona el usuario final.
var generateNextBlock = (blockData) => {
var previousBlock = getLatestBlock();
var nextIndex = previousBlock.index + 1;
var nextTimestamp = new Date().getTime() / 1000;
var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);
return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
};
Almacenar los bloques
Se utiliza una matriz de JavaScript en memoria para almacenar la cadena de bloques. El primer bloque de la cadena de bloques es siempre un denominado “bloque de génesis”, que está codificado de forma rígida.
var getGenesisBlock = () => {
return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
var blockchain = [getGenesisBlock()];
Validando la integridad de los bloques
En un momento dado debemos poder validar si un bloque o una cadena de bloques son válidos en términos de integridad. Esto es cierto especialmente cuando recibimos nuevos bloques de otros nodos y debemos decidir si los aceptamos o no.
var isValidNewBlock = (newBlock, previousBlock) => {
if (previousBlock.index + 1 !== newBlock.index) {
console.log('invalid index');
return false;
} else if (previousBlock.hash !== newBlock.previousHash) {
console.log('invalid previoushash');
return false;
} else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
return false;
}
return true;
};
Elegir la cadena más larga
Siempre debe haber un solo conjunto explícito de bloques en la cadena en un momento dado. En caso de conflictos (por ejemplo, dos nodos generan el bloque número 72) elegimos la cadena que tiene el mayor número de bloques.
var replaceChain = (newBlocks) => {
if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {
console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');
blockchain = newBlocks;
broadcast(responseLatestMsg());
} else {
console.log('Received blockchain invalid');
}
};
Comunicarse con otros nodos
Una parte esencial de un nodo es compartir y sincronizar la cadena de bloques con otros nodos. Las siguientes reglas se utilizan para mantener la red sincronizada.
- Cuando un nodo genera un nuevo bloque, lo transmite a la red
- Cuando un nodo se conecta a un nuevo par, busca el último bloque
- Cuando un nodo encuentra un bloque que tiene un índice más grande que el bloque conocido actual, agrega el bloque a su cadena actual o consulta para la cadena de bloques completa.
0 comentarios