成员 "transfer" 未找到或不可见

Member "transfer" not found or not visible

我有两个单独部署的合约。

FirstContract.sol

contract FirstContract is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter public _id;
    address payable _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 {
        firstContract._admin.transfer(value); // error here
    }
}

我遇到错误:

Member "transfer" not found or not visible after argument-dependent lookup in function () view external returns (address payable).

我不确定为什么会出现这个错误,因为函数被标记为 public here

FirstContract 派生自 ERC721 但问题末尾的 link 指向 ERC20 合同。因此 ERC20transfer() 的定义与此上下文无关。


firstContract._admin.transfer(value);

此代码段试图使用 address payable 类型的 Solidity 原生 transfer() member,即转移 ETH(不是 ERC20 代币)。但它失败了,因为 firstContract._admin 不可见。

如果 FirstContractSecondContract 的父级,以及 _admin 具有 public 可见性修饰符,那么它将是可见的。由于它没有指定任何可见性修饰符,因此使用默认值 internal

  1. 赋予 _admin 属性 public 可见性修饰符
address payable public _admin;

那么你需要将firstContract._admin(属性)的调用更改为firstContract._admin()(函数),因为编译器在外部处理public属性的方式合同。在 docs.

中查看有关自动生成的 getter 函数的更多信息
  1. 将调用从 属性 更改为函数
firstContract._admin().transfer(value);

请注意,SecondContract 不持有任何 ETH,目前无法接收任何 ETH。因此,如果您尝试 transfer() 超过 SecondContract 的当前余额(即 0),交易将恢复。

出于测试目的,您可以将 payable 修饰符添加到构造函数并使用部署交易向其发送一些 ETH,以便您可以测试 transferValue().

constructor(address _address) payable {