0% encontró este documento útil (0 votos)
362 vistas

Desarrollar Una Aplicación Blockchain Desde Cero en Python - Recursos Python

Este documento describe cómo desarrollar una aplicación blockchain desde cero en Python. Explica los conceptos básicos de blockchain y proporciona un tutorial paso a paso para crear una aplicación que almacene información de manera descentralizada usando blockchain.

Cargado por

edgarherreraphe
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
362 vistas

Desarrollar Una Aplicación Blockchain Desde Cero en Python - Recursos Python

Este documento describe cómo desarrollar una aplicación blockchain desde cero en Python. Explica los conceptos básicos de blockchain y proporciona un tutorial paso a paso para crear una aplicación que almacene información de manera descentralizada usando blockchain.

Cargado por

edgarherreraphe
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 25

(https://recursospython.

com/)
Inicio (https://recursospython.com/)

Códigos de fuente (https://recursospython.com/category/codigos-de-fuente/)

Guías y manuales (https://recursospython.com/category/guias-y-manuales/)

Foro (https://foro.recursospython.com/) Micro (https://micro.recursospython.com/)

Tutorial (https://tutorial.recursospython.com/) Newsletter (https://recursospython.com/newsletter/)

Contacto (https://recursospython.com/contacto/) Donar (https://recursospython.com/donar/)

Búsqueda … 
Desarrollar una aplicación
«blockchain» desde cero
en Python Últimas
julio 1, 2018
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-cero/)
by Recursos Python entradas
(https://recursospython.com/author/admin/)

(https://recursospython.com/guias-y-manuales/aplicacion- Introducción a Tcl/Tk
blockchain-desde-cero/#comments)34 comentarios
(https://recursospython.com/guias-y-manuales/aplicacion- (tkinter)
blockchain-desde-cero/#comments) (https://recursospython.com/gui
y-
manuales/introduccion-
a-tkinter/)

Traducido desde el inglés Develop a blockchain application from


Botón (Button) en Tcl/Tk
scratch in Python
(tkinter)
(https://www.ibm.com/developerworks/cloud/library/cl-develop-
(https://recursospython.com/gui
blockchain-app-in-python/index.html).
y-manuales/boton-
Este tutorial introduce a desarrolladores de Python, de cualquier button-en-tkinter/)
nivel de programación, al blockchain. Descubrirás exactamente qué
pyperclip – Copiar y
es un blockchain implementando un blockchain público desde cero
pegar en el portapapeles
y creando una simple aplicación para desplegarlo.
(https://recursospython.com/gui
Serás capaz de crear puntos de acceso para diferentes funciones del y-manuales/pyperclip-
blockchain, tales como añadir una transacción, usando el copiar-y-pegar-en-el-
microframework Flask, y luego ejecutar los programas en múltiples portapapeles/)
máquinas para crear una red descentralizada. También verás cómo
desarrollar una interfaz de usuario simple que interactúe con el Apagar, reiniciar y cerrar
blockchain y almacene la información para cualquier uso, como sesión en Windows y
pagos peer-to-peer (https://es.wikipedia.org/wiki/Peer-to-peer), Linux
conversaciones o comercio electrónico. (https://recursospython.com/gui
y-manuales/shutdown-
Python es un lenguaje de programación fácil de entender, esa es la windows-y-linux/)
razón por la que lo he elegido para este tutorial. A medida que
avances con este tutorial, implementarás un blockchain público y lo Enviar archivo vía socket
verás en acción. El código para una aplicación de ejemplo completa, en Python 3
escrita usando puro Python, está en GitHub. (https://recursospython.com/cod
de-fuente/enviar-
Obtener el código (https://github.com/satwikkansal/ibm_blockchain)
La lógica radica en el archivo views.py . Para realmente entender archivo-via-socket-en-
blockchain desde el principio, avancemos sobre él. python-3/)

Requisitos
Un conocimiento básico de programación en Python [véase el
tutorial de Python (https://tutorial.recursospython.com/)].
El microframework Flask (http://flask.pocoo.org/) (para crear
puntos de acceso para el servidor blockchain).
Comentarios
Fundamentos
recientes
Blockchain público vs. privado Recursos Python en psutil
– Utilidades
Una red blockchain pública, como la red Bitcoin, está
multiplataforma para
completamente abierta al público, y cualquiera puede unirse y
procesos
participar.
(https://recursospython.com/gui
En la otra mano, negocios que requieren de mayor privacidad, y-manuales/psutil-
seguridad y velocidad en las transacciones optan por una red utilidades-
blockchain privada, donde los participantes necesitan una multiplataforma-para-
invitación para unirse. Saber más procesos/#comment-971)
(https://www.ibm.com/blogs/blockchain/2017/05/the- Recursos Python en
difference-between-public-and-private-blockchain/). Decoradores
(https://recursospython.com/gui
En 2008, un artículo titulado Bitcoin: un sistema de dinero y-
electrónico peer-to-peer (https://bitcoin.org/bitcoin.pdf) fue manuales/decoradores/#comme
publicado por un individuo (o tal vez un grupo) llamado Satoshi 970)
Nakamoto. El artículo combinaba técnicas criptográficas y una red asdf en psutil – Utilidades
peer-to-peer sin la necesidad de confiar en una autoridad multiplataforma para
centralizada (como los bancos) para realizar pagos de una persona a procesos
otra. Nació Bitcoin. Además de Bitcoin, el mismo artículo introdujo (https://recursospython.com/gui
un sistema distribuido para almacenar información (ahora conocido y-manuales/psutil-
popularmente como «blockchain»), que tiene un campo de utilidades-
aplicación mucho más amplio que únicamente pagos o multiplataforma-para-
criptomonedas. procesos/#comment-
969)
Desde entonces, el interés por el blockchain ha estallado en Carlos Rodriguez en
prácticamente toda la industria. Blockchain es ahora la tecnología Decoradores
debajo de criptomonedas completamente digitales como Bitcoin, (https://recursospython.com/gui
tecnologías de computación distribuida como Ethereum, y y-
frameworks de código abierto como Hyperledger Fabric manuales/decoradores/#comme
(https://www.ibm.com/developerworks/cloud/library/cl-top- 968)
technical-advantages-of-hyperledger-fabric-for-blockchain- Recursos Python en Lista
networks/), sobre donde está montada la IBM Blockchain Platform desplegable (Combobox)
(https://www.ibm.com/developerworks/cloud/library/cl-ibm- en Tcl/Tk (tkinter)
blockchain-platform-develop-govern-operate-your-business- (https://recursospython.com/gui
network/). y-manuales/lista-
desplegable-combobox-
¿Qué es «blockchain»?
en-tkinter/#comment-
Blockchain es una forma de almacenar información digital. La 967)
información puede ser literalmente cualquier cosa. Para Bitcoin, son
transacciones (transferencias de Bitcoins de una cuenta a otra), pero
pueden incluso ser archivos; no importa. La información está
almacenada en forma de bloques, que están encadenados usando
hashes. De aquí el nombre «blockchain» [block = bloque, chain =
cadena, «cadena de bloques»].
Toda la magia radica en el modo en que la información es añadida y
almacenada en el blockchain, que produce algunas características
altamente deseables:

Inmutabilidad de la historia.
Invulnerabilidad del sistema.
Persistencia de la información.
No hay un solo punto de falla.

Ahora bien, ¿cómo es que blockchain obtiene estas características?


Nos iremos acercando a ello a medida que las vayamos
implementando. Empecemos.

Acerca de la aplicación

Definamos qué es lo que hará la aplicación que estamos


desarrollando. Nuestro objetivo es construir un sitio web simple que
permita a los usuarios compartir información. Puesto que el
contenido estará almacenado en el blockchain, será inmutable y
permanente.

Seguiremos un procedimiento de abajo hacia arriba para


implementar las cosas. Empecemos por definir la estructura de la
información que estaremos almacenando en el blockchain. Una
publicación (un mensaje publicado por cualquier usuario en nuestra
aplicación) será identificada por tres cosas esenciales:

1. Contenido
2. Autor
3. Fecha de publicación [timestamp]

1. Almacenar transacciones en bloques


Estaremos almacenando información en nuestro blockchain en un
formato que es ampliamente usado: JSON
(https://recursospython.com/guias-y-manuales/json/). Así es como
se verá una publicación almacenada en el blockchain:

"author": "nombre_del_autor",

"content": "Algunos pensamientos que el autor quiere


compartir",

"timestamp": "El tiempo en el que el contenido fue creado"

El término genérico «información» es generlamente reemplazado en


internet por el término «transacción». Por ende, para evitar
confusiones y ser consistentes, estaremos empleando el término
«transacción» para referirnos a información publicada en nuestra
aplicación de ejemplo.

Las transacciones están empaquetadas en bloques. Además, un


bloque puede contener una o más transacciones. Los bloques que
contienen las transacciones son generados frecuentemente y
añadidos al blockchain. Dado que puede haber múltiples bloques,
cada uno tendría que tener un identificador único:

1. class Block:
2. def __init__(self, index, transactions, timestamp):
3. self.index = []
4. self.transactions = transactions
5. self.timestamp = timestamp
2. Hacer los bloques inmutables
Nos gustaría detectar cualquier tipo de manipulación en la
información almacenada dentro de un bloque. En blockchain, esto
se hace usando una función hash.

Una función hash es una función que toma información de


cualquier tamaño y a partir de ella produce otra información de un
tamaño fijo, que generalmente sirve para identificar la entrada
[input]. Aquí hay un ejemplo en Python usando la función hash
sha256 .

1. >>> from hashlib import sha256


2. >>> data = "Alguna informacion de longitud
variada".encode("utf-8")
3. >>> sha256(data).hexdigest()
4. '7c79eb1f1853630a00ea195b8f2979f16c1ea8016d9e487e1099537c02f
513d9'
5. >>> sha256(data).hexdigest() # No importa cuántas veces lo
ejecutes, siempre retorna lo mismo.
6. '7c79eb1f1853630a00ea195b8f2979f16c1ea8016d9e487e1099537c02f
513d9'

Las características de una función hash ideal son:

Debería ser computacionalmente fácil de calcular.


Incluso el cambio de un simple bit de la información debería
cambiar por completo el hash.
No debería ser posible adivinar la información de entrada a partir
del hash de salida.

Ahora sabes qué es una función hash. Vamos a guardar el hash de


cada uno de los bloques en un campo dentro de nuestro objeto
Block para que actúe como una huella digital de la información que
contiene:

1. from hashlib import sha256


2. import json
3.
4. def compute_hash(block):
5. """
6. Una función que crea el hash del bloque.
7. """
8. block_string = json.dumps(self.__dict__, sort_keys=True)
9. return sha256(block_string.encode()).hexdigest()

Nota: En la mayoría de las criptomonedas, aun las transacciones


individuales en el bloque están cifradas, para formar un árbol hash
(también conocido como árbol de Merkle
(https://es.wikipedia.org/wiki/%C3%81rbol_de_Merkle)), y la raíz del
árbol puede ser usada como el hash del bloque. No es una condición
necesaria para el funcionamiento del blockchain, por lo que lo
omitiremos para mantener las cosas ordenadas y simples.

3. Encadenar los bloques


Bien, hemos montado los bloques. El blockchain supuestamente
tiene que ser una colección de bloques. Podemos almacenar todos
los bloques en una lista de Python (el equivalente a un arreglo
[array]). Pero esto no es suficiente, porque ¿qué sucedería si alguien
intencionalmente reemplaza un bloque en la colección? Crear un
nuevo bloque con transacciones alteradas, calcular el hash, y
reemplazarlo por cualquier otro bloque anterior no es una gran tarea
en nuestra implementación actual, porque mantendremos la
inmutabilidad y el orden de los bloques.

Necesitamos una solución para asegurarnos que cualquier cambio


en los bloques anteriores invalide la cadena entera. Una forma de
hacer esto es encadenar los bloques por su hash. Al encadenarlos de
esta forma, queremos decir incluir el hash del bloque anterior en el
actual. Así, si el contenido de cualquiera de los bloques anteriores
cambia, el hash del bloque va a cambiar, llevando a una discrepancia
con el campo previos_hash en el próximo bloque.

Perfecto, cada bloque está enlazado al anterior por el campo


previous_hash , ¿pero qué sucede con el primer bloque de todos? El
primer bloque es llamado el bloque génesis y es generado
manualmente o por alguna lógica única, en la mayoría de los casos.
Agreguemos el campo previous_hash a la clase Block e
implementemos la estructura inicial de nuestra clase Blockchain
(ver Listado 1).

Listado 1. La estructura inicial de nuestra clase Blockchain

1. from hashlib import sha256


2. import json
3. import time
4. class Block:
5. def__init__(self, index, transactions, timestamp,
previous_hash):
6. self.index = index
7. self.transactions = transactions
8. self.timestamp = timestamp
9. self.previous_hash = previous_hash
10.
11. def compute_hash(self):
12. block_string = json.dumps(self.__dict__,
sort_keys=True)
13. return sha256(block_string.encode()).hexdigest()

Y aquí está nuestra clase Blockchain :

1. class Blockchain:
2.
3. def __init__(self):
4. self.unconfirmed_transactions = [] # información
para insertar en el blockchain
5. self.chain = []
6. self.create_genesis_block()
7.
8. def create_genesis_block(self):
9. """
10. Una función para generar el bloque génesis y
añadirlo a la
11. cadena. El bloque tiene index 0, previous_hash 0 y
un hash
12. válido.
13. """
14. genesis_block = Block(0, [], time.time(), "0")
15. genesis_block.hash = genesis_block.compute_hash()
16. self.chain.append(genesis_block)
17.
18. @property
19. def last_block(self):
20. return self.chain[-1]

4. Implementar un algoritmo de prueba de


trabajo
(https://es.wikipedia.org/wiki/Sistema_de_pr
Aunque hay un problema. Si cambiamos el bloque anterior,
podemos recalcular los hashes de todos los bloques subsiguientes
sencillamente y crear un blockchain diferente pero válido. Para
prevenir esto, tenemos que hacer que la tarea de calcular un hash
sea difícil y aleatoria.

Así es como se hace. En lugar de aceptar cualquier hash para el


bloque, le agregaremos alguna condición. Agreguemos una
condición que nuestro hash deba empezar con dos ceros. Además,
sabemos que a menos que cambiemos el contenido del bloque, el
hash no va a cambiar.

Por lo que vamos a introducir un nuevo campo en nuestro bloque


llamado nonce. Un nonce es un número que cambiará
constantemente hasta que obtengamos un hash que satisfaga
nuestra condición. El número de ceros prefijados (el valor 2, en
nuestro caso) decide la «dificultad» de nuestro algoritmo de prueba
de trabajo. Además, notarás que nuestra prueba de trabajo es difícil
de calcular pero fácil de verificar una vez que averiguamos el nonce
(para verificar, simplemente tienes que ejecutar la función hash
nuevamente).

1. class Blockchain:
2. # Dificultad del algoritmo de prueba de trabajo.
3. difficulty = 2
4.
5. """
6. Código anterior...
7. """
8.
9. def proof_of_work(self, block):
10. """
11. Función que intenta distintos valores de nonce hasta
obtener
12. un hash que satisfaga nuestro criterio de
dificultad.
13. """
14. block.nonce = 0
15.
16. computed_hash = block.compute_hash()
17. while not computed_hash.startswith('0' *
Blockchain.difficulty):
18. block.nonce += 1
19. computed_hash = block.compute_hash()
20.
21. return computed_hash

Nótese que no hay una lógica concreta para averiguar el nonce


rápidamente; es simplemente fuerza bruta.

5. Añadir bloques a la cadena


Para agregar un bloque a la cadena, primero tendremos que verificar
si la prueba de trabajo es correcta y si el campo previous_hash del
bloque a añadir luego es igual al hash del último bloque en nuestra
cadena.

Veamos el código para insertar bloques en la cadena:

1. class Blockchain:
2. """
3. Código anterior...
4. """
5. def add_block(self, block, proof):
6. """
7. Una función que agrega el bloque a la cadena luego
de la verificación.
8. """
9. previous_hash = self.last_block.hash
10.
11. if previous_hash != block.previous_hash:
12. return False
13.
14. if not self.is_valid_proof(block, proof):
15. return False
16.
17. block.hash = proof
18. self.chain.append(block)
19. return True
20.
21. def is_valid_proof(self, block, block_hash):
22. """
23. Chquear si block_hash es un hash válido y satisface
nuestro
24. criterio de dificultad.
25. """
26. return (block_hash.startswith('0' *
Blockchain.difficulty) and
27. block_hash == block.compute_hash())

Minado

Las transacciones son almacenadas inicialmente en un conjunto de


transacciones no confirmadas. El proceso de poner transacciones no
confirmadas en un bloque y calcular la prueba de trabajo es
conocido como el minado [mining] de bloques. Una vez que el
nonce que satisface nuestra condición es averiguado, podemos decir
que el bloque ha sido minado, y es colocado en el blockchain.

En la mayoría de las criptomonedas (incluyendo Bitcoin), los mineros


suelen ser

premiados con alguna criptomoneda como una recompensa por


usar su potencia de cálculo para calcular la prueba de trabajo. Así es
como se ve nuestra función de minado.

1. class Blockchain:
2. """
3. Código anterior...
4. """
5.
6. def add_new_transaction(self, transaction):
7.
self.unconfirmed_transactions.append(transaction)
8.
9. def mine(self):
10. """
11. Esta función sirve como una interfaz para añadir las
transacciones
12. pendientes al blockchain añadiéndolas al bloque y
calculando la
13. prueba de trabajo.
14. """
15. if not self.unconfirmed_transactions:
16. return False
17.
18. last_block = self.last_block
19.
20. new_block = Block(index=last_block.index + 1,
21.
transactions=self.unconfirmed_transactions,
22. timestamp=time.time(),
23. previous_hash=last_block.hash)
24.
25. proof = self.proof_of_work(new_block)
26. self.add_block(new_block, proof)
27. self.unconfirmed_transactions = []
28. return new_block.index
Muy bien, ya casi estamos. Puedes ver el código completo hasta este
momento en GitHub
(https://github.com/satwikkansal/ibm_blockchain/blob/3d252de03586

6. Crear interfaces
Bien, ahora es momento de crear interfaces para nuestro nodo para
interactuar con otros compañeros así como con la aplicación que
vamos a crear. Estaremos utilizando Flask para crear una REST-API
que interactúe con nuestro nodo. Aquí está el código para ello:

1. from flask import Flask, request


2. import requests
3.
4. app = Flask(__name__)
5.
6. # la copia del nodo del blockchain
7. blockchain = Blockchain()

Necesitamos un punto de acceso para nuestra aplicación para enviar


una nueva transacción. Éste será utilizado por nuestra aplicación
para añadir nueva información (publicaciones) al blockchain:

1. @app.route('/new_transaction', methods=['POST'])
2. def new_transaction():
3. tx_data = request.get_json()
4. required_fields = ["author", "content"]
5.
6. for field in required_fields:
7. if not tx_data.get(field):
8. return "Invlaid transaction data", 404
9.
10. tx_data["timestamp"] = time.time()
11.
12. blockchain.add_new_transaction(tx_data)
13.
14. return "Success", 201

Aquí hay un punto de acceso para retornar la copia del blockchain


que tiene el nodo. Nuestra aplicación estará usando este punto de
acceso para solicitar todas las publicaciones para mostrar.

1. @app.route('/chain', methods=['GET'])
2. def get_chain():
3. chain_data = []
4. for block in blockchain.chain:
5. chain_data.append(block.__dict__)
6. return json.dumps({"length": len(chain_data),
7. "chain": chain_data})

Y aquí hay otro para solicitar al nodo que mine las transacciones sin
confirmar (si es que hay alguna).

1. @app.route('/mine', methods=['GET'])
2. def mine_unconfirmed_transactions():
3. result = blockchain.mine()
4. if not result:
5. return "No transactions to mine"
6. return "Block #{} is mined.".format(result)
7.
8.
9. # punto de acceso para obtener las transacciones
10. # no confirmadas
11. @app.route('/pending_tx')
12. def get_pending_tx():
13. return json.dumps(blockchain.unconfirmed_transactions)
14.
15.
16. app.run(debug=True, port=8000)

Ahora, si te gustaría, puedes jugar con nuestro blockchain creando


algunas transacciones y luego minándolas usando una herramienta
como cURL o Postman.

7. Establecer consenso y descentralización


El código que hemos implementado hasta ahora está pensado para
ser ejecutado en una sola computadora. Incluso aunque estamos
enlazando bloques con hashes, todavía no podemos confiarnos de
una única entidad. Necesitamos múltiples nodos para mantener
nuestro blockchain. Entonces, creemos un punto de acceso para
permitirle a un nodo tener conciencia de otros compañeros en la
red:

1. # la dirección de otros miembros que participan en la red


2. peers = set()
3.
4. # punto de acceso para añadir nuevos compañeros a la red.
5. @app.route('/add_nodes', methods=['POST'])
6. def register_new_peers():
7. nodes = request.get_json()
8. if not nodes:
9. return "Invalid data", 400
10. for node in nodes:
11. peers.add(node)
12.
13. return "Success", 201

Te habrás dado cuenta que hay un problema con los múltiples


nodos. Debido a la manipulación intencional o por razones
inintencionales, la copia de cadenas de algunos nodos puede diferir.
En ese caso, necesitamos ponernos de acuerdo respecto de alguna
versión de la cadena para mantener la integridad de todo el sistema.
Necesitamos consensuar.

Un algoritmo simple de consenso podría ser ponernos de acuerdo


respecto de la cadena válida más larga cuando las cadenas de
diferentes participantes de la red aparentan divergir. La racionalidad
debajo de este procedimiento es que la cadena más larga es una
buena estimación de la mayor cantidad de trabajo realizado:

1. def consensus():
2. """
3. Nuestro simple algoritmo de consenso. Si una cadena
válida más larga es
4. encontrada, la nuestra es reemplazada por ella.
5. """
6. global blockchain
7.
8. longest_chain = None
9. current_len = len(blockchain)
10.
11. for node in peers:
12. response =
requests.get('http://{}/chain'.format(node))
13. length = response.json()['length']
14. chain = response.json()['chain']
15. if length > current_len and
blockchain.check_chain_validity(chain):
16. current_len = length
17. longest_chain = chain
18.
19. if longest_chain:
20. blockchain = longest_chain
21. return True
22.
23. return False

Y ahora finalmente, necesitamos desarrollar una forma para que


cada nodo pueda anunciar a la red que ha minado un bloque para
que todos puedan actualizar su blockchain y seguir minando otras
transacciones. Otros nodos pueden simplemente verificar la prueba
de trabajo y añadirla a sus respectivas cadenas:

1. # punto de acceso para añadir un bloque minado por alguien


más a la cadena del nodo.
2. @app.route('/add_block', methods=['POST'])
3. def validate_and_add_block():
4. block_data = request.get_json()
5. block = Block(block_data["index"],
block_data["transactions"],
6. block_data["timestamp",
block_data["previous_hash"]])
7.
8. proof = block_data['hash']
9. added = blockchain.add_block(block, proof)
10.
11. if not added:
12. return "The block was discarded by the node", 400
13.
14. return "Block added to the chain", 201
15.
16. def announce_new_block(block):
17. for peer in peers:
18. url = "http://{}/add_block".format(peer)
19. requests.post(url, data=json.dumps(block.__dict__,
sort_keys=True))

El método announce_new_block debería ser llamado luego que un


bloque ha sido minado por el nodo, para que los compañeros lo
puedan añadir a sus cadenas.

8. Crear la aplicación
Bien, el backend está listo. Puedes ver el código hasta este momento
en GitHub
(https://github.com/satwikkansal/ibm_blockchain/blob/631346a130a4ef

Ahora, es tiempo de empezar a trabajar en la interfaz de nuestra


aplicación. Hemos usado plantillas Jinja2 para hacer las páginas de la
web y un poco de CSS para que se vea agradable.

Nuestra aplicación necesita conectarse a un nodo en la red


blockchain para obtener la información y también para enviar nueva.
Puede haber múltiples nodos también:

1. import datetime
2. import json
3.
4. import requests
5. from flask import render_template, redirect, request
6.
7. from app import app
8.
9.
10. CONNECTED_NODE_ADDRESS = "http://127.0.0.1:8000"
11.
12. posts = []
La función fetch_posts obtiene la información de la URL /chain del
nodo, la procesa y la almacena localmente.

1. def fetch_posts():
2. get_chain_address = "
{}/chain".format(CONNECTED_NODE_ADDRESS)
3. response = requests.get(get_chain_address)
4. if response.status_code == 200:
5. content = []
6. chain = json.loads(response.content)
7. for block in chain["chain"]:
8. for tx in block["transactions"]:
9. tx["index"] = block["index"]
10. tx["hash"] = block["previous_hash"]
11. content.append(tx)
12.
13. global posts
14. posts = sorted(content, key=lambda k:
k['timestamp'],
15. reverse=True)

La aplicación tiene un formulario HTML para tomar la entrada del


usuario y luego realiza una petición POST a un nodo conectado para
añadir la transacción al conjunto de transacciones sin confirmar. La
transacción luego es minada por la red, y finalmente será obtenida
una vez que recarguemos nuestro sitio web:

1. @app.route('/submit', methods=['POST'])
2. def submit_textarea():
3. """
4. Punto de acceso para crear una nueva transacción vía
nuestra
5. aplicación.
6. """
7. post_content = request.form["content"]
8. author = request.form["author"]
9.
10. post_object = {
11. 'author': author,
12. 'content': post_content,
13. }
14.
15. # Submit a transaction
16. new_tx_address = "
{}/new_transaction".format(CONNECTED_NODE_ADDRESS)
17.
18. requests.post(new_tx_address,
19. json=post_object,
20. headers={'Content-type':
'application/json'})
21.
22. return redirect('/')

9. Ejecutar la aplicación
¡Está lista! Puedes encontrar el código final en GitHub
(https://github.com/satwikkansal/ibm_blockchain).

Para ejecutar la aplicación:

1. Inicia el servidor del nodo blockchain:

python node_server.py

2. Ejecuta la aplicación:

python run_app.py

Deberías ver la aplicación corriendo en http://localhost:5000


(http://localhost:5000/).
1. Intenta enviando algo de información, y deberías ver algo como
esto:

(https://recursospython.com/wp-
content/uploads/2018/06/fig01.png)

2. Presiona el botón Request to mine, y deberías ver algo así:

(https://recursospython.com/wp-
content/uploads/2018/06/fig02.jpg)

3. Presiona el botón Resync, y deberías ver la aplicación


resincronizando con la cadena:

(https://recursospython.com/wp-
content/uploads/2018/06/fig03.png)

Verificar transacciones

Tal vez hayas notado una falla en la aplicación: cualquiera puede


cambiar cualquier nombre y publicar cualquier contenido. Una
forma de resolver esto es creando los usuarios usando criptografía
de clave pública-privada
(https://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica).
Cada usuario nuevo necesita una clave pública (análoga a un nombre
de usuario) y una clave privada para ser capaces de publicar en
nuestra aplicación. Las claves actúan como una firma digital. La clave
pública solo puede decodificar el contenido encriptado por la
correspondiente clave privada. Las transacciones serán verificadas
usando la clave pública del autor antes de añadir cualquier bloque.
De esta manera, sabremos exactamente quién escribió el mensaje.

Conclusión
Este tutorial cubrió los fundamentos de un blockchain público. Si lo
seguiste completamente, has implementado un blockchain desde
cero y creado una simple aplicación permitiendo a los usuarios
compartir información en él.

Acerca del autor


Satwik Kansal es un desarrollador de software con experiencia en
tecnología blockchain y ciencia de datos. Conéctate con él en Twitter
(https://www.twitter.com/satwikkansal/) o LinkedIn
(https://www.linkedin.com/in/satwikkansal/) o en su sitio web
(https://www.satwikkansal.xyz/).

(/#facebook) (/#twitter)

Entrada publicada en
Guías y Manuales (https://recursospython.com/category/guias-y-manuales/) con las
etiquetas blockchain (https://recursospython.com/tag/blockchain/)

flask (https://recursospython.com/tag/flask/)

 Copiar objetos con el módulo estándar «copy»


(https://recursospython.com/guias-y-manuales/modulo-estandar-
copy/)

Crear documentos PDF en Python con ReportLab 


(https://recursospython.com/guias-y-manuales/crear-documentos-
pdf-en-python-con-reportlab/)

34 comentarios.

Sergio says:
julio 28, 2021 at 1:30 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-954)

Estimados, está muy claro el tutorial y me funcionó en su


totalidad, lo que no termino de entender es porque indican
que la blockchain no se almacena en ningún lado, tengo
entendido que, para minar, por ejemplo en la blockchain de
Bitcoin tengo que «bajarla» y se estima que pesa unos 350 GB,
lo cual es imposible de mantener en memoria, de ahí mi
consulta,

Supongamos que hay una tormenta solar o lo que fuere y el


planeta entero queda sin electricidad un par de días,
entonces, se perderían todas las blockchains? Ocurriría como
lo que sucede con la blockchain de este tutorial, que, cuando
cancelo la ejecución y vuelvo a ejecutar, se perdieron las
transacciones realizadas?
Gracias por vuestro tiempo y amabilidad

Responder

Recursos Python says:


julio 28, 2021 at 1:56 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-955)

Hola, Sergio. El código de este artículo almacena la


cadena de bloques en memoria (es el objeto
blockchain ). Para evitar que se pierda al cerrar el
programa, podés almacenarlo físicamente en el disco
en el formato que quieras. Así, si ocurriera el
fenómeno extraordinario de que el planeta entero se
quede sin electricidad, simplemente durante ese
período no habría posibilidad de minar
transacciones, pero la cadena de bloques (o sea, la
información de todas las transacciones) no se pierde.

Saludos

Responder

LUIS says:
junio 30, 2021 at 5:22 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-944)

Muchas gracias por el artículo. Explica muchas cosas que me


costaba entender.

Pero sigo teniendo dudas con el «servidor». Su papel y su sitio

¿Qué deben tener instalado los usuarios que usan la


aplicación? Si es que hay algo más que el navegador.

Responder

Recursos Python says:


junio 30, 2021 at 5:54 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-945)
Hola, Luis. No tienen que tener instalado nada, solo el
navegador. El servidor corre en tu computadora local
durante el desarrollo. Cuando se trata de un proyecto
real, para correr el servidor se compra una máquina
virtual que se conoce como hosting.

Saludos

Responder

LUIS says:
julio 1, 2021 at 2:59 am
(https://recursospython.com/guias-
y-manuales/aplicacion-blockchain-
desde-cero/#comment-946)

Hola, muchas gracias por la respuesta.

Entonces lo había entendido bien. Hay que


montar un servidor al fin y al cabo, central.
Por lo tanto no estamos hablando de una
aplicación descentralizada.

¿Se podría decir que es pseudo blockchain o


semi blockchain?

Responder

Recursos Python
says:
julio 1, 2021 at 12:32 pm
(https://recursospython.com/guias-
y-manuales/aplicacion-
blockchain-desde-
cero/#comment-947)

Hola, Luis.

Es un blockchain con todas las


letras. Únicamente si ejecutás un
solo servidor de nodos será
centralizado: si se apaga ese nodo, se
cae la red. La idea es ejecutar
múltiples nodos en distintos
servidores. Cuantos más servidores,
más robusta y descentralizada es la
red. Si se caen todos los mineros de
Bitcoin, se destruye la red. Pero es
algo muy improbable, ya que son
millones de nodos.
Saludos

Responder

Sergio says:
junio 16, 2021 at 10:00 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-933)

Hola.

1) Inicie el servidor del nodo blockchain:

Luego,

2)Ejecuta la aplicación:

y cuando voy a ver la aplicación corriendo en


http://localhost:5000 (http://localhost:5000), me arroja el
mensaje»request.exceptions.ConnectionError». Sabes por
que me aparece ese error? Que deberia hacer para poder
solucionarlo? Yo hace poco que empece a estudiar Python, y
no puedo encontrar el problema.

Saludos

Responder

Recursos Python says:


junio 17, 2021 at 1:57 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-935)

Hola, ¿dónde te arroja ese mensaje? ¿Al ejecutar


python node_server.py o python run_app.py arroja
un error?

Responder

edu says:
mayo 29, 2021 at 5:16 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-922)
ultima cosa

esto va dentro de class block o fuera , a si y hay que eliminar


los»>>>»?

>>> from hashlib import sha256

>>> data = «Alguna informacion de longitud


variada».encode(«utf-8»)

>>> sha256(data).hexdigest()

‘7c79eb1f1853630a00ea195b8f2979f16c1ea8016d9e487e1099537c02f513d9’
>>> sha256(data).hexdigest() # No importa cuántas veces lo
ejecutes, siempre retorna lo mismo.

‘7c79eb1f1853630a00ea195b8f2979f16c1ea8016d9e487e1099537c02f513d9’

Responder

Recursos Python says:


mayo 29, 2021 at 11:29 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-924)

Hola, eso va en la consola interactiva de Python, y sí


se borran los «>>>». Acá tenés información sobre la
consola interactiva:
https://tutorial.recursospython.com/consola-
interactiva/
(https://tutorial.recursospython.com/consola-
interactiva/). Te recomiendo que leas primero algún
tutorial introductorio de Python.

Saludos

Responder

edu says:
mayo 29, 2021 at 5:13 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-921)

una pregunta, soy bastante novato y :

primer:

como cambio esto

app.run(…, port=nuevo_puerto). y esto para q8ue sirve

segundo:

como ejecuto algo con esto, es decir done me tengo que ir y


que tengi que hacer

run_app.py.
Responder

Gonzalo says:
abril 8, 2021 at 9:14 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-883)

hola! quiero correr la app pero me tira el siguiente error:


request.exceptions.ConnectionError… que puede ser?

Responder

Recursos Python says:


abril 8, 2021 at 11:28 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-884)

Hola. ¿Iniciaste primero el servidor vía python


node_server.py ?

Responder

Marcos says:
marzo 4, 2021 at 9:24 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-861)

Excelente Post..!

Responder

Miroslav says:
febrero 17, 2021 at 6:54 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-853)
Hola, genesis_block.hash = genesis_block.compute_hash() no
entiendo esta línea por el » hash» a secas sin nada en la
declaración de genesis_block.hash ?es un método hash() y va
a secas…

Saludos

Responder

Recursos Python says:


febrero 17, 2021 at 9:21 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-854)

Hola. En Python no es necesario declarar los


atributos de una clase. hash es un atributo de
genesis_block que se crea en el momento en que se
le asigna un valor.

Saludos!

Responder

Satellite says:
octubre 5, 2020 at 3:56 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-798)

Hola muy buenas, hay algún ejemplo donde este explicado


como crear los usuarios con las claves publicas-privadas que
pueda asociarse a lo ya descrito? muchas gracias genial el
post!

Responder

Carlos Gonzalez says:


mayo 4, 2020 at 7:45 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-725)
hola buenas tardes, me gustaría saber si eso mismo lo puedo
aplicar en una gestión de automóviles, con recursos mixtos
para multas, así como control de cada vehículo

Responder

Recursos Python says:


mayo 5, 2020 at 12:08 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-727)

Hola Carlos. Es muy amplia tu pregunta como para


darte una respuesta detallada, pero en principio sí, lo
podés aplicar en lo que quieras.

Saludos

Responder

Alexander says:
abril 20, 2020 at 9:43 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-680)

Felicitaciones, excelente tutorial, mil gracias amigo.

Responder

Michelle says:
marzo 30, 2020 at 6:59 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-658)

Que necesito para empezar a programar. Que programa uso?


O cómo se empieza esto?

SALUDOS!!

Responder
Recursos Python says:
marzo 31, 2020 at 11:16 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-661)

Hola, empezá por descargar Python desde


https://www.python.org/ (https://www.python.org/).

Responder

Fabian says:
julio 3, 2019 at 1:18 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-557)

Te hago una consulta, soy totalmente novato en el tema de


blockchain, y queria validar un punto. Se utiliza alguna base
de datos en los nodos para guardar la información? O es
unicamente informacion en memoria? En el caso que se use,
cual/cuales son recomendadas? Gracias!

Responder

Recursos Python says:


julio 3, 2019 at 6:31 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-558)

Hola Fabian. No se usa ninguna base de datos,


porque en ese caso la información estaría
centralizada en un solo lugar, lo cual es contrario a la
filosofía del blockchain y el peer-to-peer.

Saludos!

Responder

Fabian says:
julio 4, 2019 at 10:59 am
(https://recursospython.com/guias-
y-manuales/aplicacion-blockchain-
desde-cero/#comment-559)
Entiendo lo de descentralización, pero
imaginaba que cada nodo tenia su base de
datos con los bloques aprobados y los
pendientes. Entonces la información queda
en memoria unicamente? Desconozco
python, pero entonces si reinicio el server se
pierde la información del nodo? (igualmente
entiendo que si esto pasa la información
estaria en otro nodo con lo que se
restauraria). Aprovecho para hacer otra
consulta, tiene que haber un lugar central
donde se administren los nodos y se asigne
el nodo al cual se va a enviar la informacion?
Sino como funciona la asignacion del
CONNECTED_NODE_ADDRESS?

Responder

Angel Ortiz says:


junio 22, 2019 at 9:02 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-553)

Me da error de Python Interpreter al cargar el Views.py en mi


PythonProjects, que version de Python debemos seleccionar?

Responder

Recursos Python says:


junio 22, 2019 at 8:27 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-554)

Hola Angel, el archivo que tenés que ejecutar es


run_app.py .

Saludos

Responder

aargom says:
marzo 3, 2019 at 9:18 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-529)

Hola que tal, alguien tiene idea en donde puedo conseguir


mayor información sobre este tema, sobre todo que sea
información practica y no tan teórica? Gracias por el post,
muy útil.

Responder

Inge says:
febrero 28, 2019 at 1:51 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-524)

Exactamente que funcion debo usar para agregar un nonce


ganador al blockchain.

Responder

Victor Aguirre says:


febrero 16, 2019 at 2:40 am
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-519)

¿El puerto 5000 lo escoje por defecto Flask?

Responder

Recursos Python says:


febrero 17, 2019 at 11:41 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-520)

Hola Victor. Sí, ese es el puerto por defecto. Podés


cambiarlo vía app.run(..., port=nuevo_puerto) .

Responder

Jose says:
abril 26, 2021 at 11:12 am
(https://recursospython.com/guias-
y-manuales/aplicacion-blockchain-
desde-cero/#comment-897)

Hola, es posible crear una aplicación de


intercambio de dinero tipo binance o
coinbase , pero de no esa magnitud? Quiero
crear una aplicación solo para usuarios
médicos de mi ciudad , que puedan cambiar
su dinero que reciben a Btc , eth, etc…

Responder

Recursos Python
says:
abril 26, 2021 at 12:34 pm
(https://recursospython.com/guias-
y-manuales/aplicacion-
blockchain-desde-
cero/#comment-898)

Hola. Con los conocimientos


suficientes, sí, es posible.

Saludos

Responder

Rafael says:
diciembre 30, 2018 at 10:25 pm
(https://recursospython.com/guias-y-
manuales/aplicacion-blockchain-desde-
cero/#comment-504)

Interesante como cultura informática.

Responder

Deja una respuesta

Comentario
Nombre * Email *

Publicar el comentario

© 2013 - 2021

¡Suscríbete a nuestra newsletter! (https://www.recursospython.com/newsletter/)

Políticas de Uso y Privacidad (https://www.recursospython.com/politicas-de-uso-y-privacidad/)

En inglés: Python Assets (https://pythonassets.com/)

(https://creativecommons.org/licenses/by-nc/3.0/deed.es)

También podría gustarte