Custom Error en Solidity
Custom Error
Siguiendo el anterior tutorial, en el que desarrollamos un contrato inteligente para poder almacenar nuestro número favorito, en ésta ocasión vamos a ver un nuevo concepto: Custom Error ó Error Personalizado.
Podemos lanzar un error cuando una condición determinada de nuestro código se cumpla. Ésto provocará que todos los cambios que se hayan hecho durante la transacción en el estado del contrato se revertirán. En Solidity hay 3 palabras reservadas para éste propósito:
- require
- assert
- revert
Tecnologías
El stack de versiones que se usarán para el desarrollo del proyecto es el siguiente.
- Node (16.18.1)
- Npm (9.2.0)
- Typescript (4.8.4)
Objetivo
Vamos a modificar nuestro Smart Contract para que no deje introducir números mayores a 100. Y lanzar un custom error cuando sea mayor.
Modificación FavoriteNumber
Al inicio del archivo, entre la versión del compilador Solidity y la declaración del contrato, crearemos el nuevo error personalizado. Siguiendo las buenas prácticas en el naming sería algo como NombreContrato__NombreError.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
error FavoriteNumber__NumberMustBeLower(uint favoriteNumber);
contract FavoriteNumber {
...
}
Después vamos a crear la condición que se deberá cumplir para lanzar el error y revertir la transacción. Y la incluiremos en la función setFavoriteNumber.
...
contract FavoriteNumber {
...
function setFavoriteNumber(uint favoriteNumber) external {
if (favoriteNumber > 100) {
revert FavoriteNumber__NumberMustBeLower(favoriteNumber);
}
s_favoriteNumber = favoriteNumber;
}
...
}
Quedando el contrato de la siguiente manera.
FavoriteNumber.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
error FavoriteNumber__NumberMustBeLower(uint favoriteNumber);
contract FavoriteNumber {
uint private s_favoriteNumber;
constructor() { }
function setFavoriteNumber(uint favoriteNumber) external {
if (favoriteNumber > 100) {
revert FavoriteNumber__NumberMustBeLower(favoriteNumber);
}
s_favoriteNumber = favoriteNumber;
}
function getFavoriteNumber() public view returns (uint) {
return s_favoriteNumber;
}
}
Test
Por último, nos queda actualizar los tests para incluir la nueva casuística. Al final de los tests del archivo FavoriteNumber.test.ts escribimos uno sencillo para validar la nueva funcionalidad del contrato.
it('Can not set invalid favorite number', async () => {
// Invalid favorite number
const invalidFavoriteNumber = '101';
// Tries to update favorite number
const transaction = favoriteNumberContract.setFavoriteNumber(invalidFavoriteNumber);
await expect(transaction).to.be.revertedWithCustomError(favoriteNumberContract, 'FavoriteNumber__NumberMustBeLower');
});
Perfecto. Ahora ejecutamos los tests.
npx hardhat test
> FavoriteNumber Unit Tests
> √ Initial favorite number by default
> √ Set favorite number
> √ Can not set invalid favorite number
> 3 passing (1s)
¡Eso es todo! 🥳 Acabas de implementar un custom error en tu contrato para que no deje añadir números favoritos mayores a 100.
Github
Todo el código fuente lo puedes encontrar aquí.
Analyst Frontend Developer en Comunytek (BBVA CIB – NOVA).
Autodidacta, apasionado de las nuevas tecnologías y de los proyectos DIY.
Trackbacks/Pingbacks