Tenemos la cadena de
Blockchain por un lado, los nodos
peer-to-peer que tienen una copia de la
Blockchain, tenemos los
SmartContracts que implementan lógica, tenemos un
Wallet, tenemos un front para poder acceder con experiencia de usuario (o algo similar, ya que ésta es una de las grandes barreras de uso del mundo
Web3, la experiencia de usuario). Son muchas piezas que debemos colocar y entender cómo interaccionan entre ellas. Este artículo intentará acercar de manera sencilla un mapa en forma de pieza e intentar mostrar cómo se unen las piezas:
- Blockchain: Al final es nuestra ‘base de datos’ distribuida, la que hace que los datos sean redundantes e ‘inmutables’. Almacena la información de la Web3.
- SmartContract: es el que aporta la lógica para llevar a cabo las operaciones que se quieran hacer en el mundo Web3.
- DApp: permite acceder e interactuar a los contratos que podemos encontrar en una Blockchain.
¿Y qué ocurre con el
front-end y el
back-end? Pues la parte frontal la dejamos para
JS (y los
React, muchas de las aplicaciones utilizan este lenguaje) y el
back-end para… ¿
Flask? Sí, con
Flask se pueden hacer muchas cosas y
DApps también.
Definiendo una DApp
Para ejemplificar el uso de nuestra primera
DApp vamos a proponer el siguiente escenario:
- Tendremos una cadena de Blockchain de desarrollo: En este caso utilizaremos Ganache-Cli. Esta Blockchain estará ejecutandose en el puerto 8545 y en localhost. Accesible a través de http://localhost:8545 y una ChainID de 1337.
- Crearemos un SmartContract de ejemplo denominado Hi: Este contrato será desplegado sobre la Blockchain con Remix IDE (el IDE de Ethereum Project). Cuando despleguemos el contrato nos quedaremos con la dirección del contrato y el ABI de éste. El ABI es el Application Binary Interface, necesario para conocer qué funciones tiene un contrato y cuáles son los parámetros de entrada y las salidas que puede generar dicho contrato. Es fundamental.
- Crearemos una DApp con Flask: Diferenciaremos dos partes, la parte de plantillas dónde utilizaremos JS para interactuar en la parte cliente y conectar con Metamask y utilizar la parte de Flask para interactuar con la Blockchain y los SmartContracts a través de la librería Web3.py.
Lo primero que haremos es levantar
Ganache-Cli en consola. Si no indicamos nada con los parámetros de
Ganache-Cli, por defecto, nos crea
10 cuentas con
100ETH cada una. Además, nos proporcionar las claves privadas para que juguemos con ello.
Figura 3: Creación de cuentas den Ganache-Cli
Ahora, vamos a crearnos un
SmartContract de prueba. Este contrato se llamara
Hi (hi.sol) y tiene el siguiente aspecto:
Figura 4: SmartContract hi.sol
Como se puede ver, el contrato no hace nada más que almacenar la frase “
hola mundo” y dispone de una función denominada
getMessage(). Esta función devuelve el contenido de la variable ‘
message’, en este caso “
hola mundo”. Con
Remix IDE se puede compilar fácilmente el código y obtener el
ABI del contrato y el
Bytecode (el contrato compilado con sus dependencias). El aspecto del
ABI es el siguiente:
Figura 5: Aspecto del ABI de nuestro ejemplo
Como se puede ver en el
ABI tenemos una función
getMessage con ningún parámetro de entrada y que genera una salida de tipo
String (el mensaje). Con
Remix IDE podemos conectarnos fácilmente al proveedor que tenemos activo, en este caso a
Ganache-Cli. Para ello, vemos el desplegable de ‘
Environment’ y vemos las diferentes opciones. Elegimos
Ganache Provider. Vemos como se encarga el entorno, las cuentas, los
ETH de cada cuenta referente a
Ganache-Cli.
Figura 6: Configuración de Ganache Provider
Desplegamos el
SmartContract con
Remix IDE y obtenemos una instancia con la dirección del contrato. Esto es importante, ya que después necesitaremos el
ABI como la dirección del contrato para interactuar con él.
Creando la DApp
Ahora vamos a comenzar un proyecto para generar la
DApp. Vamos a crear el proyecto en dos partes. Hay una parte que es puro
Flask y en el que se mostrará cómo se puede acceder a la
Blockchain e interactuar con los contratos con la librería
web3.py (incluso podemos desplegar contratos, generando transacciones sobre la
Blockchain) y, por otro lado, interactuaremos con la librería
ethers.js a través de
Javascript puro.
Comenzamos por la parte de
ethers.js. Para ello, pensemos en la aplicación
Flask con la ruta
‘/’. Cuando recibimos una petición a este recurso lanzaremos un
render_template para ‘
pintar’ un
index.html.
Figura 7: "Pintando" un index.html
En el
index.html vamos a meter el código
HTML (al cual se le puede pasar parámetros desde
Flask para crearlo en función de las necesidades o parámetros de entrada previos) y el código
Javascript que interactuará con
Metamask.
Figura 8: Código Javascript para interactuar con la wallet Metamask
En este código se puede ver como
Flask devuelve el
index.html y éste dispone de una información extraída de la conexión con
Metamask. El código
Javascript utilizado permite interactuar con
Metamask y obtener la dirección de cuenta activa con la que conectar. Antes de conectar, la web que obtenemos es la siguiente:
Figura 9: Antes de conectar nuestra wallet
Tanto el texto como el botón de ‘
Consultar Contract Address’ están deshabilitados. Cuando le damos a ‘
Conectar a Metamask’ se activa la función ‘
Connect()’ que vemos en el código y se hace la conexión con éste.
Figura 10: Conexión con nuestra wallet Metamask
Metamask aparece y elegimos la cuenta con la que queremos conectarnos. Una vez hecho esto la web cambiará de ésta y donde ponía ‘
Address User’ se indicará la dirección pública del usuario conectado. Ahora podíamos hacer consultas con la librería para saber el balance, por ejemplo, del usuario.
Figura 11: Address obtenida
El botón ‘
Consultar Contract Address’ queda habilitado y la caja de texto también. Ahora que hay un usuario conectado podemos interactuar con la segunda parte. Ahora, para ejemplificar cómo
Flask puede interactuar (a través del
back-end) con la
Web3 (usando la librería
web3.py) vamos a pensar en el siguiente ejemplo:
- Introducimos la dirección del contrato que desplegamos con Remix IDE en la Blockchain local.
- Esto llegará por POST a un recurso de Flask y haciendo uso de la librería web3.py nos conectaremos al proveedor (localhost y puerto 8545) y consultaremos algo del contrato, por ejemplo, las funciones que tiene e invocaremos una función, la de getMessage().
Figura 12: Usando web3.py podemos interacturar con el SmartContract y la Wallet.
Aquí vemos cómo conectamos con el proveedor a través de
Web3.HTTPProvider. Hacemos uso de
web3.eth.contract como método para conectarnos (a través de la dirección de contrato y el
ABI a un contrato accesible a través de dicho proveedor.
Figura 13: Datos del contrato
Por último, vemos cómo invocar funciones con
contract_object.functions.getMessage().call(). Este es un ejemplo interesante porque se ve todo lo que podemos ir haciendo de forma ordenada. El resultado en el navegador es el siguiente:
Con esto, finalizamos nuestro ejemplo de
DApp y formas de interactuar con
Web3, una parte con
JavaScript y otra parte con
Python / Flask. Sin duda, un ejemplo para empezar a jugar. Pronto más artículos donde jugaremos con la tecnología
Web3.