English English French French Spanish Spanish German German
Geekflare cuenta con el apoyo de nuestra audiencia. Podemos ganar comisiones de afiliados comprando enlaces en este sitio.
Comparte en:

¿Cómo crear una cadena de bloques con Python?

Escáner de seguridad de aplicaciones web Invicti – la única solución que ofrece verificación automática de vulnerabilidades con Proof-Based Scanning™.

¿Sabías que Bitcoin está construido sobre Blockchain? Hoy vamos a construir una Blockchain con Python desde cero.

What is Blockchain?

En el 2008 Papel Bitcoin fue publicado por un individuo o grupo desconocido llamado Satoshi Nakamoto. Bitcoin surgió como una versión peer-to-peer de efectivo electrónico que permitía transacciones sin pasar por instituciones centralizadas (bancos). La mayoría de la gente no sabe que en ese mismo artículo, Satoshi definió una forma distribuida de almacenar información, hoy en día conocida como Servicios.

La tecnología Blockchain
La tecnología Blockchain

En pocas palabras, Blockchain es un libro de contabilidad digital inmutable y compartido que almacena transacciones a través de una red descentralizada de computadoras.

Podemos dividir Blockchain en dos términos simples:

  • Bloque: un espacio donde almacenamos transacciones
  • Cadena: un conjunto de registros vinculados

Esto define Blockchain como una cadena de bloques enlazados, donde cada bloque almacena una transacción realizada con parámetros específicos.

Cada bloque se construye encima de otro bloque, creando una cadena de bloques irreversible. En otras palabras, cada bloque depende de otro. Esto resulta en un sistema robusto e inmutable en el que cualquier persona con los permisos correctos puede revisar la integridad.

Blockchain presenta un interesante conjunto de características:

  • Inmutabilidad de la historia
  • Persistencia de la información
  • Sin errores con los datos almacenados

Muchos sistemas actualmente se basan en Blockchain, como criptomonedas, transferencia de activos (NFTs), y posiblemente en un futuro próximo, la votación.

Vale la pena mencionar que un Python Blockchain no tiene por qué ser un programa complejo con miles de líneas de código. En esencia, sería una lista de transacciones vinculadas entre sí.

Por supuesto, esta fue una breve explicación, pero si desea una guía completa, hemos producido un tutorial completo sobre Blockchain para principiantes. Asegúrese de comprobarlo.

Sin más demora, construyamos un Blockchain simple con Python.

Building a Blockchain With Python

Antes de comenzar, definamos lo que vamos a hacer en este tutorial:

  • Cree un sistema Blockchain simple escrito en Python
  • Utilice nuestra Blockchain con transacciones preestablecidas representadas como cadenas
  • Prueba la inmutabilidad de nuestra Blockchain

No vamos a usar JSON pero listas de Python. Esto nos permitirá simplificar el proceso y enfocarnos en aplicar los conceptos clave de una Blockchain.

Qué necesitarás para seguir este tutorial:

Creando la clase Block

Abra su editor de código favorito y cree un main.py expediente. Este será el archivo con el que trabajaremos.

Ahora, importa hashlib, un módulo que nos permite crear mensajes cifrados unidireccionales. Las técnicas de criptografía como el hash hacen que Blockchain cree transacciones seguras.

Una función hash es un algoritmo que toma algunos datos (generalmente una cadena codificada) y devuelve un identificador único, a menudo llamado "resumen" o "firma". Esta última parte es vital; con una función hash, una ligera diferencia en la entrada produce un identificador radicalmente diferente como salida. Veremos esto en acción más adelante.

Por ahora, solo importe el módulo integrado hashlib:

# main.py file
"""
A simple Blockchain in Python
"""

import hashlib

Este módulo incluye la mayoría de los algoritmos hash que necesitará. Solo tenga en cuenta que usaremos el hashlib.sha256 () función.

Ahora, entremos en GeekCoinBlock, nuestro nombre de blockchain totalmente original.

class GeekCoinBlock:
    
    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()

Sé que esto puede resultar en un fragmento de código torpe. Analicemos cada parte en la siguiente sección.

Explicación de GeekCoinBlock

Primero, creamos una clase llamada GeekCoinBloque, un contenedor para objetos que tendrán ciertas características (atributos) y comportamientos (métodos).

Entonces definimos el __en eso__ (también llamado constructor), que se invoca cada vez que se crea un objeto GeekCoinBlock.

Este método tiene tres parámetros:

  • yo (la instancia de cada objeto)
  • anterior_bloque_hash (una referencia al bloque anterior)
  • lista_transacciones (una lista de transacciones realizadas en el bloque actual).

