多次调用时,Solidity 代码会给出 VM 异常错误

Solidity code gives VM exception error when called multiple times

让我们从我的 solidity 代码开始:

pragma solidity ^0.4.18;

contract Voting {
    address mainAddress;
    bytes32[] candidateNames;
    mapping(bytes32 => uint) candidateVotes;
    mapping(bytes32 => bytes32) candidatesDetails;
    address[] voters;

    function Voting() public {
        mainAddress = msg.sender;
    }

    modifier isMainAddress {
        if (msg.sender == mainAddress) {
            _;
        }
    }

    function getAllCandidates() public view returns (bytes32[]) {
        return candidateNames;
    }

    function setCandidate(bytes32 newCandidate) isMainAddress public {
        candidateNames.push(newCandidate);
    }

    function setVote(bytes32 candidate) public {
        require(validVoters());
        candidateVotes[candidate] = candidateVotes[candidate] + 1;
        voters.push(msg.sender);
    }

    function getVote(bytes32 candidate) public view returns (uint) {
        return candidateVotes[candidate];
    }

    function setDescrption(bytes32 candidateName, bytes32 candidatesDesc) isMainAddress public {
        candidatesDetails[candidateName] = candidatesDesc;
    }

    function getDescription(bytes32 candidateName) public view returns (bytes32){
        return candidatesDetails[candidateName];
    }

    function getCurrentAddress() public view returns (address) {
        return msg.sender;
    }

    function validVoters() public view returns (bool) {
        for(uint i = 0; i < voters.length ; i++){
           if (voters[i] == msg.sender) {
                return false;
           } 
        }
        return true;
    }
}

函数:Voting()、getAllCandidates()、setCandidate()、getVote()、setDescription()、getDescription()、getCurrentAddress() 在多次调用时工作正常次。所以,我想我们现在可以忽略它们了。

函数 setVote() 在第一次执行 时运行良好。当一个人投票一次。当同一个人第二次尝试投票时,问题就出现了。它给出以下错误:

这可能是初学者的错误,但我连续 2 天都在尝试解决这个问题,现在我真的需要帮助。

此外,

谢谢。

有问题的函数:

function setVote(bytes32 candidate) public {
    require(validVoters());
    candidateVotes[candidate] = candidateVotes[candidate] + 1;
    voters.push(msg.sender);
}

请注意 validVoters() 必须 return true 才能使此功能成功。如果它 returns falserequire 将失败并恢复交易。另请注意,在函数的末尾,msg.sender 被添加到数组 voters.

我们来看看validVoters():

function validVoters() public view returns (bool) {
    for(uint i = 0; i < voters.length ; i++){
       if (voters[i] == msg.sender) {
            return false;
       } 
    }
    return true;
}

这个函数returns false如果msg.sendervoters,我们知道账户投票一次后就会这样。

所以第二次通过,validVoters() returns false,这导致 setVote() 中的 require(validVoters()) 恢复交易。