Truffle TestRPC-Fehler: VM-Ausnahme beim Ausführen von eth_call: ungültiger Opcode

Ich habe ein Projekt aus einer Truffle Box erstellt. Ich habe meinen eigenen Vertrag für die Stimmabgabe erstellt. An diesem Punkt möchte ich in der Lage sein, abzustimmen, was zu funktionieren scheint, und die Gesamtstimmen für alle Kandidaten zurückgeben, aber ich erhalte einen Fehler, hier ist ein Code.

pragma solidity ^0.4.2;

contract Voting {

mapping (bytes32 => uint8) public votesReceived;

uint8[] public totalVotes;

bytes32[] public candidateList;

function Voting(bytes32[] candidateNames) {
    candidateList = candidateNames;
}

// This function returns the total votes a candidate has received so far
function totalVotesFor(bytes32 candidate) returns (uint8) {
    if (validCandidate(candidate) == false) revert();
    return votesReceived[candidate];
}

//returns totalVotes
function getAllVotes() constant returns (uint8[]) {
    for(uint i = 0; i < candidateList.length; i++) {
        bytes32 candidate = candidateList[i];
        totalVotes[i] = votesReceived[candidate];
    }
    return totalVotes;
}

// This function returns all candidates
function getCandidateList() returns (bytes32[]) {
    return candidateList;
}

// This function increments the vote count for the specified candidate. This
// is equivalent to casting a vote
function voteForCandidate(bytes32 candidate) {
    if (validCandidate(candidate) == false) revert();
    votesReceived[candidate] += 1;
}

function validCandidate(bytes32 candidate) returns (bool) {
    for(uint i = 0; i < candidateList.length; i++) {
        if (candidateList[i] == candidate) {
            return true;
        }
    }
    return false;
}
}

und hier ist mein Javascript-Code

        const voting = contract(VotingContract)
        voting.setProvider(web3.currentProvider)

        // Declaring this for later so we can chain functions on it.
        var votingInstance;

        // Get current ethereum wallet.
        web3.eth.getCoinbase((error, coinbase) => {
            // Log errors, if any.
            if (error) {
                console.error(error);
            }

            voting.deployed().then(function (instance) {
                votingInstance = instance

                // Attempt to vote.
                votingInstance.voteForCandidate(candidate, {from: coinbase})
                    .then(function (result) {
                        //your vote is cast
                        return votingInstance.getAllVotes()
                    })
                    .then(function(result){
                        console.log(result)
                    })
                    .catch(function (error) {
                        // If error...
                        console.log(error)
                    })
            })
        })

Beim Aufrufen von VotingInstance.getAllVotes() erhalte ich diesen Fehler

Error: Error: VM Exception while executing eth_call: invalid opcode
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:59368:17
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:69306:5
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:11335:9
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:7895:16
at replenish (/usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8415:25)
at iterateeCallback (/usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8405:17)
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8380:16
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:11332:13
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:69302:9
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:63982:7
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:59368:17
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:69306:5
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:11335:9
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:7895:16
at replenish (/usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8415:25)
at iterateeCallback (/usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8405:17)
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:8380:16
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:11332:13
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:69302:9
at /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js:63982:7
at Object.InvalidResponse (http://localhost:3000/static/js/bundle.js:54358:17)
at http://localhost:3000/static/js/bundle.js:43504:37
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:9899:9
at completeRequest (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:9950:9)
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:673:16
at replenish (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:1193:25)
at iterateeCallback (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:1183:17)
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:1158:16
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:9827:7
at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/scripts/inpage.js:9923:18

Ich kann nirgendwo eine Lösung finden, jemand bitte HILFE!!

Antworten (2)

Das Problem hier ist, dass Sie versuchen, eine Zustandsvariable totalVotes von einer konstanten Funktion ( getAllVotes ) zu ändern.

Eine konstante Funktion kann nur Daten lesen. Wenn Sie innerhalb der Funktion Berechnungen für ein Array oder eine Struktur durchführen müssen, können Sie das Schlüsselwort verwenden memory. Sie können jedoch keine Zustandsvariable ändern (im Smart-Contract global deklarierte Variable).

//returns totalVotes
function getAllVotes() constant returns (uint8[]) {
    uint8[] memory totalVotes = new uint8[](candidateList.length);

    for(uint i = 0; i < candidateList.length; i++) {
        bytes32 candidate = candidateList[i];
        totalVotes[i] = votesReceived[candidate];
    }
    return totalVotes;
}

Nur ein paar Dinge. Sie erklären sich totalVoteszur Vertragslagerung bereit

uint8[] public totalVotes;

Die Funktion getallVotesist als konstant deklariert, aber Sie versuchen, sie zu änderntotalVotes

//returns totalVotes
function getAllVotes() constant returns (uint8[]) {
    for(uint i = 0; i < candidateList.length; i++) {
        bytes32 candidate = candidateList[i];
        totalVotes[i] = votesReceived[candidate];
    }
    return totalVotes;
}

Und von dieser Antwort https://ethereum.stackexchange.com/a/3590 können Sie kein dynamisches Array zurückgeben.