Solidity

如果合約需要支持多個介面,如何覆蓋 supportInterface() 函式?

  • January 22, 2022

我正在創建一個擴展 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);
 }
}

函式按以下順序呼叫:

  1. 我的契約
  2. 訪問控制
  3. ERC721
  4. ERC165

至於interfaceId已知合約的s,有時會列在合約的EIP頁面評論某處,直接搜尋即可0xhttps://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

引用自:https://ethereum.stackexchange.com/questions/115519