Solidity 0.5.1无构造函数合约类型转换为何必须传入地址参数
Solidity 0.5.1 传地址初始化合约实例的底层原理
核心结论
代码里的ERC20Token(address(token))不是调用合约构造函数创建新实例,是Solidity 0.5.x版本强制要求的「地址类型转合约类型的显式类型转换」操作,和ERC20Token是否自定义构造函数完全无关。
两类合约操作的语法区别
Solidity里和合约类型相关的操作分两种,语法完全独立,很容易被混淆:
- 部署新合约:如果要在链上部署一个全新的ERC20Token合约,必须加
new关键字,写法是new ERC20Token([构造函数参数])。这个操作会触发EVM创建新合约账户、执行构造函数、生成全新的合约地址。如果合约没写自定义构造函数,写new ERC20Token()是合法的,不需要传参。 - 引用已部署的合约:如果要和已经部署在链上某个地址的现有合约交互,不需要重新部署,只要拿到对应合约的调用句柄就行。Solidity 0.5.0开始加了强类型校验,不允许把address类型隐式转成合约类型,必须显式做类型转换,告诉编译器这个地址对应的合约符合目标ABI,写法就是
合约名(目标合约地址)。这个操作只在编译期做类型检查,不会产生链上交易、不会调用构造函数、也不会部署新合约。
报错原因
你改成ERC20Token _token = ERC20Token();之后,编译器识别逻辑是这样的:
- 没有
new关键字,不会判定为部署新合约的操作 - 显式类型转换要求必须传入1个address类型的参数,这里没传,不符合语法要求
所以编译器直接抛出错误:
Exactly one argument expected for explicit type conversion
对应代码逻辑的验证
你的操作流程是先部署ERC20Token,再把部署后的地址传给MyContract做初始化。buyToken里的ERC20Token(address(token))只是把提前存好的已部署ERC20Token地址转成合约类型的调用句柄,后续调用_token.mint()是和之前部署好的那个ERC20Token交互,全程不会触发ERC20Token的构造函数,自然和ERC20Token有没有自定义构造函数没有关系。
内容的提问来源于stack exchange,提问作者Ki ng
相关产品推荐
相关产品推荐

