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

时间:2018-01-16 04:14:29

标签: solidity smartcontracts remix

让我们从我的可靠性代码开始:

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()在第一次执行时运行正常。当一个人投票一次。当同一个人第二次尝试投票时,问题就出现了。它给出了以下错误:

enter image description here

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

此外,

  • 我使用 Remix - 基于浏览器的IDE 来运行/检查我的可靠性代码。

  • 我使用 Ganache 作为测试帐户。

谢谢。

1 个答案:

答案 0 :(得分:1)

有问题的功能:

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

请注意,validVoters()必须返回true才能使此功能成功。如果它返回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;
}

如果false位于msg.sender,此函数将返回voters,我们知道在帐户投票一次后就是这种情况。

因此,第二次,validVoters()返回false,这会导致require(validVoters())中的setVote()恢复交易。