Almacenamos el hash anterior y la lista de transacciones y creamos una variable de instancia bloque_datos como una cuerda. Esto no sucede con las criptomonedas reales, en las que almacenamos ese tipo de datos como otro hash, pero para simplificar, almacenaremos cada bloque de datos como una cadena.

Finalmente, creamos el bloque_hash, que otros bloques usarán para continuar la cadena. Aquí es donde hashlib resulta útil; en lugar de crear una función hash personalizada, podemos usar la función predefinida sha256 para hacer bloques inmutables.

Esta función recibe cadenas codificadas (o bytes) como parámetros. Por eso estamos usando el block_data.encode () método. Después de eso, llamamos hexdigest () para devolver los datos codificados en formato hexadecimal.

Sé que todo esto puede ser abrumador, así que juguemos con hashlib en un shell de Python.

In [1]: import hashlib

In [2]: message = "Python is great"

In [3]: h1 = hashlib.sha256(message.encode())

In [4]: h1
Out[4]: <sha256 ... object @ 0x7efcd55bfbf0>

In [5]: h1.hexdigest()
Out[5]: 'a40cf9cca ... 42ab97'

In [6]: h2 = hashlib.sha256(b"Python is not great")

In [7]: h2
Out[7]: <sha256 ... object @ 0x7efcd55bfc90>

In [8]: h2.hexdigest()
Out[8]: 'fefe510a6a ... 97e010c0ea34'

Como puede ver, un ligero cambio en la entrada como "Python es genial" a "Python no es genial" puede producir un hash totalmente diferente. Todo esto tiene que ver con la integridad de Blockchain. Si introduce algún pequeño cambio en una cadena de bloques, su hash cambiará drásticamente. Esta es la razón por la que el dicho "No se puede corromper una Blockchain" es cierto.

Usando nuestra clase de bloque

Construiremos una clase Blockchain completa más tarde, pero por ahora, usemos nuestra clase Block para crear una cadena de bloques (Blockchain).

En el mismo archivo, cree un par de transacciones compuestas por cadenas simples almacenadas en variables, por ejemplo:

class GeekCoinBlock:
    ...

t1 = "Noah sends 5 GC to Mark"
t2 = "Mark sends 2.3 GC to James"
t3 = "James sends 4.2 GC to Alisson"
t4 = "Alisson sends 1.1 GC to Noah"

Por supuesto, GC se refiere a GeekCoin

Ahora, construya el primer bloque de nuestra Blockchain usando la clase GeekCoinBlock e imprima sus atributos. Tenga en cuenta que el anterior_hash El parámetro del bloque génesis (primer bloque que precede a otros bloques) siempre será una cadena arbitraria o hash, en este caso, "primer bloque".

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

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

Luego, hacemos lo mismo con el segundo bloque, pero pasando el hash del primer bloque como el anterior_hash argumento.

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

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

Ejecutemos y analicemos el resultado que obtenemos de este fragmento de código. Una vez más, escribe tu terminal:

❯ python main.py
Block 1 data: Noah sends 5 GC to Mark - Mark sends 2.3 GC to James - firstblock
Block 1 hash: 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 01e4e15242a9601725f4a86ca01fbddaaec7105b442955bb0efcadbfc759806d
Block 2 hash: 448c4306caf7f6937b0307f92f27fbea3bb73b3470363dee5026a1209dadcfa8

Por ahora, solo ve texto y algunos hashes de 64 caracteres, pero esto retoma prácticamente el mecanismo de Blockchain.

Empiezas con un bloque de génesis, la base de todos los demás bloques.

Cualquiera puede validar la integridad de la cadena, y es por eso que Blockchain es un sistema tan seguro. Por ejemplo, si modificamos ligeramente el contenido de una transacción, digamos:

t2 = "Mark sends 2.3 GC to James" -> t2 = "Mark sends 3.2 GC to James" 

Vemos un cambio dramático en el hash de los bloques.

Block 1 data: Noah sends 5 GC to Mark - Mark sends 3.2 GC to James - firstblock
Block 1 hash: 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 data: James sends 4.2 GC to Alisson - Alisson sends 1.1 GC to Noah - 7a990bf1d70230bf2dad6160496c0b3046da7a17b1281fd1d4c63d4eac58e78c
Block 2 hash: 569b977306ce88b53e001dca7ba00c03a51c60d6df4650e7657dcd136f2da0ac

Puedes ver el proyecto actual en este Repositorio GitHub.

