Introducción
En el ecosistema de desarrollo blockchain, Hardhat se ha consolidado como una de las herramientas más versátiles para la compilación, despliegue y prueba de contratos inteligentes sobre Ethereum. Integrarlo con un backend en Node.js permite crear aplicaciones descentralizadas (dApps) completas, donde la lógica off-chain y la interacción con la blockchain convergen de manera fluida.
Este artículo detalla, paso a paso, cómo configurar un proyecto backend en Node.js junto con Hardhat para desarrollar, testear y desplegar tus contratos inteligentes, siguiendo buenas prácticas y haciendo uso de Ethers.js como librería principal.
1. Pre-requisitos
- Node.js v14 instalado. Descarga en nodejs.org.
- npm o yarn como gestor de paquetes.
- Conocimientos básicos de Solidity y JavaScript.
- Cuenta en Infura o Alchemy para acceder a nodos de Ethereum (opcional para testnets/mainnet).
2. Instalación y configuración del proyecto
2.1 Inicializar el proyecto Node.js
En una carpeta vacía, ejecuta:
npm init -y
Esto crea un package.json con la configuración básica.
2.2 Instalar Hardhat y dependencias
Agrega Hardhat y Ethers.js al proyecto:
npm install --save-dev hardhatnpm install ethers @nomiclabs/hardhat-ethers dotenv express cors
También incluimos dotenv para variables de entorno y Express junto con CORS para el servidor.
2.3 Crear el entorno de Hardhat
Genera la configuración por defecto:
npx hardhat
Elige “Create a basic sample project” y confirma la instalación de dependencias sugeridas.
2.4 Configurar hardhat.config.js
require(dotenv).config()
require(@nomiclabs/hardhat-ethers)
module.exports = {
solidity: 0.8.17,
networks: {
hardhat: {},
ropsten: {
url: process.env.ROPSTEN_URL,
accounts: process.env.PRIVATE_KEY [process.env.PRIVATE_KEY] : []
}
}
}
Define en un fichero .env tus variables:
| Variable | Descripción |
|---|---|
| ROPSTEN_URL | Endpoint de nodo (Infura/Alchemy). |
| PRIVATE_KEY | Clave privada de la cuenta desplegadora. |
3. Desarrollo de contratos inteligentes
3.1 Crear un contrato de ejemplo
En contracts/Greeter.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17
contract Greeter {
string private greeting
constructor(string memory _greeting) {
greeting = _greeting
}
function greet() public view returns (string memory) {
return greeting
}
function setGreeting(string memory _greeting) public {
greeting = _greeting
}
}
3.2 Compilar
Ejecuta:
npx hardhat compile
3.3 Pruebas unitarias
En test/greeter-test.js:
const { expect } = require(chai)
describe(Greeter, function () {
it(should return the initial greeting, async function () {
const Greeter = await ethers.getContractFactory(Greeter)
const greeter = await Greeter.deploy(Hola Mundo)
await greeter.deployed()
expect(await greeter.greet()).to.equal(Hola Mundo)
})
})
Lanza las pruebas con npx hardhat test.
4. Configuración del backend en Node.js
4.1 Estructura de carpetas
- contracts/ – Contratos Solidity.
- scripts/ – Despliegue de contratos con Hardhat.
- test/ – Pruebas de contratos.
- server/ – Código del backend Express.
4.2 Conexión a la blockchain con Ethers.js
En server/ethers.js:
require(dotenv).config()
const { ethers } = require(ethers)
const provider = new ethers.providers.JsonRpcProvider(process.env.ROPSTEN_URL)
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider)
// Exporta el proveedor y la wallet
module.exports = { provider, wallet }
4.3 Servidor Express y endpoints
En server/index.js:
const express = require(express)
const cors = require(cors)
const { wallet } = require(./ethers)
const GreeterArtifact = require(../artifacts/contracts/Greeter.sol/Greeter.json)
const app = express()
app.use(cors())
app.use(express.json())
const greeterAddress = DIRECCION_DEL_CONTRATO
app.get(/greet, async (req, res) => {
const contract = new ethers.Contract(greeterAddress, GreeterArtifact.abi, wallet)
const greeting = await contract.greet()
res.json({ greeting })
})
app.post(/greet, async (req, res) => {
const { message } = req.body
const contract = new ethers.Contract(greeterAddress, GreeterArtifact.abi, wallet)
const tx = await contract.setGreeting(message)
await tx.wait()
res.json({ txHash: tx.hash })
})
app.listen(3000, () => console.log(Servidor iniciado en puerto 3000))
5. Despliegue en testnet
- Configura scripts/deploy.js con tu contrato:
async function main() {
const Greeter = await ethers.getContractFactory(Greeter)
const greeter = await Greeter.deploy(Hola Testnet)
await greeter.deployed()
console.log(Greeter desplegado en:, greeter.address)
}
main().catch(console.error)
- Ejecuta:
npx hardhat run --network ropsten scripts/deploy.js. - Actualiza greeterAddress en tu backend con la dirección resultante.
6. Buenas prácticas y consejos
- Seguridad: Nunca subas tus claves privadas en repositorios. Usa gestores de secretos.
- Versionado: Bloquea las versiones de Solidity y dependencias.
- Pruebas: Escribe casos extremos y prueba revert en fallos esperados.
- Monitoreo: Integra herramientas como hardhat-gas-reporter.
- Documentación: Mantén los scripts y variables bien documentadas en README.md.
Conclusión
Combinar Node.js y Hardhat ofrece una solución integral para el desarrollo de dApps robustas. Con esta configuración, cubres desde el diseño de contratos inteligentes hasta la exposición de APIs REST, facilitando la interacción off-chain. Aprovecha la flexibilidad de Hardhat, la potencia de Ethers.js y la simplicidad de Express para construir aplicaciones blockchain de alta calidad.
Para más detalles y actualizaciones, consulta la documentación oficial de Hardhat y Ethers.js.
Deja una respuesta