Solidity跨合约调用payable地址报transfer成员不存在错误怎么解决
报错根本原因
FirstContract中的_admin状态变量未添加public修饰符,Solidity 中状态变量默认可见性为internal,仅合约内部和继承合约可访问,外部合约没有直接访问权限。- 即便你后续给
_admin补充了public修饰符,Solidity 会为 public 状态变量自动生成同名的 getter 函数,你需要通过加括号的方式调用函数拿到返回值。直接写firstContract._admin拿到的是函数本身的引用,而非返回的address payable类型的管理员地址,所以对函数引用调用transfer方法就会触发你收到的报错。
修复步骤
- 修改
FirstContract.sol,给_admin变量添加public修饰符,也可以单独实现公开的管理员地址查询方法 - 修改
SecondContract.sol中调用_admin的逻辑,添加括号调用 getter 函数拿到地址后再执行transfer - 补充
transferValue方法的payable修饰符,否则方法无法接收ETH,转账逻辑也会执行失败
修正后代码示例
FirstContract.sol
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract FirstContract is ERC721 { using Counters for Counters.Counter; Counters.Counter public _id; // 新增public修饰符,自动生成getter函数 address payable public _admin; constructor(address admin) ERC721("Token Name", "TOKEN") { _admin = payable(admin); } function incrementToken() public { _id.increment(); } }
SecondContract.sol
import "./FirstContract.sol"; contract SecondContract { FirstContract firstContract; constructor(address _address) { firstContract = FirstContract(_address); } function increment() external { firstContract.incrementToken(); } function transferValue(uint value) external payable { // 加括号调用_admin() getter函数拿到地址,再执行transfer firstContract._admin().transfer(value); } }
内容的提问来源于stack exchange,提问作者Kevvv
相关产品推荐
相关产品推荐