Codificar una cadena de bloques

No es tan inteligente basar la integridad de nuestro sistema en variables codificadas a mano, por lo que necesitamos otro enfoque.

Tenemos los bloques. Es hora de crear una clase que los una en una Blockchain.

Comencemos por eliminar nuestras transacciones anteriores y bloquear objetos, luego usando el código a continuación.

# main.py

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

    def generate_genesis_block(self):
        self.chain.append(GeekCoinBlock("0", ['Genesis Block']))
    
    def create_block_from_transaction(self, transaction_list):
        previous_block_hash = self.last_block.block_hash
        self.chain.append(GeekCoinBlock(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]

Este es nuevamente un gran fragmento de código. Analicemos cada parte:

  • auto.cadena - La lista donde se registran todos los bloques. Podemos acceder a cada bloque a través de índices de lista.
  • generar_genesis_bloque - Anexar la génesis o primer bloque a la cadena. El hash anterior del bloque es "0" y la lista de transacciones es simplemente "Genesis Block".
  • create_block_from_transaction - Esto nos permite agregar bloques a la cadena con solo una lista de transacciones. Sería muy molesto crear un bloque manualmente cada vez que queremos registrar una transacción
  • mostrar_cadena - Imprime la cadena de bloques con un bucle for
  • último_bloque - Una propiedad que nos permite acceder al último elemento de la cadena. Lo usamos en el create_block_from_transaction método.

Probemos este Blockchain.

# main.py

import hashlib

class GeekCoinBlock:
    ...


class Blockchain:
    ...

t1 = "George sends 3.1 GC to Joe"
t2 = "Joe sends 2.5 GC to Adam"
t3 = "Adam sends 1.2 GC to Bob"
t4 = "Bob sends 0.5 GC to Charlie"
t5 = "Charlie sends 0.2 GC to David"
t6 = "David sends 0.1 GC to Eric"

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()

Ahora, ejecute el main.py archivo.

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

Data 2: George sends 3.1 GC to Joe - Joe sends 2.5 GC to Adam - 39331a6a2ea1cf31a5014b2a7c9e8dfad82df0b0666e81ce04cf8173cc5aed3e
Hash 2: 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5

Data 3: Adam sends 1.2 GC to Bob - Bob sends 0.5 GC to Charlie - 98cf363aecb33989aea0425a3c1287268bd86f63851bc08c0734a31db08506d5
Hash 3: 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589

Data 4: Charlie sends 0.2 GC to David - David sends 0.1 GC to Eric - 6f1cfcc3082488b97db8fdf8ed33f9ac7519be3e285a37a6fcc2f1904f373589
Hash 4: 869df2f03c9860767d35b30a46233fbeea89a3000ae5019d1491e3829d1ab929

¡Felicidades! 🙌 Acaba de crear una cadena de bloques Python simple desde cero.

Ahora puede fortalecer la inmutabilidad de Blockchain mediante el uso de getters y setters e implementar otras características como prueba de trabajo, minería, o cualquier otro concepto que explicamos en el Artículo de los fundamentos de la minería de Bitcoin.

Conclusión

Blockchain es la tecnología detrás Bitcoin, Etherium y todas las demás criptomonedas que existen. En este artículo, aprendió cómo crear una Blockchain con Python mediante el uso de algoritmos hash como sha256, clases y objetos.

Su desafío es crear un sistema de minería y, por qué no, implementarlo con una API REST utilizando marcos como Django or Frasco.

Mucha gente está haciendo fortunas con las criptomonedas. Imagínese lo que podría hacer si creara uno por sí mismo. 🤑

¡Sigue codificando! 👨‍💻

Gracias a nuestros patrocinadores
Más lecturas geniales sobre Blockchain
Impulse su negocio
Algunas de las herramientas y servicios para ayudar a que su negocio crezca.
  • Invicti utiliza Proof-Based Scanning™ para verificar automáticamente las vulnerabilidades identificadas y generar resultados procesables en cuestión de horas.
    Prueba Invicti
  • Web scraping, proxy residencial, administrador de proxy, desbloqueador web, rastreador de motores de búsqueda y todo lo que necesita para recopilar datos web.
    Prueba Brightdata
  • Semrush es una solución de marketing digital todo en uno con más de 50 herramientas en SEO, redes sociales y marketing de contenido.
    Prueba Semrush
  • Intruder es un escáner de vulnerabilidades en línea que encuentra debilidades de ciberseguridad en su infraestructura, para evitar costosas filtraciones de datos.
    Trata Intruder