solidity dapp ERC-165

ERC-165这个标准用于发布和检测智能合约实现了哪些接口。

当我们需要和一个合约进行交互时,可能并不清楚他是否实现了某些合约例如"ERC20\ERC721"等。所以可以先通过Erc165进行查询(该合约必须实现ERC165),就可以避免很多交互的问题。

ERC165 标准

 ERC165 标准,就是一个接口,里面就一个方法——supportsInterface;用户可以通过调用此方法,输入相应查询的接口ID,查询该合约是否实现了对应的接口ID;

interface IERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

ERC165接口ID 为 0x01ffc9a7;

接口ID是如何计算出来的呢?

        接口是由以太坊ABI定义的一组函数选择器。函数选择器,就是函数签名(如:"myMethod(uint256,string)")的 Keccak(SHA-3)哈希的前 4 字节。有两种方式生成:

  1.  bytes4(keccak256('supportsInterface(bytes4)'));
  2. supportsInterface(bytes4).selector

        接口ID(interface identifier)定义为接口中所有函数选择器的异或(XOR),下例中,通过calculateSelector函数计算Animal的接口ID。

interface Animal {

    function run() external pure;

    function eat(int) external pure;

}



contract Selector {

    function calculateSelector() public pure returns (bytes4) {

        Animal  a;

        return a.run.selector ^ a.eat.selector;

    }

}

具体如何如何应用呢?

        我们继续使用Animal这个例子,我们分别实现了Dog和Cat两个合约,都实现了Animal和IERC165接口;方式略有不同,

        Dog使用supportsInterface的pure(纯函数)实现。 最坏情况下的执行成本是236 gas,但gas随着支持的接口数量增加而线性增加。

        Cat这种方法使用supportsInterface的view (视图函数)实现。 任何输入的执行成本都是586 gas。 但合约初始化需要存储每个接口(SSTORE是20,000 gas)。 ERC165MappingImplementation合约是通用的,可重用的。

interface IERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

interface Animal {
    function run() external;
    function eat() external ;

}

contract Dog is IERC165,Animal {
    function supportsInterface(bytes4 interfaceID) external view returns (bool){
        Return interfaceID == 0x01ffc9a7 ||  interfaceID ==  (this.run.selector ^     this.eat.selector)
}
    function eat() external {}
    function run() external {}

}

//========================================================

contract ERC165MappingImplementation is IERC165 {

    mapping(bytes4 => bool) internal supportedInterfaces;
    function ERC165MappingImplementation() internal {
        supportedInterfaces[this.supportsInterface.selector] = true;
    }

    function supportsInterface(bytes4 interfaceID) external view returns (bool) {
        return supportedInterfaces[interfaceID];
    }
}

contract Cat is ERC165MappingImplementation, Animal{
    function Cat() public {
        supportedInterfaces[this.eat.selector ^ this.run.selector] = true;
    }

    function eat() external {}
    function run() external {}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0xweb3q

有钱的捧个钱场,没钱的捧个人场

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值