Instalación de HardHat en Ubuntu 20.04

Una de las primera cosas que debemos hacer en el desarrollo de contratos inteligentes y aplicaciones descentralizadas es la instalación de las herramientas de desarrollo. En esta entrada veremos cómo realizar la instalación de las herramientas.

Requisitos Previos

Veamos ahora los requisitos que necesitamos de base para la instalación:

Si no tienes este entorno instalado y quieres hacer uso de diferentes versiones de NodeJS en local te recomendamos encarecidamente que instales:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

Para luego instalar la versión de Node que nosotros queramos, por ejemplo:

nvm use 16

Creación del directorio del proyecto

Como siempre necesitaremos crear una carpeta para el proyecto por ejemplo con el comando:

mkdir miproyecto

Después nos meteremos en él

cd miproyecto

Y crearemos la estructura básica de NPM con:

npm init

Instalación de Hardhat

Hardhat es uno de los principales entornos de desarrollo que tenemos para solidity y la EVM. que básicamente es un gestor de tareas y plugins para el desarrollo de contratos inteligentes. Veamos cómo instalarlo.

Con el fichero package.json ya creado ya podemos empezar a introducir las dependencias del proyecto empezando por Hardhat:

npm install --save-dev hardhat

Esto instalará todas las dependencias y nos las colocará como siempre en la carpeta node_modules.

Si quisiéramos disponer del comando hardhat a nivel de sistema lo podríamos instalar de manera global:

npm i -g hardhat

Ya va siendo hora de que empecemos a versionar este proyecto con git:

git init

Estaría bien que creáramos un .gitignore para evitar subir al repositorio git remoto todo lo no necesario.

.idea
package-lock.json

En mi caso la carpeta de configuración de Jetbrains, y el package-lock.json

Añadiremos los ficheros a Git:

git add package.json .gitignore

Y haremos nuestro primer commit:

git commit -m 'primer commit'

Creación del proyecto

Ya va siendo hora de crear el proyecto para ello usaremos del comando global:

hardhat

O si hemos hecho la instalación en local con:

npx hardhat

Esto nos sacará la selección de creación del proyecto:

selección de tipo de proyecto

Como queremos empezar de manera suave seleccionaremos “Create a basic sample project” y vamos dejando las opciones por defecto:

Opciones por defecto en la creación de proyecto

Aunque lo suyo es tuviéramos soporte de Typescript, pero eso lo dejaremos para más adelante.

Estructura del proyecto Hardhat

Cuando termine de ejecutar el generador de proyecto nos dejará una estructura base para el proyecto:

Estructura básica del proyecto

Vemos un poco por encima la estructura:

  • miproyecto:
    • contracts -> lugar para los contratos inteligentes
      • Greeter.sol -> ejemplo de contrato inteligente
    • scripts -> scripts de despliegue normalmente
      • sample-script.js -> ejemplo de despliegue
    • test -> carpeta para las pruebas
      • sample-test.js -> ejemplo de prueba
    • .gitignore
    • hardhat.config.js -> fichero de configuración para hardhat
    • package.json
    • package-lock.json
    • README.md

Cabe destacar las dependencias de desarrollo que nos han colocado en el package.json:

"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.2",

En estos casos usamos lo siguiente:

  • chaiJS: lanzamiento de pruebas
  • waffle: para las pruebas de contratos inteligentes
  • ethersJS: para la conexión a la cadena de bloques y contratos inteligentes
  • hardhat-ethers y hardhat-waffle que son los plugins de conexión con estas dos bibliotecas

Si estuviéramos usando la versión avanzada de Typescript deberíamos añadir la siguiente estructura:

  • scripts
    • deploy.ts -> fichero de despliegue Typescript
  • test
    • index.ts -> fichero de pruebas Typescript
  • .env.example -> fichero de definición del entorno
  • .eslintignore -> fichero de exclusiones de eslint
  • .eslintrc.js -> fichero de configuración de eslint
  • .npmignore -> fichero de exclusiones de npm
  • .prettierignore -> fichero de exclusiones de prettier
  • .prettierrc -> fichero de configuración de prettier
  • .solhintignore -> fichero de exclusión de solhint
  • .solhint.json -> fichero de configuración de solhint
  • tsconfig.json -> fichero de configuración de Typescript

Por supuesto la lista de dependencias crece bastante:

