Erc-20

TypeError:派生合約必須覆蓋函式“_beforeTokenTransfer”

  • April 1, 2022

我正在嘗試實現一個繼承, , ,和的ERC20令牌。ERC20.sol``ERC20Detailed.sol``ERC20Burnable.sol``ERC20Mintable.sol``ERC20Pausable.sol

contract DemoContract is ERC20,ERC20Detailed,ERC20Burnable,ERC20Mintable, ERC20Pausable {
   constructor(uint256 initialSupply) ERC20Detailed("Test Token", "TEST", 18) public {
       _mint(msg.sender, initialSupply);
   }
}

函式_beforeTokenTransfer定義 ERC20.sol如下:

function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }

如下ERC20Pausable.sol

function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
   super._beforeTokenTransfer(from, to, amount);

   require(!paused(), "ERC20Pausable: token transfer while paused");
}

當我嘗試使用 truffle 框架編譯我的合約時,我收到以下錯誤:

TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types.

contract DemoContract is ERC20,ERC20Detailed,ERC20Burnable,ERC20Mintable, ERC20Pausable {
^ (Relevant source part starts here and spans across multiple lines).

儘管在ERC20Pausable.sol.

以下是從 DemoContract 中移除 ERC20 後的新合約:

contract ERC20 is Context, IERC20

contract ERC20Detailed is ERC20

abstract contract ERC20Burnable is Context, ERC20

abstract contract ERC20Mintable is ERC20, MinterRole

abstract contract ERC20Pausable is ERC20, Pausable

contract DemoContract is ERC20Detailed,ERC20Burnable,ERC20Mintable, ERC20Pausable

但是,錯誤仍然存在。

contract DemoContract is ERC20,ERC20Detailed,ERC20Burnable,ERC20Mintable, ERC20Pausable

每個 contract ERC20DetailedERC20Burnable和已經從 contract 繼承ERC20Mintable,所以你也不應該從這個 contract 繼承。ERC20Pausable``ERC20

例如,編譯以下程式碼會產生與您相同的錯誤:

pragma solidity 0.6.4;

contract Foo {
   uint x;
   function func(uint _x) public virtual {
       x = _x;
   }
}

contract Foo2 is Foo {
   function func(uint _x) public virtual override {
       super.func(2*_x);
   }
}

contract Foo3 is Foo, Foo2 {
   function func(uint _x) public virtual override {
       super.func(3*_x);
   }
}

當您更改contract Foo3 is Foo, Foo2contract Foo3 is Foo2.

請注意,這在 solc 0.4.x 中不是問題(當然,在刪除virtualandoverride之後)。

如果我可以使用上面的例子來擴展我的解釋,謝謝

當您有兩個或多個基類定義具有相同名稱和參數類型的函式時,您必須使用override(baseContract1, baseContract2). Foo 和 Foo2 不一定要相互繼承。

嘗試:

contract Foo3 is Foo, Foo2 {
   function func(uint _x) public virtual override(Foo, Foo2) {
       super.func(3*_x);
   }
}

引用自:https://ethereum.stackexchange.com/questions/80584