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 […]