Solidity合约中的interface如何使用

1,058 阅读1分钟

Interface

什么是 interface ?

Interfaces 和抽象合约比较类似,但是他们不能实现任何功能。通过定义好的 interface 我们可以在不清楚目标合约具体实现方式的情况下,调用目标的合约

如何定义 interface ?

interface Country {
    // 定义接口中的方法和返回值
}

interface 中不能做什么 ?

  • 接口中不能定义 state 变量(包括 constants)
  • 不能继承
  • 不能有构造函数(constructor)
  • 不能实例化一个 interface
  • 不能实现接口中的方法
  • 接口中的方法不能定义为私有或者内部方法,所有的方法必须定义为外部方法(external)

举个例子

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

/**
 * @title Counter
 * @notice 目标合约
 */
contract Counter {
    uint public count;

    // count值递增
    function increment() external {
        count += 1;
    }
}

/**
 * @title ICounter
 * @notice 接口
 */
interface ICounter {
    function count() external view returns (uint);

    function increment() external;
}

/**
 * @title MyContract
 * @notice 所在接口
 */
contract MyContract {
    function incrementCounter(address _counter) external {
        ICounter(_counter).increment();
    }

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

测试用例

这里我们使用了 hardhat test 工具来测试接口的返回值

//导出依赖库
const { expect } = require('chai')
const { ethers } = require('hardhat')

describe('MyTest', function () {
  it('should be able to increase count', async function () {
    //获得上面的2个合约
    const Counter = await ethers.getContractFactory('Counter')
    const MyContract = await ethers.getContractFactory('MyContract')

    //部署合约
    const counter = await Counter.deploy()
    const mycontract = await MyContract.deploy()

    //通过第二个合约接口调用counter合约,对counter的值进行递增操作
    await mycontract.incrementCounter(counter.address)
    await mycontract.incrementCounter(counter.address)
    await mycontract.incrementCounter(counter.address)

    //获得最终的counter的值
    const countResult = await mycontract.getCount(counter.address)

    //判断counter的值是否 == bigNumber('3')
    expect(countResult).to.eql(ethers.BigNumber.from('3'))
  })
})

最终的输出值符合预期

  MyTest
    ✔ should be able to increase count (1460ms)


  1 passing (1s)

github: github.com/coffiasd/so…