Blog
Nuestro Blockchain como API
- Publicado por: Rafael Fernandez
- Categoría: Blockchain
Bienvenido a esta segunda sección del curso de Blockchain en Python. Continúa leyendo para averiguar cómo convertiremos nuestra Blockchain en una API.
Como vimos en la sección anterior de este curso, las transacciones se agrupan en bloques y se van añadiendo a la Blockchain. Para crear una Blockchain, cada uno de los bloque nuevos usa el hash del bloque anterior como parte de sus datos. Para que se cree un nuevo bloque, un minero selecciona un conjunto de transacciones, agrega el hash del bloque anterior y extrae el bloque.
Si ocurre algún cambio en los datos de cualquier bloque, afectará a todos y cada uno de los valores del hash que contenga cualquiera de los bloques que vengan tras él, y por lo tanto, se volverán inválidos. Gracias a eso, la Blockchain es inmutable.
Por ejemplo: todos los mineros en la red de Bitcoin compiten entre sí para encontrar un bloque válido, el cual se agrega a la cadena de bloques y obtendrán una recompensa de la red. No es frecuente encontrar un nonce que valide un bloque, pero debido al número de mineros, la probabilidad de que un minero en la red valide un bloque es extremadamente alta. El primer minero que envía un bloque válido obtiene su bloque agregado a la cadena de bloques y recibe la recompensa en bitcoins. Pero, ¿qué sucede si dos mineros o más presentan sus bloques al mismo tiempo?
Resolviendo conflictos
Si dos mineros resuelven un bloque casi al mismo tiempo, tendremos 2 blockchains diferentes en la red, y tenemos que esperar al siguiente bloque para resolver el conflicto. Algunos mineros decidirán explotar sobre blockchain 1 y otros sobre blockchain 2. El primer minero que encuentre un nuevo bloque resolverá el conflicto. Si el nuevo bloque se extrajo encima de blockchain 1, entonces blockchain 2 deja de ser válido, la recompensa del bloque anterior va al minero de blockchain 1 y las transacciones que formaban parte de blockchain 2 y no se agregaron a blockchain regresan al grupo de transacciones y se agrega a los siguientes bloques. En resumen, si hay un conflicto en la cadena de bloques, gana la cadena más larga.
En esta oportunidad, vamos a utilizar Python Flask Framework. Es un micro-framework, que facilita el mapeo de los puntos finales a las funciones de Python. Esto nos permite interactuar con nuestro blockchain a través de la web usando solicitudes HTTP.
Crearemos tres métodos:
- El método /transactions/new para crear una nueva transacción en un bloque.
- Igualmente el método /mine para decirle a nuestro servidor que explote un nuevo bloque.
- Y el método /chain para devolver el Blockchain completo.
Configuración de Frasco
Nuestro “servidor” formará un solo nodo en nuestra red de blockchain. Vamos a crear un código repetitivo:
import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask class Blockchain(object): ... # Instancia nuestro Nodo app = Flask(__name__) # Generar una dirección única a nivel global para este nodo node_identifier = str(uuid4()).replace('-', '') #Instancia de la Blockchain blockchain = Blockchain() @app.route('/mine', methods=['GET']) def mine(): return "Vamos a minar un nuevo bloque" @app.route('/transactions/new', methods=['POST']) def new_transaction(): return "Añadiremos una nueva transacción" @app.route('/chain', methods=['GET']) def full_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain), } return jsonify(response), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
Una breve explicación de lo que hemos agregado arriba:
- La línea 15: Crea una instancia de nuestro nodo. Lea más sobre Flask aquí .
- En la línea 18: crea un nombre aleatorio para nuestro nodo.
- Tenemos que en la línea 21: Crea una instancia de nuestra clase Blockchain.
- La línea 24-26 se encarga de crear el /mine punto final, que es una GETsolicitud.
- Si ves las líneas 28-30: Cree el /transactions/new punto final, que es una POSTsolicitud, ya que le enviaremos datos.
- En cambio, si observas la línea 32-38: crea el /chain punto final, que devuelve la cadena de bloques completa.
- Y finalmente, en la línea 40-41: Ejecuta el servidor en el puerto 5000.
El punto final de Transacciones
Así es como se verá la solicitud de una transacción. Es lo que el usuario envía al servidor:
{ "remitente": "mi dirección", "destinatario": "dirección de otra persona", "cantidad": 5 }
Como ya tenemos nuestro método de clase para agregar transacciones a un bloque, el resto es fácil. Escribamos la función para agregar transacciones:
import hashlib import json from textwrap import dedent from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/transactions/new', methods=['POST']) def new_transaction(): values = request.get_json() #Compruebe que los campos obligatorios están en los datos POST. required = ['sender', 'recipient', 'amount'] if not all(k in valores for k in requerido): return 'Valores faltantes', 400 # Crear una nueva transacción index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) response = {'message': f'Transaction will be added to Block {index}'} return jsonify(response), 201
Este es un método para crear Transacciones
El punto final de minería
Nuestro punto final de minería es donde ocurre la magia, y es fácil. Tiene que hacer tres cosas:
- Calcular la prueba de trabajo.
- Recompensar al minero (nosotros) agregando una transacción que nos otorga una moneda.
- Forjar el nuevo bloque agregándole a la cadena.
import hashlib import json from time import time from uuid import uuid4 from flask import Flask, jsonify, request ... @app.route('/mine', methods=['GET']) def mine(): #Ejecutamos el algoritmo de prueba de trabajo para obtener la siguiente prueba… last_block = blockchain.last_block last_proof = last_block['proof'] proof = blockchain.proof_of_work(last_proof) # Debemos recibir una recompensa por encontrar la prueba. # El remitente es "0" para indicar que este nodo ha extraído una nueva moneda. blockchain.new_transaction( sender="0", recipient=node_identifier, amount=1, ) #Forjar el nuevo bloque añadiéndolo a la cadena previous_hash = blockchain.hash(last_block) block = blockchain.new_block(proof, previous_hash) response = { 'message': "Nuevo bloque forjado", 'index': block['index'], 'transactions': block['transactions'], 'proof': block['proof'], 'previous_hash': block['previous_hash'], } return jsonify(response), 200
Ten en cuenta que el destinatario del bloque minado es la dirección de nuestro nodo. Y la mayor parte de lo que hemos hecho aquí es simplemente interactuar con los métodos en nuestra clase Blockchain. En este punto, hemos terminado, y podemos comenzar a interactuar con nuestra cadena de bloques.
Comprobación de la validez de la cadena
Ahora que sabemos cómo crear nuevos bloques y unirlos en una cadena, definamos funciones para verificar que los nuevos bloques sean válidos y que toda la cadena sea válida.
En una red Blockchain, esto se vuelve importante de dos maneras:
- Cuando inicialmente configuramos nuestro nodo, descargaremos el historial completo de la cadena de bloques. Después de descargar la cadena, necesitaríamos ejecutar a través de Blockchain para calcular el estado del sistema. Para protegerse contra alguien que inserta transacciones no válidas en la cadena inicial, debemos verificar la validez de toda la cadena en esta descarga inicial.
- Una vez que nuestro nodo esté sincronizado con la red (tiene una copia actualizada de la Blockchain y una representación del estado del sistema) necesitará verificar la validez de los nuevos bloques que se transmiten a la red.
Necesitaremos tres funciones para facilitar en esto:
checkBlockHash: una función de ayuda simple que asegura que el contenido del bloque coincida con el hash
checkBlockValidity: verifica la validez de un bloque, dado su padre y el estado actual del sistema. Queremos que esto nos devuelva el estado actualizado si el bloque es válido, y generar un error de lo contrario.
checkChain: compruebe la validez de toda la cadena y calcule el estado del sistema a partir del bloque de genesis. Esto devolverá el estado del sistema si la cadena es válida, y generará un error de lo contrario.
➡ ¡Enhorabuena! Continúa aprendiendo con nuestro Curso de Blockchain:
[…] ➡ Ir a la siguiente lección Nuestro Blockchain como API – aprenderPython.net […]
me gusta, se ve interesante