Solidity合约报错:未传递基类构造函数参数,需传参或标记为抽象类
问题解决:Solidity基类构造函数参数错误
错误原因
你遇到的TypeError: No arguments passed to the base constructor是因为合约AssetAcquisition继承了Ownable和ERC20两个基类,但构造函数只给ERC20传递了参数,未正确处理Ownable的构造函数要求;同时你重复定义了Ownable和ERC20已实现的变量(比如_owner、_totalSupply),这也会导致编译器冲突。
修复步骤
1. 移除重复定义的冗余变量
Ownable已内置owner()查询方法和内部的_owner变量,ERC20已经实现了总供给、用户余额、授权额度的存储逻辑,删掉以下重复定义的变量:
string private _tokenname、string private _tokensymboladdress public _owneruint256 public _totalSupplymapping(address => uint256) balancesmapping(address => mapping(address => uint256)) private _allowances
2. 正确调用基类构造函数
根据你使用的OpenZeppelin版本调整构造函数:
- OpenZeppelin v4+(当前master分支版本):
Ownable构造函数无参数,自动将合约部署者设为owner。构造函数只需初始化ERC20的名称和符号:constructor(string memory _tokenName, string memory _tokenSymbol) ERC20(_tokenName, _tokenSymbol) { // 可选:铸造初始代币给owner,注意乘以ERC20默认的18位小数 _mint(owner(), 1000000 * 10 ** decimals()); } - 旧版本(v2/v3):
Ownable构造函数需要传入初始owner地址,此时要同时调用两个基类的构造函数:constructor(address __owner, string memory _tokenName, string memory _tokenSymbol) ERC20(_tokenName, _tokenSymbol) Ownable(__owner) { _mint(__owner, 1000000 * 10 ** decimals()); }
3. 初始化代币总供给
ERC20的_totalSupply是内部变量,需通过_mint方法铸造代币来初始化总供给,上面的代码已经包含了这一步。
修复后的完整合约代码
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol"; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; import './StringUtils.sol'; // @dev contract for asset transfer and acquisition contract AssetAcquisition is Ownable, ERC20 { uint randNonce = 0; uint modulus = 0; uint maxWaitTime = 100; struct Assets { address owner; address sender; address payable receiver; uint256 amountleft; uint256 datesent; } mapping(address => Assets) public assetstore; Assets[] public assetstorage; event AssetTransferAndMergerEvent(address payable _companyaddress, address payable _mergeraddress, uint256 amount); event AssetTransferMergerDetails(address owner, address sender, address payable receiver, uint256 amountleft, uint256 datesent); // 适用于OpenZeppelin v4+的构造函数 constructor(string memory _tokenName, string memory _tokenSymbol) ERC20(_tokenName, _tokenSymbol) { // 铸造1000000代币给合约owner(部署者) _mint(owner(), 1000000 * 10 ** decimals()); } // 如果需要指定非部署者为初始owner,替换上面的构造函数为: // constructor(address __owner, string memory _tokenName, string memory _tokenSymbol) ERC20(_tokenName, _tokenSymbol) { // _transferOwnership(__owner); // _mint(__owner, 1000000 * 10 ** decimals()); // } }
验证
修复后,编译器不会再要求将合约标记为抽象类,你可以正常部署合约。
内容的提问来源于stack exchange,提问作者Bonsu
相关产品推荐
相关产品推荐

