如何修复“ VM错误:无效的操作码。无效的操作码”

时间:2019-07-07 00:26:53

标签: solidity

我正在尝试创建一个名为join的功能,该功能可使玩家加入游戏。每次有人加入游戏之前。该功能将检查该玩家是否已经存在,如果他/她存在于游戏中,该功能将自动为该特定玩家的余额充值。否则,该函数会将新播放器添加到称为播放器的映射对象中。但是,当我尝试在混音中运行该函数时,它返回如下错误:

VM error: invalid opcode.
       invalid opcode   
       The execution might have thrown.
       Debug the transaction to get more information.

以下是我的代码:

    pragma solidity >=0.5.0;


    contract lotteryAdvanced {
        address public manager;
        mapping(address=>uint) public players;
        uint public totalAmount = 0;
        uint public numPlayers = 0;
        address[] public users;
        modifier managerOnly() {
            require(msg.sender == manager, 'You are not the manager of this game');
            _;
        }
        constructor() public{
            manager = msg.sender;
        }


        function join() public payable{
            require(msg.value >= 100000000000000000 wei, 'Please enter a number within the provided range');
            for( uint i = 0; i <= uint(users.length) ; i++)
            {
              if(msg.sender == users[i]) {
                players[msg.sender] = players[msg.sender] + msg.value;
              }
              players[msg.sender] = msg.value;
              users.push(msg.sender);
            }
            numPlayers++;
        }
    ```

1 个答案:

答案 0 :(得分:0)

这可能无法解决Remix / EVM的直接问题,但是-查看共享的代码-看来for循环中有几行应该在外面,并有条件地执行:

for(uint i = 0; i <= uint(users.length); i++)
{
    if(msg.sender == users[i]) {
        players[msg.sender] = players[msg.sender] + msg.value;
    }
    players[msg.sender] = msg.value;
    users.push(msg.sender);
}

在这里,您为msg.value中的每个现有玩家编写一次players[msg.sender]作为players[]的条目;然后为每个玩家将msg.sender推入users。这导致发生以下情况:

  1. players[msg.sender]的值将始终为msg.value,即使在msg.sender已经是players中的条目的情况下(即,即使此特定玩家已经在游戏中)。您可以有效地覆盖前面if块中的“充值”代码。

  2. 您最终在n+1中拥有msg.sender的{​​{1}}副本,其中users是存在的用户数(在n中) users[]被调用时。

我将遍历您的join()代码的每一行,并验证它是否正在正确执行您期望的步骤。通过将join()建模为映射而不是数组,并维护单独的{{,您可以避免for循环(可能是“无界的”,请参见this definition)。 1}}状态变量。这样一来,您就可以恒定时间更新users映射,从而最大程度地节省了汽油费用。