You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity跨合约调用payable地址报transfer成员不存在错误怎么解决

报错根本原因

  • FirstContract 中的 _admin 状态变量未添加 public 修饰符,Solidity 中状态变量默认可见性为 internal,仅合约内部和继承合约可访问,外部合约没有直接访问权限。
  • 即便你后续给 _admin 补充了 public 修饰符,Solidity 会为 public 状态变量自动生成同名的 getter 函数,你需要通过加括号的方式调用函数拿到返回值。直接写 firstContract._admin 拿到的是函数本身的引用,而非返回的 address payable 类型的管理员地址,所以对函数引用调用 transfer 方法就会触发你收到的报错。

修复步骤

  1. 修改 FirstContract.sol,给 _admin 变量添加 public 修饰符,也可以单独实现公开的管理员地址查询方法
  2. 修改 SecondContract.sol 中调用 _admin 的逻辑,添加括号调用 getter 函数拿到地址后再执行 transfer
  3. 补充 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:15:05