Solidity
如果合約需要支持多個介面,如何覆蓋 supportInterface() 函式?
我正在創建一個擴展 ERC721、ERC721Enumerable、AccessControlEnumerable 的基本 ERC721 令牌。我希望它支持 ERC721Enumerable 和 AccessControlEnumerable 介面。在我重寫的 supportsInterface 函式中呼叫 super.supportsInterface(interfaceId) 是否足以實現它?
另外,我想知道是否有知名介面的介面ID 列表,例如IERC20、IERC721?
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable, AccessControlEnumerable) returns (bool) { return super.supportsInterface(interfaceId); }
您的程式碼已經
supportsInterface()
很好地覆蓋了該方法,並將導致呼叫所有擴展合約的方法。OpenZeppelin Contracts Wizard也使用此方法。如果您獲得更多介面,只需將它們添加到
override()
元組中。介面的順序可能很重要,因為它們從最後一個呼叫到第一個。
function supportsInterface(bytes4 interfaceId) public view override(ERC721, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); }
例如,具有這種拓撲結構,
contract MyContract is ERC721, AccessControl { function supportsInterface(bytes4 interfaceId) public view override(ERC721, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } } contract ERC721 is ERC165, IERC721, IERC721Metadata { function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } } abstract contract AccessControl is IAccessControl, ERC165 { function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } }
函式按以下順序呼叫:
- 我的契約
- 訪問控制
- ERC721
- ERC165
至於
interfaceId
已知合約的s,有時會列在合約的EIP頁面評論某處,直接搜尋即可0x
。 https://eips.ethereum.org/EIPS/eip-721另一種獲取介面值的方法是使用 REMIX IDE 並呼叫這樣的函式。
event Log(bytes4 data); function log() public { emit Log(type(IERC721).interfaceId); }
ERC165 0x01ffc9a7 ERC721 0x80ac58cd ERC721Metadata 0x5b5e139f ERC721TokenReceiver 0x150b7a02 ERC721Enumerable 0x780e9d63 AccessControl 0x7965db0b