En l’entrada d’avui veuràs com utilitzar Web3.js de manera senzilla, directament a la consola del navegador. Per a fer-ho, importarem la dependència a través d’un CDN. A partir d’aquí, inicialitzarem un contracte, mitjançant la seva adreça i ABI, i interactuarem amb ell, construïnt les nostres pròpies transaccions.
¿Què és Web3.js?
Web3.js és una col·lecció de biblioteques que permeten interactuar amb un node d’Ethereum local o remot, mitjançant les connexions HTTP, IPC o WebSocket.
És important no confondre Web3.js, la llibrería, amb el concepte de Web3 del que últimament tant es parla, i que representa bàsicament la idea d’un nou Internet distribuït basat en la tecnología blockchain i en l’ús de contractes intel·ligents.
Dit això, passem a centrar-nos la en Web3.js.
Aquesta dependència podem dir que representa una unió de llenguatge JavaScript per a la interfície JSON RPC d’Ethereum, que la fa directament utilitzable en tecnologia web, ja que JavaScript és compatible de manera nativa a gairebé tots els navegadors web.
Web3.js també s’utilitza habitualment al costat del servidor a les aplicacions Node.js i a les aplicacions d’escriptori basades en Electron.
A sota et copio l’accés a la referència oficial de Web3, per si vols aprofondir més en tots els seus usos.
https://web3js.readthedocs.io/
Importar Web3.js a la Consola del Navegador
Fet aquesta breu introducció a Web3.ja, començem a entrar en la materia que ens ocupa el post.
Com he dit al principi, l’objectiu es fer una demostració de com pots desplegar un contracte que ja tinc predefinit, i interactuar amb ell a través de Web3.js.
En aquest cas, aprofitant que tenim el contracte a Remix, no utilitzarem cap IDE, sino que farem ús de la consola del teu navegador habitual, que pots obrir prement F12.
El primer pas és importar Web3.js CDN a la consola del navegador, copiant el següent codi:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'script.js';
script.src = 'https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js';
document.head.appendChild(script);
En aquest cas, com pots veure, estem utilitzant un CDN com a dependència, ja que és la manera que considero més senzilla i ràpida. De totes maneres, si no vols dependre d’una tercera part, també pots guardar una copia de la llibreria en local, i utilitzar aquest fitxer com a depèndencia, en comptes del CDN.
Crear Instancia de Web3 i Inicialitzar el Contracte
A continuació, crearem una instància de la web3 i inicialitzarem el nostre contracte amb la seva adreça i ABI.
Primer de tot el que cal fer és connectar Metamask en el browser, ja que és el que ens farà de proveïdor. Per establir aquesta connexió, pots copiar aquestes líneas en la mateixa consola del navegador:
ethereum.request({ method: 'eth_requestAccounts' })
web3 = new Web3(window.ethereum
Després de copiar aquestes líneas, veuràs que Metamask et demanarà seleccionar una de les teves comptes i connectar-la.
Fet això, pots executar per consola aquest mètode que ofereix Web3.js, i que et permetrà comprobar que estigui llegint bé la teva adreça de Metamask. L’adreça retornada hauría de coincidir amb l’adreça de Metamask des de la que estas operant.
web3.givenProvider.selectedAddress
A continuació, per crear la teva instància del contracte, el primer que necessitem és l’ABI del contracte, que pots obtenir en el moment de compilar el teu smart contract. En l’exemple que ens ocupa he utilitzat Remix per escriure i compilar el meu contracte, com pots veure en el vídeo.
Un cop compilat el contracte, ja podràs veure disponible la seva ABI i copia-la al porta-papers. A continuació, en la consola del navegador, pots crear una nova variable, anomenada ABI, i enganxar el contingut que has copiat des de Remix.
Pots seguir els passos tu mateix, amb el teu propi contracte, pero si vols seguir el mateix exemple que he utilitzat, a continuació tens el codi que has d’enganxar a la consola del navegador, amb l’ABI del meu contracte.
const ABI = [ { "inputs": [], "name": "retrieve", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "num", "type": "uint256" } ], "name": "store", "outputs": [], "stateMutability": "nonpayable", "type": "function" } ]
La següent cosa que necessites per crear la instància del contracte, és la seva adreça. L’adreça del contracte la podràs obtenir en el moment de desplegar el contracte en una cadena de blocs.
Per desplegar el contracte des de Remix, cal indicar els seguents paràmetres, com veuràs en el vídeo:
- Environment. Aquí, si utilitzes Metamask, has de seleccionar “Injected Web3” per indicar que el proveïdor és Metamask.
- Xarxa o cadena de blocs. En l’exemple del vídeo, veuràs que em detecta automàticament la testnet de Rinkeby, ja que és la que tinc conectada a Metamask.
A partir d’aquí, previa confirmació de Metamask, ja podràs fer el deployment. Assegura’t, però, de disposar d’alguns tokens en l’adreça de Metamask des d’on el facis, ja que desplegar un contracte consumeix gas.
Si estàs en una testnet, pots aconseguir tokens fàcilment des de qualsevol Faucet.
Un cop desplegat el contracte, veuràs que des de Remix mateix ja tens accés a executar les seves funcions i testejar la seva funcionalitat des del punt de vista de l’usuari que interactuarà amb el contracte.
En aquest exercici, però, el que volem és interactuar amb el contracte des del navegador, a través de Web3.js.
El que necessitem en aquest punt és copiar l’adreça del contracte, que la podràs localitzar a Remix, a l’apartat de Deployed Contracts, i enganxar-la a la consola, dins d’una variable. Si vols utilitzar el mateix exemple del vídeo, pots copiar directament el següent fragment de codi:
const SSaddress = "0x2Fdf7b37a1802c9485B5E90bfC182A88a220300f"
Amb tot això, ja podràs crear la instància del contracte i afegir el proveïdor del navegador, amb les següents ordres:
const simpleStorage = new web3.eth.Contract(ABI, SSaddress)
simpleStorage.setProvider(web3.givenProvider)
Interactuar amb el Contracte a través de Web3.js
Ara ja podem interactuar amb el contracte des del nostre navegador, a través de Web3.js. Si has utilitzat el mateix contracte del meu exemple, veuràs que disposa de dues funcions, una de lectura, i una d’escriptura.
Anem a ejecutar el primer mètode, anomenat retrieve. Aquest és un mètode de lectura, que bàsicament retorna el valor d’una variable definida al nostre contracte. Per cridar-lo, només cap que executis la següent ordre a la consola del navegador.
simpleStorage.methods.get().call().then(console.log)
A continuació farem la crida de l’altre mètode, anomenat store. Aquest és un mètode d’escriptura, i, per tant, modifica l’estat de la blockchain.
Per executar aquest mètode necessitem passar un paràmetre amb el valor del número que volem donar a la variable del nostre smart contract, i també l’adreça des d’on volem fer la crida.
A més, al ser un mètode que modifica l’estat de la blockchain, implica que haurem de fer una confirmació des de Metamask, i que consumirem gas de la direcció des d’on fem la crida.
simpleStorage.methods.set(SET_YOUR_NEW_NUMBER_HERE).send({from: web3.givenProvider.selectedAddress})
Un cop la transacció s’hagi efectuat correctament, podem tornar a fer una crida del mètode retrieve, per veure que realment la variable s’ha actualitzat amb el nou valor que hem donat:
simpleStorage.methods.get().call().then(console.log)
Conclusions
Web3.js és una depèndencia Javascrit que ens permet interactuar de forma ràpida amb un node d’Ethereum, permetent-nos escriure a l’estat de la Blockchain a través d’Smart Contracts desplegats a la xarxa, així com sol·licitar valors d’estat.
Una manera habitual d’integrar una aplicació de navegador web amb Ethereum és utilitzar l’extensió del navegador Metamask en combinació amb Web3.js. Metamask és una cartera Ethereum dins del navegador que injecta un objecte de proveïdor Web3 al navegador. Un proveïdor Web3 és una estructura de dades que proporciona un enllaç a nodes d’Ethereum accessibles públicament.
L’ús de Metamask en combinació amb Web3.js, en una interfície web, proporciona una manera còmoda d’interactuar amb la xarxa Ethereum i crear aplicacions descentralitzades (dapps).