solidity ERC165 supportsInterface function

Openzeppelin


ERC165

Through the ERC165 standard, a smart contract can declare the ERC standard interface it supports for other contracts to check. The IERC165 interface contract only declares a supportsInterface function, enter the interfaceId interface id to be queried, and return true if the contract implements the interface id:

interface IERC165 {
    
    
    /**
     * @dev 如果合约实现了查询的`interfaceId`,则返回true
     * 规则详见:https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     *
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

1. How does ERC721 implement the supportsInterface() function

ERC721 inherits the interface of ERC165. When the interface id of IERC721 or IERC165 is queried, it returns true; otherwise, it returns false.

    function supportsInterface(bytes4 interfaceId) external pure override returns (bool)
    {
    
    
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC165).interfaceId;
    }

If the contract also inherits the ERC721Metadata interface, supportsInterface can be rewritten as:

function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
    
    
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}

Two, interfaceId calculation method

The interface of ERC721 is as follows:

/// 注意这个**0x80ac58cd**
///  **⚠⚠⚠ Note: the ERC-165 identifier for this interface is 0x80ac58cd. ⚠⚠⚠**
interface ERC721 /* is ERC165 */ {
    
    
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    function balanceOf(address _owner) external view returns (uint256);

    function ownerOf(uint256 _tokenId) external view returns (address);

    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;

    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

    function approve(address _approved, uint256 _tokenId) external payable;

    function setApprovalForAll(address _operator, bool _approved) external;

    function getApproved(uint256 _tokenId) external view returns (address);

    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

The interfaceId calculation method of this interface is:
0x80ac58cd = bytes4(keccak256(ERC721.Transfer.selector) ^keccak256(ERC721.Approval.selector) ^ ··· ^keccak256(ERC721.isApprovedForAll.selector))
where ^ is an XOR operator

Guess you like

Origin blog.csdn.net/hhhhhhhhhjx/article/details/127270133