【问题标题】:Member "transfer" not found or not visible未找到或不可见成员“转移”
【发布时间】:2021-12-29 08:27:13
【问题描述】:

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

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
    }
}

我收到了错误:

在函数 () 查看外部返回(应付地址)中的参数相关查找后,未找到或不可见成员“转移”。

我不知道为什么会出现这个错误,因为函数被标记为publichere

【问题讨论】:

  • 这是因为它被标记为内部。要绕过它,请在 FirstContract 中创建一个调用 _id.increment() 的公共函数,因为 FirstContract 正在使用 Counter
  • @egjlmn1 谢谢。我能够解决它,但遇到了另一个问题。我已经更新了问题。
  • 您可以在 FirstContract 中创建一个额外的代理方法并通过它调用 admin.transfer - 就像对 incrementToken 所做的那样
  • 我怀疑是因为 _admin 不是公开的。除此之外 transfer 不建议发送以太币。尝试切换到call() 看这里solidity-by-example.org/sending-ether

标签: blockchain ethereum solidity smartcontracts


【解决方案1】:

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


firstContract._admin.transfer(value);

这个 sn-p 正在尝试使用 address payable 类型的 Solidity 原生 transfer() member,即转移 ETH(不是 ERC20 代币)。但它失败了,因为firstContract._admin 不可见。

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

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

然后你需要将firstContract._admin(属性)的调用更改为firstContract._admin()(函数),因为编译器处理外部合约中公共属性的方式。在 docs 中查看有关自动生成的 getter 函数的更多信息。

  1. 将调用从属性改为函数
firstContract._admin().transfer(value);

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

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

constructor(address _address) payable {

【讨论】:

  • 哇,谢谢你,这很有意义。那么在这种情况下firstContract._admin().transfer(value); 编译器正在调用两个函数?首先是getter函数,然后是使用第一个函数返回值的传递函数?
  • @Kevvv 没错。具体来说-您的情况下的transfer()address payable 类型的成员函数,因此它转移了ETH。与ERC20transfer()函数无关。
猜你喜欢
  • 2019-04-29
  • 2021-08-18
  • 2021-06-11
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
相关资源
最近更新 更多