Fabio Arpires
Andrés Muñoz
Sebastian Perez
ProfesorJosé Manuel Piña Rodríguez
José Manuel Piña Rodríguez
Pepe Sosa
Javier Flores
Rafael Livise Larico
Mateo Santiago Zapata Maldonado
Oscar Riojas
Kevin Fiorentino
Rafael Livise Larico
Comparto mi solución:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; contract IdentificadorToken { using ERC165Checker for address; modifier onlyERC20(address _direccion) { require(_direccion.supportsInterface(type(IERC20).interfaceId),"La Direccion no es compatible, no es un token ERC20"); _; } modifier onlyERC721 (address _direccion){ require(_direccion.supportsInterface(type(IERC721).interfaceId),"La Direccion no es compatible, no es un token ERC721"); _; } function verificarERC20(address _direccion) onlyERC20(_direccion) public view returns(string memory) { return "La Direccion es compatible, es un token ERC20"; } function verificarERC721(address _direccion) onlyERC721(_direccion) public view returns(string memory) { return "La Direccion es compatible, es un token ERC721"; } }
using ERC165Checker for address, quiere decir que ahora el tipo address ya no va a ser él que viene por defecto, sino uno extendido que tiene más métodos ? Aún no tengo claro como funciona el using ...
Exacto, estás extendiendo el comportamiento del address, por lo tanto cuando uses este podrás llamar a las funciones que agrega la librería.
Reto, otra solucion:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; contract introspectionReto3 { function whatTypeOfTokenIsIt (address account) public view returns(string memory) { if(ERC165Checker.supportsInterface(account, type(IERC20).interfaceId)){ return "It's ERC-20 Token"; } else if (ERC165Checker.supportsInterface(account, type(IERC721).interfaceId)){ return "It's ERC-721 token"; } else { return "It's none"; } } }
Mi solución al desafio:
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; contract Verification { using ERC165Checker for address; bytes4 private InterfaceId_ERC721 = 0x80ac58cd; bytes4 private InterfaceId_ERC20 = 0x36372b07; function tryERC721( address token ) public view returns(bool) { return token.supportsInterface(InterfaceId_ERC721); } function tryERC20( address token ) public view returns(bool) { return token.supportsInterface(InterfaceId_ERC20); } }
Tengo una solución muy similar a la tuya y siempre da false, copié tu solución y lo mismo, siempre me da false, con el fungible ERC20 ¿Te pasa lo mismo?
Saludos!
hola, interesante solucion. te consulto, de donde salen los valores hexa de las interfaces?? saludos
Luego de ver la solucion entendi mejor el uso de using en librerias.
// 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/ERC165Checker.sol"; contract IdentificadorToken { using ERC165Checker for address; error InvalidTokenFormat (string message); function isERC20 (address _address) public view returns (string memory) { if (!_address.supportsInterface(type(IERC20).interfaceId)) { revert InvalidTokenFormat("El formato del token no es valido, no hace referencia a un estandar ERC20"); } return "Este contrato si cumple con los requisitos de ERC20"; } function isERC721 (address _address) public view returns (string memory) { if (!_address.supportsInterface(type(IERC721).interfaceId)) { revert InvalidTokenFormat("El formato del token no es valido, no hace referencia a un estandar ERC721"); } return "Este contrato si cumple con los requisitos de ERC721"; } }
Encontré esta parte de interfaces muy apropiado para este caso: https://www.tutorialspoint.com/solidity/solidity_interfaces.htm
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/interfaces/IERC1155.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; interface ITest { function isERC1155(address Address) external returns (bool); function isERC721(address Address) external returns (bool); function isERC20(address Address) external returns (bool); } contract Test is ITest, IERC165 { using ERC165Checker for address; bytes4 public constant IID_ITEST = type(ITest).interfaceId; bytes4 public constant IID_IERC165 = type(IERC165).interfaceId; bytes4 public constant IID_IERC20 = type(IERC20).interfaceId; bytes4 public constant IID_IERC1155 = type(IERC1155).interfaceId; bytes4 public constant IID_IERC721 = type(IERC721).interfaceId; function isERC1155(address Address) external view returns (bool) { return Address.supportsInterface(IID_IERC1155); } function isERC721(address Address) external view returns (bool) { return Address.supportsInterface(IID_IERC721); } function isERC20(address Address) external view returns (bool) { return Address.supportsInterface(IID_IERC20); } function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == IID_ITEST || interfaceId == IID_IERC165; } }
Tuve algún conflicto con mi contrato ERC20 realizado en clases anteriores que hereda AccessControl.
Por lo que estuve investigando, hay que tener algún reparo cuando un contrato hereda más de 2 interfaces. El orden es importante. Además, REMIX me daba algunos errores y también tuve que hacer el override de AccessControl en la función supportsInterface de la siguiente manera:
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, AccessControl) returns (bool) { // .. }
Comparto el código del Token ERC20 y el código del ERC165 que desarrollé. Funciona!
Reto:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC721.sol"; contract obervador { function isTokenERC20(address account) public view returns (bool) { return ERC165Checker.supportsInterface(account, type(IERC20).interfaceId); } function isTokenERC721(address account) public view returns (bool) { return ERC165Checker.supportsInterface(account, type(IERC721).interfaceId); } }