EIP-165 标准接口检测

意义:

这个提案创建一个标准方法以发布和检测智能合约实现了哪些接口。
检测合约是否实现了ERC-165.
同时supportsInterface用于帮助其他合约检测本合约实现了哪些接口。
一般是公司内部使用,方便合作办公。

接口ID(interface identifier)定义为接口中所有函数选择器的异或(XOR)。

如何检测合约是否实现了 ERC-165

1.在合约地址上使用附加数据(input data)
0x “01ffc9a7” ”01ffc9a7“ 0000000000000000000000000000000000000000
0000000000000000(前4函数选择器 后4位是interfaceID interfaceID由各函数的selector的结果异或算得)和 gas 30,000 进行STATICCALL调用,相当于contract.supportsInterface(0x01ffc9a7)。

2.如果调用失败或返回false , 说明合约不兼容ERC-165标准

3.如果返回true,则使用输入数据0x“01ffc9a7”“ffffffff” 000000000000000000000000000000000000000000000000000000000000进行第二次调用。

4.如果第二次调用失败或返回true,则目标合约不会实现ERC-165(不允许合约内出现接口id为0xffffffff的接口)。

5.若无0xffffffff,则它实现了ERC-165。

如何检测合约是否实现了某个接口

1.如果不确定合约是否实现ERC-165,请使用上面的方法进行确认。
2.如果没有实现ERC-165,那么你将不得不看看它采用哪种老式方法。
3.如果实现了ERC-165,那么只需调用 supportsInterface(interfaceID) 来确定它是否实现了对应的接口。

如果我要检测某个合约是否实现了ERC20标准

应用场景:
一个项目实现了ERC165接口,并可以通过该接口查询该项目实现了哪些其他的接口,可以供其他人查询。(前提是这个合约需要配合,一般建立在小组/公司内部开发中)

pragma solidity ^0.8.0;

contract ERC165 {
    
    
    bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
    mapping(bytes4 => bool) private _supportedInterfaces;
    constructor()  {
    
    
        _registerInterface(_InterfaceId_ERC165); // 本合约实现了ERC165
    }
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
    
    
        return _supportedInterfaces[interfaceId];
    }
    function _registerInterface(bytes4 interfaceId) internal {
    
    
        require(interfaceId != 0xffffffff, "Can't register 0xffffffff");
        _supportedInterfaces[interfaceId] = true;
    }
}

contract Example is ERC165 {
    
     
    // 继承了上文的函数,但是没有继承他们的数据 
    // 因此这个合约中可以使用supportInterface()
    bytes4 public interfaceImplemented = 0x11111111; //若本项目/合约实现了某接口,且id0x11111111,则可以直接设置为true
    constructor() public {
    
    
        _registerInterface(interfaceImplemented);
    }
}

旧版本是输入32个字节的数据参数,但是在solidity5中解析时将会损坏,因为需要4位字节签名。故新版本位4字节签名+32字节参数。

资料来源:https://eips.ethereum.org/EIPS/eip-165

猜你喜欢

转载自blog.csdn.net/weixin_43380357/article/details/129696963