- Home
- /
- Blog
- /
- OpenZeppelin
OpenZeppelin: Inspeccionar Contratos#
Cuando interactuamos con otro contrato dentro de nuestro propio contrato, a veces es necesario verificar si el contrato ajeno al nuestro posee determinadas caracter铆sticas antes de realizar una acci贸n.
Inspeccionando contratos#
Si necesitamos enviar tokens a otro contrato, pero por precauci贸n queremos verificar antes que dicho contrato pueda manipular esos tokens correctamente y evitar su perdida, podemos hacer una verificaci贸n de ese contrato previamente.
El est谩ndar ERC165, especificado en el EIP165 y denominado Est谩ndar de Detecci贸n de Interfaces, permite verificar si un contrato implementa o no una determinada interfaz antes de interactuar con 茅l. De esta forma, validar si el otro contrato est谩 preparado para recibir tokens o ejecutar determinada acci贸n.
Implementaci贸n del est谩ndar ERC165#
OpenZeppelin implementa una serie de contratos ERC165 para detectar interfaces en otros contratos.
- ERC165.sol: Contrato base para la comprobaci贸n de la interfaz IERC165.
- ERC165Checker.sol: Contrato que permite detectar cualquier otra interfaz que necesitemos.
Nota: Otro est谩ndar interesante para la validaci贸n de interfaces es el ERC1820. El mismo es una extensi贸n de ERC165 que permite la declaraci贸n y validaci贸n de interfaces en direcciones que no necesariamente contengan un contrato.
Si necesitas verificar que un contrato implementa, por ejemplo, la interfaz IERC20, el mismo debe implementar ERC165 para poder realizar esta comprobaci贸n.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
contract VerifyInterfaces {
// Verificamos si el contrato cumple con IERC20
function isERC20(address addr) public view returns (bool) {
return ERC165Checker.supportsInterface(addr, type(IERC20).interfaceId);
}
// Verificamos si el contrato cumple con IERC721
function isERC721(address addr) public view returns (bool) {
return ERC165Checker.supportsInterface(addr, type(IERC721).interfaceId);
}
// Verificamos si el contrato cumple con IERC165
function isERC165(address addr) public view returns (bool) {
return ERC165Checker.supportsInterface(addr, type(IERC165).interfaceId);
}
}
contract MyTokenERC20 is ERC20, ERC165 {
constructor() ERC20("Mi Token ERC20", "MTF") {
_mint(msg.sender, 1000);
}
// Sobreescribimos supportsInterface() para que otro contrato pueda validar la interface IERC20
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) {
return
interfaceId == type(IERC20).interfaceId ||
super.supportsInterface(interfaceId);
}
}
Te animo a que despliegues los contratos anteriores en entornos como Remix y compruebes que el contrato MyTokenERC20 implementa tanto la interfaz IERC20 como IERC165, pero no la interfaz IERC721. Esto puedes corroborarlo gracias a las funciones del contrato VerifyInterfaces que hace las comprobaciones a cada interfaz.
El contrato MyTokenERC20 debe implementar el est谩ndar ERC165 y sobreescribir la funci贸n supportsInterface(bytes4)
para que un contrato externo valide la interfaz IERC20.
Cada contrato inteligente es responsable de implementar ERC165 para permitir la verificaci贸n de una interfaz.
Corroborar la implementaci贸n de una interfaz entre contratos te ahorrar谩 m谩s de un dolor de cabeza cuando tengas que comunicar contratos y evitar problemas cuando el contrato ajeno al nuestro no implementa determinadas funcionalidades que esperamos.
Post creado en colaboraci贸n con el Curso de OpenZeppelin de Platzi.