¿Cómo crear blockchain con Python?

Construyamos nuestra Blockchain en Python

En los últimos meses, se ha hablado mucho acerca del blackchain y el bitcoin pero, ¿cómo funciona esta cadena de bloques? En esta nota aprenderemos las bases para construir una cadena de bloques propia y despertar nuestro pensamiento creativo.

¿Qué es blockchain?

Fue en 2008 cuando una entidad digital desconocida de nombre Satoshi Nakamoto, publicó lo que sería el articulo Bitcoin. Bitcoin nace como una versión de peer-to-peer de efectivo electrónico que permite hacer transacciones sin la intervención de instituciones centralizadas (bancos).

Lo que la gran mayoría de las personas desconocen hasta el día de hoy, es en el mismo documento del bitcoin, el autor o los autores también definieron una forma distribuida de almacenar información. Lo que hoy en día conocemos como blockchain.

En términos sencillos podemos definir al blockchain como un único libro digital de contabilidad que es compartido e inmutable que almacenas las transacciones por medio de una red descentralizada de ordenadores. Entonces, del blockchain derivan dos términos:

  • Bloque: Que es el espacio donde se almacenan las transacciones (el libro digital).
  • Cadena: Es el conjunto de registros vinculados (las transacciones).

De ahí viene el termino cadena de bloques. Donde cada uno de sus bloques almacena una transacción que se ha realizado con un conjunto de parámetros específicos. Cada bloque, es construido sobre otro. Por lo que, se crea una cadena de bloques irreversible.

Esto lo convierte en un sistema robusto e inmutable. Donde cualquier persona con los debidos permisos puede revisar su integridad. Además, el blockchain tiene algunas características más:

- Anuncio -
  • Tiene inmutabilidad en la historia.
  • Persistencia de la información.
  • No hay cabida para errores con los datos almacenados.

Aplicaciones del blockchain

El blockchain, cada vez toma más relevancia y se está presente en varias industrias. Especialmente en el sector tecnológico. Por ejemplo, en las criptomonedas, los NFTs, y puede que, en un futuro, sea implementado en las votaciones.

Ahora bien, una blockchain de Python no necesariamente tiene que ser un programa complejo con miles de líneas de código interminable y complejo de entender. Solo se trataría de una lista de transacciones vinculadas entre sí.

Construyendo blockchain con Python

En esta ocasión, no usaremos JSON. En su lugar utilizaremos listas de Python. Esto nos ayudará a simplificar el proceso y centrarnos únicamente en aplicar los conceptos clave de un Blockchain.

Para realizar la actividad, necesitamos comprender las clases y métodos de Python además del manejo básico de comandos.

Creando la clase Block

Abriremos nuestro editor de código preferido (en este caso Atom) y luego vamos a crear un archivo al que llamaremos main.py. Este será el archivo en el que vamos a trabajar.

Luego, importaremos hashlib, un módulo que nos permitirá crear mensajes cifrados unidireccionales. Las técnicas de criptografía como las que nos ofrece hashing, hacen que el Blockchain cree transacciones seguras.

Una función hash es un algoritmo que toma algunos datos (esencialmente una cadena codificada) y nos devuelve un ID único, que a menudo suele llamarse resumen o firma. Siendo esta última parte vital; como una función hash, una ligera diferencia en la entrada produce un ID radicalmente distinto como salida.

# archivo main.py
"""
Una cadena de bloques simple en Python
"""

import hashlib

Es en este módulo que incluiremos la mayoría de los algoritmos hash que necesitaremos. Solo debemos tener presente que usaremos la función hashlib.sha256().

Continuaremos el desarrollo del nuestro blockchain apoyados del siguiente código. A simple vista resulta algo difícil de entender, pero vamos entendiendo el código por partes.

class TalentDevelopers:
    
    def __init__(self, previous_block_hash, transaction_list):

        self.previous_block_hash = previous_block_hash
        self.transaction_list = transaction_list

        self.block_data = f"{' - '.join(transaction_list)} - {previous_block_hash}"
        self.block_hash = hashlib.sha256(self.block_data.encode()).hexdigest()

Explicación del código

Primero, creamos una clase de nombre TalentDevelopers, que servirá como un contenedor para objetos que tendrán un conjunto de características (atributos) como comportamientos (métodos).

Luego, definimos el método __init__ (también denominado constructor), al que invocaremos cada vez que creemos un objeto TalentDevelopers. Este método, tiene tres parámetros más:

  • self: que será la instancia de cada objeto
  • previous_block_hash: La referencia del bloque anterior.
  • transaction_list: la lista de transacciones realizadas en el bloque actual.

Almacenamos tanto el hah anterior como a lista de transacciones y crearemos una variable de instancia block_data en forma de cadena. Cabe mencionar que esto no es lo que sucede con las criptomonedas reales, en este ejercicio solo lo usaremos para fines demostrativos.

Por último, tenemos el block_hash, que será usado por otros bloques para continuar la cadena. Es aquí donde encontramos la utilidad de hashlib: en lugar de crear una función personalizada hash, podemos usar el sha256 pre-construido para la construcción de bloques inmutables.

Esta función recibirá cadenas codificadas, o bytes, como parámetros. Por ello es que usaremos el método block_data.encode(). Luego, llamaremos a hexdigigest() para retornar los datos codificados en formato hexadecimal.

Uso de la clase de bloques

Usaremos la clase Block para crear una cadena de bloques. Dentro del mismo archivo, vamos a crear una serie de transacciones hechas por cadenas simples almacenadas en variables. Por ejemplo:

