Blog
La interacción con nuestro Blockchain
- Publicado por: Rafael Fernandez
- Categoría: Blockchain
Bienvenido a este tercer modulo del curso de Blockchain en Python, de AprenderPython.com. Ya en esta sección tenemos algo hecho sobre nuestros bloques de cadena, o Blockchain, ahora vamos a interactuar con esta estructura, para así percatarnos de su buen o mal funcionamiento. De esta manera podemos verificar el camino que lleva nuestro proyecto.
En una red real de blockchain, los nuevos nodos descargan una copia de la cadena de bloques y la verifican, luego anuncian su presencia en la red punto a punto y comienzan a recibir las transacciones. Luego de agrupar las transacciones en un bloque, luego pasan su bloque propuesto a otros nodos.
Hemos visto cómo verificar una copia de la cadena de bloques y cómo agrupar las transacciones en un bloque. Si recibimos un bloque de otro lado, es fácil verificarlo y agregarlo a nuestra cadena de bloques.
Implementación de la Blockchain
Puede iniciar un nodo de cadena de bloques desde el terminal yendo a la carpeta blockchain, y escribir python blockchain_client.py o python blockchain_client.py -p <NÚMERO DEL PUERTO>. Si no especifica un número de puerto, se establecerá de manera predeterminada en el puerto 5000.
En su navegador, vaya a ver el tablero de la interfaz de la cadena de bloques.http://localhost:<PORT NUMBER>
El tablero tiene dos pestañas en la barra de navegación:
- Mine: para visualizar transacciones y datos de blockchain, y para extraer nuevos bloques de transacciones.
- Configurar: para configurar las conexiones entre los diferentes nodos de la cadena de bloques.
A continuación hay una explicación de las partes más importantes en el código blockchain.py.
Comenzamos definiendo una clase Blockchain que tiene los siguientes atributos:
transactions: Lista de transacciones que se agregarán al siguiente bloque.
chain: El blockchain real que es una matriz de bloques.
nodes: Un conjunto que contiene las direcciones de nodo. El blockchain usa estos nodos para recuperar datos de blockchain de otros nodos y actualiza su blockchain si no están sincronizados.
node_id: Una cadena aleatoria para identificar el nodo blockchain.
La Blockchainclase también implementa los siguientes métodos:
register_node(node_url): Agrega un nuevo nodo de cadena de bloques a la lista de nodos.
verify_transaction_signature(sender_address, signature, transaction): Comprueba que la firma proporcionada corresponde a la transacción firmada por la clave pública (sender_address).
submit_transaction(sender_address, recipient_address, value, signature): Agrega una transacción a la lista de transacciones si se verifica la firma.
create_block(nonce, previous_hash): Agrega un bloque de transacciones a la cadena de bloques.
hash(block): Crea un hash SHA-256 de un bloque.
proof_of_work(): Algoritmo de prueba de trabajo. Busca un nonce que satisfaga la condición de minería.
valid_proof(transactions, last_hash, nonce, difficulty=MINING_DIFFICULTY): Comprueba si un valor hash satisface las condiciones de minería. Esta función se usa dentro de la función proof_of_work.
valid_chain(chain): comprueba si una bockchain es válida.
resolve_conflicts(): Resuelve conflictos entre los nodos de blockchain reemplazando una cadena con la más larga en la red.
clase Blockchain :
import hashlib import json from time import time from urllib.parse import urlparse from uuid import uuid4 import requests from flask import Flask, jsonify, request class Blockchain: def __init__(self): self.current_transactions = [] self.chain = [] self.nodes = set() # Aquí se crea el bloque génesis self.new_block(previous_hash='1', proof=100) def register_node(self, address): """ Añadir un nuevo nodo a la lista de nodos :param address: Dirección del nodo. Eg. 'http://192.168.0.5:5000' """ parsed_url = urlparse(address) if parsed_url.netloc: self.nodes.add(parsed_url.netloc) elif parsed_url.path: # Acepta una URL sin esquema como'192.168.0.5:5000'. self.nodes.add(parsed_url.path) else: raise ValueError('Invalid URL') def valid_chain(self, chain): """ Determinar si una cadena de bloqueo determinada es válida :param chain: Una cadena de bloqueo :return: Verdadero si es válido, falso si no lo es """ last_block = chain[0] current_index = 1 while current_index < len(chain): block = chain[current_index] print(f'{last_block}') print(f'{block}') print("\n-----------\n") # Comprobar que el hash del bloque es correcto last_block_hash = self.hash(last_block) if block['previous_hash'] != last_block_hash: return False # Verifique que la Prueba de Trabajo sea correcta if not self.valid_proof(last_block['proof'], block['proof'], last_block_hash): return False last_block = block current_index += 1 return True def resolve_conflicts(self): """ Este es nuestro algoritmo de consenso, resuelve conflictos. reemplazando nuestra cadena por la más larga de la red. :return: True si nuestra cadena fue reemplazada, Falss si no """ neighbours = self.nodes new_chain = None # Sólo buscamos cadenas más largas que las nuestras. max_length = len(self.chain) # Agarrar y verificar las cadenas de todos los nodos de nuestra red for node in neighbours: response = requests.get(f'http://{node}/chain') if response.status_code == 200: length = response.json()['length'] chain = response.json()['chain'] # Compruebe si la longitud es mayor y si la cadena es válida if length > max_length and self.valid_chain(chain): max_length = length new_chain = chain # Reemplazar nuestra cadena si descubrimos una cadena nueva y válida más larga que la nuestra if new_chain: self.chain = new_chain return True return False def new_block(self, proof, previous_hash): """ Crear un nuevo Bloque en el Cadena de Bloques :param proof: La prueba dada por el algoritmo de Prueba de Trabajo :param previous_hash: Hash del Bloque anterior :return: Nuevo Bloque """ block= { 'index': len(self.chain) + 1, 'timestamp': time(), 'transactions': self.current_transactions, 'proof': proof, 'previous_hash': previous_hash or self.hash(self.chain[-1]), }
La siguiente línea inicia una aplicación Python Flask que utilizaremos para crear diferentes API para interactuar con la cadena de bloques.
app = Flask ( __name__ ) CORS ( app )
A continuación, iniciamos una instancia de Blockchain.
blockchain = Blockchain ()
A continuación definimos las 2 rutas Flask que devuelven las páginas html para nuestro tablero de mandos frontales blockchain.
@ app.route ( '/' ) def index (): return render_template ( './index.html' ) @ app.route ( '/ configure' ) def configure (): return render_template ( './configure.html' )
➡ ¡Enhorabuena! Continúa aprendiendo con nuestro Curso de Blockchain:
[…] ➡ Ir a la siguiente lección La interacción con nuestra Blockchain – AprenderPython.net […]