¿Cómo desarrollar smart contracts con Hardhat?

Hardhat es un entorno de desarrollo para smart contracts compatibles con la máquina virtual de Ethereum (EVM).

Integra las herramientas necesarias para gestionar el ciclo de vida completo de los smart contracts: codificación, compilación, depuración y despliegue en la blockchain.

La utilización de Hardhat gira en torno al componente Hardhat Runner, encargado de ejecutar tareas y permitir la integración de plugins. Mediante los plugins es posible ampliar las funciones básicas de Hardhat.

Los contratos se programan de forma nativa en Solidity si bien existe un plugin para poder utilizar Vyper.

Existen otras alternativas a Hardhat que igualmente permiten desarrollar smart contracts, entre las que se destacan:

  • Truffle: es el entorno de desarrollo primigenio en Ethereum con una amplia base de desarrolladores, ligado casi de forma indisoluble a Ganache como implementación local de la red Ethereum. Sin entrar en comparaciones, su mayor desventaja actualmente es que desde finales de 2023 ha dejado de estar mantenido por la comunidad quedando catalogado como proyecto obsoleto. Como alternativa para aquellos desarrolladores habituados a Truffle se cita Hardhat al compartir ambos en gran medida la misma filosofía de desarrollo.
  • Foundry: entorno de desarrollo más moderno que Hardhat. Enfocado a utilizar Solidity como lenguaje nativo para programar los test, ofrece mejoras de rendimiento en proyectos que requieren baterías intensivas de pruebas aunque en general
    a costa de una mayor complicación. Su base de desarrolladores es menos extensa que la de Hardhat, por lo que en ocasiones es más complicado encontrar soporte de la comunidad.

Los detalles completos acerca del uso de Hardhat y su conjunto de herramientas se pueden consultar en la página oficial del proyecto Hardhat.

Instalación de Hardhat y desplieque de un nodo de red

El primer paso para comenzar a utilizar Hardhat es instalar los paquetes básicos e inicializar el proyecto. Se permite escoger entre javascript o typescript como lenguaje para programar los test y las scripts de nuestro proyecto:

yarn add --dev hardhat

yarn hardhat init

Al invocar cualquier tarea se crea una instancia en memoria del componente Hardhat Network, un nodo local de Ethereum efímero, ligado a la duración de la tarea, que acepta peticiones JSON-RPC y websocket. Por defecto se crean 20 direcciones de Ethereum con 10000 ETH cada una para permitir las interacciones. El nodo está configurado para minar cada transacción en un bloque nuevo sin ninguna demora.

Otra posibilidad consiste en ejecutar la Hardhat Network como un proceso independiente de larga duración para permitir la conexión de DApps y wallets externos:

yarn hardhat node

El nodo queda expuesto en las siguientes URLs:

  • http://127.0.0.1:8545
  • ws://127.0.0.1:8545

Para ejecutar las tareas de Hardhat en ese nodo hay que indicarlo explícitamente mediente el modificador –network localhost.

Configuración de Hardhat

Durante el proceso de incialización del proyecto Hardhat se habrá creado un fichero de configuración, «hardhat.config.js» si hemos escogido javascript como lenguaje.

Lo habitual será contar con un fichero limpio sobre el que ir añadiendo nuestras configuraciones particulares.

La recomendación general es instalar el plugin «hardhat-toolbox» (junto con sus dependencias si se usa como gestor de paquetes yarn o una versión antigua de npm) para integrar las funciones básicas de Hardhat utilizando la librería «ethers.js» y añadirlo como dependencia en el fichero «hardhat.config.js»:

yarn add --dev  @nomicfoundation/hardhat-toolbox
                @nomicfoundation/hardhat-ignition-ethers
                @nomicfoundation/hardhat-ignition
                @nomicfoundation/ignition-core
                @nomicfoundation/hardhat-network-helpers
                @nomicfoundation/hardhat-chai-matchers
                @nomicfoundation/hardhat-ethers
                @nomicfoundation/hardhat-verify
                ethers @nomiclabs/hardhat-etherscan
                chai@4.4.1 hardhat-gas-reporter solidity-coverage
                @typechain/hardhat typechain @typechain/ethers-v6
                @types/mocha ts-node typescript

De esta manera un fichero básico de configuración podría ser el siguiente:

require("@nomicfoundation/hardhat-toolbox");

module.exports = {    
    solidity: {
      version: "0.8.23"
    },       
    paths: {
      sources: "./contracts",
      tests: "./test",
      cache: "./cache",
      artifacts: "./artifacts"
    }
}

Todas las dependencias cargadas en el fichero de configuración son inyectadas de forma automática en el Hardhat Runtime Environment, un objeto que contiene toda la funcionalidad que Hardhat expone el ejecutar una tarea, un test o una script. De este modo se simplifica mucho la programación de tests y scripts al contar de forma implícita con muchas de las utilidades necesarias.

En el ejemplo se han definido de forma explícita las rutas por defecto usadas por Hardhat para ubicar los distintos tipos de ficheros asociados a los smart contracts.

Para más detalles sobre el fichero «hardhat.config.js» se puede consultar referencia de configuración de Hardhat.

¿Cómo compilar smart contracts con Hardhat?

Es muy recomendable definir de forma explícita en el fichero «hardhat.config.js» la versión del compilador «solc» a utilizar para garantizar el resultado de la compilación.

Opcionalmente se pueden definir otros parámetros de compilación en Hardhat propios del compilador «solc» dentro del apartado «settings». Serían los detallados en el fichero JSON de descripción de la entrada del compilador.

Si bien para el despliegue de los contratos es en general necesario recurrir a optimizaciones del compilador, se recomienda deshabilitarlas para permitir el registro completo de la pila durante la ejecución de los tests para depurar los contratos.

Los smart contracts se habrán programado previamente usando nuestro editor de preferencia dentro de la carpeta definida para las «sources» en el fichero «hardhat.config.js» (directorio «contracts» por defecto).

Las tareas básicas de compilación son:

  • yarn hardhat compile: compila únicamente los ficheros fuente que hayan cambiado desde la última compilación y ubica los resultados en la carpeta definida para los «artifacts» en el fichero «hardhat.config.js» (directorio «artifacts» por defecto).
  • yarn hardhat compile –force: fuerza la recompilación de los archivos aunque no hayan cambiado desde la última compilación.
  • yarn hardhat clean: borra la cache y los resultados de la compilación anterior.

Siguientes pasos: programación de tests

Hardhat es un entorno integrado de desarrollo para smart contracts. Se presenta como una alternativa respecto de otras opciones como podrían ser Truffle o Foundry.

En este artículo se han cubierto los primeros pasos para desarrollar smart contracts con Hardhat: la instalación del entorno, la configuración básica y la compilación de los contratos.

En próximos artículos se abordarán otros ciclos del proceso como son la programación de test para los contratos.


¿Cuál es tu herramienta preferida para programar smart contracts? Te animo a que compartas tus experiencias enviando comentarios. Si tienes que desarrollar smart contracts, contáctame: puedo ocuparme de la gestión completa de su ciclo de vida. ¡Muchas gracias!