Erc-20
TypeError:派生合約必須覆蓋函式“_beforeTokenTransfer”
我正在嘗試實現一個繼承, , ,和的
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
ERC20Detailed
、ERC20Burnable
和已經從 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, Foo2
為contract Foo3 is Foo2
.請注意,這在 solc 0.4.x 中不是問題(當然,在刪除
virtual
andoverride
之後)。
如果我可以使用上面的例子來擴展我的解釋,謝謝
當您有兩個或多個基類定義具有相同名稱和參數類型的函式時,您必須使用
override(baseContract1, baseContract2)
. Foo 和 Foo2 不一定要相互繼承。嘗試:
contract Foo3 is Foo, Foo2 { function func(uint _x) public virtual override(Foo, Foo2) { super.func(3*_x); } }