Una cadena de bloques o también conocida como blockchain es una estructura de datos en la que la información se guarda en conjuntos (bloques), a los que se ánade meta informaciones relativas a otro bloque de la cadena anterior en una linea temporal, lo que significa que su contenido solo puede ser editado modificando todos los bloques anteriores.
En este post aprenderemos como crear un blockchain con javascript y nodejs.
Crearemos una carpeta con el nombre de nuestra elección en este caso la llamaremos “blockchain” , dentro de ella crearemos un archivo que se llamara main.js.
Ahora abriremos esta carpeta con el editor de código de nuestra preferencia.
1.- Primero crearemos una clase llamada Block el cual contendrá una función constructor, también crearemos las funciones calculateHash, mineBlock, la función constructor creara las instancias de los objetos del bloque y les proporcionara sus propiedades.
class Block {
constructor(data) {
this.index = 0;
this.date = new Date();
this.data = data;
this.previousHash = "0";
this.hash = this.calculateHash();
this.nonce = 0;
}
calculateHash() {
}
mineBlock(difficulty) {
}
2.- Iniciaremos npm, abriremos el terminal y nos ubicamos en nuestro proyecto ahora solo ejecutaremos en siguiente comando y solo resta configurar el proyecto a nuestro gusto.
npm init
3.- Ahora aremos uso de un modulo de npm llamado crypto-js, este puede ser instalado con el siguiente comando.
npm install –save crypto-js
4.- Ahora que la biblioteca esta instalada crearemos una constante llamada SHA265 que requiere de crypto-js/sha265, esto lo usaremos para crear la función de calculo.
const SHA256 = require('crypto-js/sha256');
class Block {
constructor(data) {
this.index = 0;
this.date = new Date();
this.data = data;
this.previousHash = "0";
this.hash = this.calculateHash();
this.nonce = 0;
}
calculateHash() {
return SHA256(this.index + this.previousHash + this.date + this.data + this.nonce).toString();
}
mineBlock(difficulty) {
while(!this.hash.startsWith(difficulty)) {
this.nonce++;
this.hash = this.calculateHash();
}
}
}
La función calculateHash la usaremos para dar a cada bloque su propio hash, este toma cada pieza del objeto Block, lo lanza en una función SHA256 y lo convierte a una cadena.
La segunda función mineBlock sera usada para procesar con seguridad las transacciones en redes blockchain agregando dificultad al proceso de generado del hash, en este caso la dificulta sera el numero de ceros con el cual comenzara el hash.
5.- Ahora que creamos la estructura de nuestro bloque individual, necesitamos crear una estructura un objeto de clase Blockchain esta tendrá las siguientes funciones, constructor, createGenesis, latestBlock, addBlock, checkValid.
class Blockchain {
constructor(difficulty = '00') {
this.chain = [this.createGenesis()];
this.difficulty = difficulty;
}
createGenesis() {
return new Block(0, {amount: 100});
}
latestBlock() {
return this.chain[this.chain.length - 1];
}
addBlock(newBlock) {
newBlock.index = this.latestBlock().index + 1;
newBlock.previousHash = this.latestBlock().hash;
newBlock.hash = newBlock.calculateHash();
newBlock.mineBlock(this.difficulty);
console.log('Minado!! '+ newBlock.hash+' con nonce '+ newBlock.nonce);
this.chain.push(newBlock);
}
checkValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
}
Bien expliquemos que hicimos en este código.
Función Constructor.
Función createGenesis.
Función latestBlock.
Función addBlock.
Función checkValid.
6.- Finalmente agregaremos esta lineas al final de nuestro código que añaden dos bloques con datos, los validara y mostraran en consola.
let myCoin = new Blockchain('000');
myCoin.addBlock(new Block({amount: 50}));
myCoin.addBlock(new Block({amount: 25}));
console.log("La cadena de bloques es valida?", myCoin.checkValid());
Nota: La clase Blockchain recibe la dificulta de minado en este caso la dificulta son 3 ceros, entre mas ceros mas difícil sera el minado de los bloques.
7.- Ahora nuestro código final se vera así.
const SHA256 = require('crypto-js/sha256');
class Block {
constructor(data) {
this.index = 0;
this.date = new Date();
this.data = data;
this.previousHash = "0";
this.hash = this.calculateHash();
this.nonce = 0;
}
calculateHash() {
return SHA256(this.index + this.previousHash + this.date + this.data + this.nonce).toString();
}
mineBlock(difficulty) {
while(!this.hash.startsWith(difficulty)) {
this.nonce++;
this.hash = this.calculateHash();
}
}
}
class Blockchain {
constructor(difficulty = '00') {
this.chain = [this.createGenesis()];
this.difficulty = difficulty;
}
createGenesis() {
return new Block(0, {amount: 100});
}
latestBlock() {
return this.chain[this.chain.length - 1];
}
addBlock(newBlock) {
newBlock.index = this.latestBlock().index + 1;
newBlock.previousHash = this.latestBlock().hash;
newBlock.hash = newBlock.calculateHash();
newBlock.mineBlock(this.difficulty);
console.log('Minado!! '+ newBlock.hash+' con nonce '+ newBlock.nonce);
this.chain.push(newBlock);
}
checkValid() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
}
let myCoin = new Blockchain('0000');
myCoin.addBlock(new Block({amount: 50}));
myCoin.addBlock(new Block({amount: 25}));
console.log("La cadena de bloques es valida?", myCoin.checkValid());
8.- Ahora solo queda probar nuestro blockchain abre el terminal, ubícate en la raíz de tu proyecto y ejecuta el siguiente comando.
node main.js
9.- Veras algo como esto.
Minado!! 000020f23e31c8f28fb54adb6754edd4319cb74065663acce78981630077028e con nonce 130611
Minado!! 000052c92a3c0533f6379bbca7f3096a4aa5cba6b7280761f983284a5680ca8f con nonce 23024
La cadena de bloques es valida? true
10.- Para ver la informacion que contiene cada bloque agrega al final la siguiente linea de código.
console.log(JSON.stringify(myCoin, null, 4));
Minado!! 000004d09ad97f858e05c4b101fce77ae3670f908f820dca5fa5d882f3e284d7 con nonce 63331
Minado!! 0000b78e1ea385c3d39f83b4d4bf22f53fd675e8b21a4a33afb4ba0d799d34af con nonce 9669
La cadena de bloques es valida? true
{
"chain": [
{
"index": 0,
"date": "2018-10-16T23:41:01.033Z",
"data": 0,
"previousHash": "0",
"hash": "3b2403dfac8d26ae556adb59f97b6f925d41687e3c436b0d70e09d99d31bf733",
"nonce": 0
},
{
"index": 1,
"date": "2018-10-16T23:41:01.038Z",
"data": {
"amount": 50
},
"previousHash": "3b2403dfac8d26ae556adb59f97b6f925d41687e3c436b0d70e09d99d31bf733",
"hash": "000004d09ad97f858e05c4b101fce77ae3670f908f820dca5fa5d882f3e284d7",
"nonce": 63331
},
{
"index": 2,
"date": "2018-10-16T23:41:07.385Z",
"data": {
"amount": 25
},
"previousHash": "000004d09ad97f858e05c4b101fce77ae3670f908f820dca5fa5d882f3e284d7",
"hash": "0000b78e1ea385c3d39f83b4d4bf22f53fd675e8b21a4a33afb4ba0d799d34af",
"nonce": 9669
}
],
"difficulty": "0000"
}
Listo ahora ya has creado una cadena de bloques (Blockchain) en javascript y nodejs, en futuros post aprenderemos mas sobre blockchain y javascript.
El repositorio de todo el código: GitHub