class TalentDevelopers:
    ...

t1 = "Jose sends 5 GC to Maria"
t2 = "Maria sends 2.3 GC to Edgar"
t3 = "Edgar sends 4.2 GC to Faby"
t4 = "Faby sends 1.1 GC to Jose"

Ahora, vamos a construir el primer bloque de nuestra Blockchain usando la clase TalentDevelopers e imprimiremos sus atributos. Debemos tene presente que el parámetro previous_hash del bloque siempre será alguna cadena arbitraria o hash.

block1 = TalentDevelopers('firstblock', [t1, t2])

print(f"Block 1 data: {block1.block_data}")
print(f"Block 1 hash: {block1.block_hash}")

Liego, haremos lo mismo con el segundo bloque. Pero en esta ocasión usando el hash del primer bloque, como el previous_hash argumento.

block2 = TalentDevelopers(block1.block_hash, [t3, t4])

print(f"Block 2 data: {block2.block_data}")
print(f"Block 2 hash: {block2.block_hash}")

Después ejecutaremos y analizaremos la salida que se obtenga de esta pieza de código. Así que una vez más, escribiremos en la terminal lo siguiente:

❯ python main.py
Block 1 data: Jose sends 5 GC to Maria - Maria sends 2.3 GC to Edgar - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: Edgar sends 4.2 GC to Faby - Faby sends 1.1 GC to Jose - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Hasta aquí, solo podemos ver textos y algunos hashes de 64 caracteres. Esto es algo parecido a lo que reanuda el mecanismo de una blockchain. Iniciamos con un bloque génesis, que es la base de todos los demás. De esta forma, cualquiera puede validar la integridad de la cadena, y es justo por eso que el Blockchain es un sistema seguro.

Codificando la Blockchain

Sería poco inteligente de nuestra parte que basáramos la integridad de nuestro sistema basados únicamente en variables hechas a mano. Así que necesitemos emplear un enfoque distinto. Y este es por medio de bloques. Ha llegado el momento de construir una clase que pueda unirnos en una auténtica cadena de cloques.

Para ello, nos desharemos de las transacciones hechas anteriormente y usaremos en siguiente código:

# main.py

class Blockchain:
    def __init__(self):
        self.chain = []
        self.generate_genesis_block()

    def generate_genesis_block(self):
        self.chain.append(TalentDevelopers("0", ['Genesis Block']))
    
    def create_block_from_transaction(self, transaction_list):
        previous_block_hash = self.last_block.block_hash
        self.chain.append(TalentDevelopers(previous_block_hash, transaction_list))

    def display_chain(self):
        for i in range(len(self.chain)):
            print(f"Data {i + 1}: {self.chain[i].block_data}")
            print(f"Hash {i + 1}: {self.chain[i].block_hash}\n")

    @property
    def last_block(self):
        return self.chain[-1]

De nueva cuenta, tenemos una enrome pieza de código. Así que vamos a analizarla en detalle:

  • sel.chain: Es la lista donde se registrarán todos los bloques. Podremos acceder a cada uno de ellos mediante índices de listas.
  • generate_genesis_block: Se encarga de colocar el primer e importante bloque de nuestra Blockchain. El hash del bloque anterior es ‘0’ y la lista de transacciones será simplemente ‘Genesis Block’.
  • create_block_from_transaction: Esto nos va a permitir agregar bloques a la cadena con ta solo una lista de transacciones.
  • display_chain: Imprimirá la cadena de bloques con un bucle for.
  • last_block: Esta es la propiedad que nos va a permitir acceder al último elemento de la cadena. Lo usamos en l método create_block_from_transaction.

¡Probemos nuestra blockchain! Para ello usaremos el siguiente fragmento de código:

# main.py

import hashlib

class TalentDevelopers:
    ...


class Blockchain:
    ...

t1 = "Jose sends 3.1 GC to Maria"
t2 = "Maria sends 2.5 GC to Edgar"
t3 = "Edgar sends 1.2 GC to Faby"
t4 = "Faby sends 0.5 GC to Cristina"
t5 = "Cristina sends 0.2 GC to David"
t6 = "David sends 0.1 GC to Sofia"

myblockchain = Blockchain()

myblockchain.create_block_from_transaction([t1, t2])
myblockchain.create_block_from_transaction([t3, t4])
myblockchain.create_block_from_transaction([t5, t6])

myblockchain.display_chain()

Luego, ejecutaremos el archivo main.py. y tendremos un resultado parecido al siguiente.

Data 1: Genesis Block - 0
Hash 1: 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e

Data 2: Jose sends 3.1 GC to Maria - Maria sends 2.5 GC to Edgar - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Data 3: Edgar sends 1.2 GC to Faby - Faby sends 0.5 GC to Cristina - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Data 4: Cristina sends 0.2 GC to David - David sends 0.1 GC to Sofia - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

¡Perfecto! Ahora hemos creado nuestra propia Blockchain en Python desde cero. Ahora tenemos una idea más clara de cómo funciona la tecnología que está detrás de Bitcoin o Etherium. Estaos listos para ir un paso más e implementar incluso una API REST con frameworks como Django o Flask.

- Anuncio -
Artículo anteriorJungheinrich AG adquiere un desarrollador de robots móviles autónomos
Artículo siguienteProgramar descansos para incrementar el pensamiento creativo
Especialista en Marketing Digital con enfoque en resultados. Apasionado de los emprendimientos de alto impacto que involucran tecnología e innovación.