Creando una Blockchain con menos de 100 líneas de código


Crear una cadena de bloques con menos de 100 líneas de código

.

Foto de Thought Catalog en Unsplash

El concepto básico de blockchain es muy sencillo: una base de datos distribuida que mantiene una lista de registros ordenados en continuo crecimiento.

El blockchain es un término que normalmente se asocia a Bitcoin y/o Ethereum, pero blockchain es más que eso, blockchain es la tecnología que hay detrás de estos, y detrás de cualquier otra criptodivisa.

Hay muchos otros usos para blockchain, por ejemplo, juegos (CryptoKitties) o también blockchain+IOT (Internet de las cosas), y esto es sólo el comienzo para la tecnología.


Una simple imagen sobre el concepto de blockchainLa blockchain es, como su nombre indica, una cadena de bloques, por lo que, tenemos la primera clase, el Bloque.


En esta etapa mi bloque tiene los atributos:

    • index – el índice del bloque la posición en la cadena
    • timestamp – fecha y hora en que el bloque fue añadido en Blockchain
    • datos – el valor de los datos, es decir, lo que se quiere guardar
    • hash anterior – el hash del índice del bloque -1
    • hash – el hash del bloque

.

Si no sabes lo que es el hash, lo expliqué en mi último post aquí.

Verás algunas cosas interesantes en la imagen y aquí te explico un poco:

    • Deja más OOP la función isValid es para cada bloque responder si es válido
    • El constructor define todas las cosas del bloque
    • la función “update” es para actualizar el dict cuando se lee de un archivo, esto es para guardar los datos para el futuro
    • calcular el hash para archivos previamente guardados, para convertir siempre al mismo encode, ya que, diferentes encodes tienen diferentes caracteres y diferentes caracteres producen diferentes hashes.

.

Así que esta es una cadena válida, si el bloque fue cambiado, el bloque actual lo sabrá, y se hará inválido, y si algún bloque anterior fue cambiado, la cadena lo sabrá, y toda la cadena será inválida. Ese es el concepto que hace que los datos guardados en Blockchain sean inmutables.

Así que mirando en nuestra segunda clase, Blockchain, parece:

Así, la clase blockchain crea los bloques y busca cualquier problema en la cadena, y esta clase se encarga de guardar en un simple archivo JSON y leer de él. Nuestra primera versión blockchain está lista!!! o/

Todo el código está abajo, podéis ejecutarlo y ver la salida

#!/usr/bin/python3
# coding=UTF-8
# encoding=UTF-8
import json
import os
import hashlib
import datetime
class Block:
def __init__(self, index, data, previousHash=‘00000’):
self.index = index
self.timestamp = str(datetime.datetime.now())
self.data = data
self.previousHash = previousHash
self.hash = self.calculateHash()
def update(self, dic):
self.__dict__=dic
return self
def calculateHash(self):
return hashlib.sha256(str(self.index).encode(‘utf-8’)
+ self.previousHash.encode(‘utf-8’)
+ str(self.data).encode(‘utf-8’)
+ self.timestamp.encode(‘utf-8’)).hexdigest()
def isValid(self):
return self.hash == self.calculateHash()
def printBlock(self):
return (\nBlock #” + str(self.index)
+ \nData: “ + str(self.data)
+ \nTimeStamp: “ + str(self.timestamp)
+ \nBlock Hash: “ + str(self.hash)
+ \nBlock Previous Hash: “ + str(self.previousHash)
+\n—————“)
class BlockChain:
def __init__(self, file=“block.chain”):
self.chain = [Block(0, “Genesis”)]
self.file=file
def getLatestBlock(self):
return self.chain[len(self.chain)1]
def getNextIndex(self):
return self.getLatestBlock().index + 1
def generateBlock(self, data):
self.chain.append(Block(self.getNextIndex(), data, self.getLatestBlock().hash))
def isChainValid(self):
for i in range (1, len(self.chain)):
if not self.chain[i].isValid():
return False
if self.chain[i].previousHash != self.chain[i1].hash:
return False
return True
def printBlockChain(self):
return .join([self.chain[i].printBlock() for i in range(1, len(self.chain))])
def save(self):
if(self.isChainValid()):
with open(self.file, ‘w’) as f:
f.write(json.dumps(self, default=lambda obj: obj.__dict__))
else:
print(“Not saved the chain!”)
def open(self):
if(os.path.exists(self.file)):
with open(self.file) as f:
data = json.load(f)
self.__dict__ = data
self.chain = [Block(“”,“”).update(dic) for dic in data[“chain”]]
def main():
blockchain = BlockChain()
blockchain.generateBlock(“Hello World!”)
blockchain.generateBlock(3)
blockchain.generateBlock({“account”: 123123, “mount”: 100})
print(blockchain.printBlockChain())
print (“Chain valid? “ + str(blockchain.isChainValid()))
blockchain.save()
blockchain.chain[1].data = “Hello Darkness my old friend!”
print(blockchain.printBlockChain())
print (“Chain valid? “ + str(blockchain.isChainValid()))
blockchain.save()
test = BlockChain()
test.open()
print(test.printBlockChain())
print (“Chain valid? “ + str(test.isChainValid()))
test.save()
if __name__ == ‘__main__’:

main()

Este archivo contiene texto Unicode bidireccional que puede ser interpretado o compilado de forma diferente a lo que aparece a continuación. Para revisarlo, abra el archivo en un editor que revele los caracteres Unicode ocultos.

En esta versión de nuestra blockchain, no hemos implementado la Prueba de Trabajo, la idea primero es crear la blockchain y garantizar la integración de la cadena. Ese será mi siguiente paso.

He creado un proyecto que podéis seguir en GitHub, iré incrementando más y más mi blockchain, si tenéis interés sólo tenéis que seguirme, escribiré algunos posts sobre todo el proceso.

P.S: No soy un experto en el blockchain, así que cualquier problema, arreglo de código, o consejos, esto es será muy bienvenido para comentar abajo y ayudará a algunas personas también. O puedes hablar conmigo en privado en el LinkedIn.

¡Nos vemos pronto!

Categorías : # Blockchain

Deja una respuesta

Tu dirección de correo electrónico no será publicada.