这两种实体接口方法有什么区别?

What's the difference between these 2 solidity interfaces methods?

我已经开始新的 solidity 之旅大约一个月了,到目前为止一切顺利,但是对于接口,我很难理解这两种实现接口的方法之间的区别。

我可以清楚地注意到接口在第二种方法中有多么有用,但在第一种方法中却没有。

方法一:

pragma solidity ^0.8.0;

interface ICounter {

    function count() external view returns (uint256);
    function addToCount() external;
}

contract myInterface is ICounter {

    uint256 counter = 0;

    function count() external view override returns (uint256) {
        return counter;
    }

    function addToCount() override external {
        counter++ ;
    }
}

方法二:

pragma solidity ^0.8.0;

contract myContract {
    uint256 count =0;

    function increment() external {
    count++ ;
    }
}

pragma solidity ^0.8.0;

interface ICounter {

    function count() external view returns (uint256);
    function increment() external;
}

contract myInterface {

    function incrementCount(address _counter) external {
        ICounter(_counter).increment();
    }

    function getCount(address _counter) external view returns (uint256) {
        return ICounter(_counter).count();
    }
}

Solidity 中的接口主要用于与部署在其他地址上的合约进行交互,如您在方法 2.

中所示

在变量中存储指向另一个合约(假设它实现了接口)的指针的示例:

pragma solidity ^0.8.0;

interface ICounter {
    function increment() external;
}

contract MyContract {
    ICounter counter;

    constructor(address _counter) {
        counter = ICounter(_counter);
    }

    function incrementCount() external {
        counter.increment();
    }
}

方法1中,您的代码使用is关键字进行继承,可以描述为myInterface child 个 ICounter

但是没有办法明确说明接口的实现 - "myInterface 实现了 ICounter"。如您所见,您需要在 addToCount() 函数上使用 override 修饰符来声明您正在 覆盖 parent 函数 - 这根本不建议实现接口。

我不认为方法 2 是一种不好的做法,因为它可以帮助您记住实现所有预期功能 - 否则合约将被视为 abstract 并且无法部署。但就我个人而言,这是不太受欢迎的方法,因为没有办法声明实现而不是继承(至少在当前的 Solidity 版本 0.8 中没有)。

注意:我知道例如 OpenZeppelin uses“从接口继承”的方法 1。我只是不同意他们的做法。:)