"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-etherscan": "^3.0.3",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@typechain/ethers-v5": "^7.2.0",
"@typechain/hardhat": "^2.3.1",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.1.0",
"@types/node": "^12.20.47",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"chai": "^4.3.6",
"dotenv": "^10.0.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.1",
"eslint-plugin-promise": "^5.2.0",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.2",
"hardhat": "^2.9.2",
"hardhat-gas-reporter": "^1.0.8",
"prettier": "^2.6.1",
"prettier-plugin-solidity": "^1.0.0-beta.13",
"solhint": "^3.3.7",
"solidity-coverage": "^0.7.20",
"ts-node": "^10.7.0",
"typechain": "^5.2.0",
"typescript": "^4.6.3"

Comandos de Hardhat

A partir de este momento ya deberíamos ser capaces de usar los comandos de hardhat sobre nuestro proyecto.

Compilación

empezando por la compilación de los contratos desde la instalación local:

npx hardhat compile

Si todo ha ido bien debería poder compilar los contratos inteligentes, en este caso del Greeter.sol que viene de ejemplo:

Downloading compiler 0.8.4
Compiled 2 Solidity files successfully

Lanzamiento de Pruebas

Las pruebas son cruciales en los contratos inteligentes porque una vez desplegados en producción ya no hay marcha atrás, lo desplegado desplegado queda para siempre en la cadena de bloques. Y salvo que tengamos técnicas de actualización de contratos inteligentes no se va a poder modificar su comportamiento.

Por lo que para lanzar la prueba diseñada dentro de la carpeta test en el fichero sample-test.js o index.ts en el caso de haber activado Typescript debemos ejecutar este comando:

npx hardhat test

Con lo que tendremos uns salida similar a la siguiente:

  Greeter
Deploying a Greeter with greeting: Hello, world!
Changing greeting from 'Hello, world!' to 'Hola, mundo!'
    ✔ Should return the new greeting once it's changed (493ms)


  1 passing (497ms)

Despliegue de contratos inteligentes

En el caso de realizar un despliegue en una blockchain local, waffle en nuestro caso usaremos:

npx hardhat run scripts/sample-script.js

o en el caso de usar Typescript:

npx hardhat run scripts/deploy.ts

Obtendremos una salida similar a la siguiente:

Deploying a Greeter with greeting: Hello, Hardhat!
Greeter deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3

Donde nos dará la dirección de despliegue del contrato inteligente en local.

Conexión desde Metamask u otra wallet de navegador

Si queremos enganchar nuestra metamask a un nodo local arrancado con waffle deberemos ejecutar:

npx hardhat node

Con esto nos ofrecerá un servidor local al que conectarnos a la URL http://127.0.0.1:8545/ por HTTP y Websocket JSON-RPC. Nos mostrará las direcciones generadas por waffle, unas 20 en total, cada una de ellas con 10000 ETH de mentira para probar.

Es importante recordar que estas direcciones no deberíamos usarlas JAMÁS para realizar ningún despliegue en pruebas (redes de testing de las blockchains) o en producción (en las blockchains de verdad).

Para añadir la red de pruebas en local a Metamask iremos a Configuración -> Redes-> Agregar Red Y rellenaremos la nueva red:

  • Network Name: Localhost 8545
  • New RPC URL: http://loclahost:8545/
  • Chain ID: 31337
  • Currency Symbol: ETH
  • Block Explorer URL: vacio (es decir, no pones nada)

Una vez seleccionada la red deberíamos importar una dirección desde el nodo. Como vimos antes nos permitía ver las 20 direcciones y sus claves privadas. La clave privada es lo que usaremos para importar la dirección desde Metamask desde Importar Cuenta.

Teniendo seleccionado la clave privada copiamos la clave privada de una de las direcciones por ejemplo la cuenta 0 y la pegamos en el campo “Pegue aquí la cadena de la clave privada” y pulsa el botón “Importar”.

Si hemos hecho correctamente la importación deberíamos ver el saldo inicial de la cuenta que acabamos de importar si tenemos seleccionada la red correcta y la cuenta importada.

Captura de metamask enganchado a waffle y a nuestra cuenta de prueba

Notas finales

Conviene recordar también que para nuestra conveniencia y no mezclar las cuentas lo suyo sería disponer de un navegador con Metamask instalado diferente al que usemos habitualmente para nuestras cuentas de verdad.

Por ejemplo podrías usar Brave, Firefox, Chromium o Vivaldi para el desarrollo y dejar Chrome para producción.

Repositorios de ejemplo

  • Repositorio Javascript Básico: https://github.com/pepesan/ejemplo_hardhat_js
  • Repositorio Typescript “Complejo”: https://github.com/pepesan/ejemplo_hardhat_typescript

Comments

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. ACEPTAR

Aviso de cookies