Solidity get interface id and ERC165

To get interface id, use

type(ITest).interfaceId

Remember interfaceId = xor of all selectors (methods) name and param type, don’t care to return type

For example:

  • Return zero with empty interface
=> bytes4: 0x00000000

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ITest {
}

contract Test is ITest {
    bytes4 public constant IID_ITEST = type(ITest).interfaceId;    
}
  • Return same id with difference return type
=> bytes4: 0x0ee2cb10

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ITest {
    function getCreator() external;
}

contract Test is ITest {
    bytes4 public constant IID_ITEST = type(ITest).interfaceId;   
    
    function getCreator() external override { } 
}

===========
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ITest {
    function getCreator() external returns (uint);
}

contract Test is ITest {
    bytes4 public constant IID_ITEST = type(ITest).interfaceId;   
    
    function getCreator() external pure override returns (uint) {
        return 0;
    }
}
  • Return same id with difference param name
=> bytes4: 0xd48e638a

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITest {
    function getCreator(uint name) external returns (uint);
}
contract Test is ITest {
    bytes4 public constant IID_ITEST = type(ITest).interfaceId;   
    
    function getCreator(uint name) external pure override returns (uint) {
        return name;
    }
}

===========
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITest {
    function getCreator(uint name2) external returns (uint);
}
contract Test is ITest {
    bytes4 public constant IID_ITEST = type(ITest).interfaceId;   
    
    function getCreator(uint name2) external pure override returns (uint) {
        return name2;
    }
}
  • MockERC1155
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract MockERC1155 is ERC1155 {
  constructor() public ERC1155("https://nhancv.com/{id}.json") {
    mint(msg.sender, 0, 1);
  }

  function mint(
    address account,
    uint256 id,
    uint256 amount
  ) public {
    _mint(account, id, amount, "");
  }
}
  • MockERC721
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MockERC721 is ERC721 {
  constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {
    mint(msg.sender, 0);
  }

  function mint(address account, uint256 id) public {
    _mint(account, id);
  }
}
  • Combine with ERC165
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";

interface ITest {
    function isERC1155(address nftAddress) external returns (bool);
    function isERC721(address nftAddress) 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_IERC1155 = type(IERC1155).interfaceId;
    bytes4 public constant IID_IERC721 = type(IERC721).interfaceId;
    
    function isERC1155(address nftAddress) external view override returns (bool) {
        return nftAddress.supportsInterface(IID_IERC1155);
    }    
    
    function isERC721(address nftAddress) external view override returns (bool) {
        return nftAddress.supportsInterface(IID_IERC721);
    }
    
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == IID_ITEST || interfaceId == IID_IERC165;
    }
}

Leave a Reply

Your email address will not be published.Required fields are marked *