Solidity交易错误,如果您发送价值,则被调用的函数应该是可支付的,且您发送的价值应小于您当前的余额。

23
我正在Remix上学习Solidity。我在跟着YouTube上的一些教程视频做的时候,在构建2个合约时遇到了困难。ERC20Token合约有一个增加余额的函数,而Mycontract实例化并调用了mint函数。我按照那个人在YouTube上的方式做了,但是当我调用buyToken函数时遇到了错误。错误显示:“transact to MyContract.buyToken errored: VM error: revert. revert 交易已被还原至初始状态。注意:如果您发送价值,则调用的函数应为可支付的,且您发送的价值应小于您当前的余额。请调试交易以获取更多信息。”请帮帮我。以下是代码。
pragma solidity 0.5.1;

contract ERC20Token{
   string public name;
   mapping(address => uint256) public balances;

   function mint() public {
       balances[tx.origin] ++;
  }
}

contract MyContract {
   address payable wallet;
   address public token;


   constructor(address payable _wallet, address _token) public {
    wallet = _wallet;
    token = _token;
}

    

   function buyToken() public payable {
       ERC20Token _token = ERC20Token(address(token)); 
       _token.mint();
       wallet.transfer(msg.value);
    
      }
  }

enter image description here


这条评论有点晚了,你在调用buyToken时是否发送了以太币? - jhonny
11个回答

5

首先,您需要部署 ERC20Token

enter image description here

在我的情况下,它被部署到地址 0xcD6a42782d230D7c13A74ddec5dD140e55499Df9

enter image description here

ERC20Token 的地址对于下一步很重要。


然后,您部署 MyContract。不要忘记传递构造函数参数:

  • _wallet 是 Remix JS VM 模拟器中任何有效地址(从“账户”选择框中)

    为了回答这个问题,我选择了地址 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c,您将在第三步中看到它。

  • _token 是上一步中的代币合约地址

enter image description here


最后,您可以执行 MyContractbuyToken() 函数。

在函数执行之前,您可以看到发送者有 89 ETH,并将使用本次交易发送 50 ETH。

enter image description here

成功执行后,发送者现在有 39 ETH,因为以下这行代码,wallet已经收到了 50 ETH:

wallet.transfer(msg.value);

这里输入图片描述

从截图中可以看出,交易已成功。

这里输入图片描述


4

你应该在构造函数中使用 payable 关键字,如下所示:

constructor(address payable _wallet) public payable{
     ...
}

它只在构造函数中工作,为什么不能在另一个函数中使用?function enter() public payable {} - Nikhil Patil

2
由于您当前的余额为0,您可以尝试使用低级交互将一些余额发送到合约地址。如果可行,请告诉我!

enter image description here


2
我遇到了这个问题,但是这个方法不起作用。在使用任何数量的wei或ether进行部署时,我都会得到相同的错误。 - LittleBobbyTables

1

0

通过使用balanceOf(owner)函数检查您的余额,因为您创建的代币就是您的余额,如果您没有任何东西,就无法购买物品。您在此编写的智能合约具有您拥有的代币数量作为余额。我也在我的智能合约中遇到了类似的错误,并在一天后发现了这个问题。

要克服这个问题,请执行以下操作:

  • 添加程序以从个人的余额中添加和减去余额,包括买家和所有者。
  • 如果您想要为新手提供一些入门级别的余额来开始购买物品。

0

我在其他地方没有看到的一个答案是,如果您正在通过浏览器运行Remix,则只需刷新页面/浏览器即可。


0

如果你正在使用测试环境,建议尝试使用O wei。


0

当您的合约没有任何接收以太币的方法时,也会出现此错误。请确保检查一下,接收(receive())函数应该存在。


0
将这行代码更改为:wallet.transfer(msg.value); 更改为:wallet.transfer(payable(msg.value));

你能详细说明这是如何解决问题的吗?提供一个参考或简要解释会很有帮助。 - ryanwebjackson

0

请确保您首先部署ERC20Token。然后,在已部署的ERC20Token旁边有一个剪贴板,可复制ER20Token的地址。将该地址复制到MyContract的_token字段中,并从账户中复制一个钱包地址到_wallet字段中。

切换帐户,以便您看到不同的钱包地址,然后单击MyContract buyToken按钮,您就不应再出现错误。

您的代码是正确的,但您在处理钱包/令牌地址时出错了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接