0

I've created a project from a Truffle Box. I have created my own contract for voting. At this point i want to be able to vote, which seems to be working, and return the total votes for all candidates, but im getting an error, here is some 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;
}
}

and here is my 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)
                    })
            })
        })

When calling votingInstance.getAllVotes() i get this error

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

can't find a solution anywhere, someone please HELP!!

Derek Hannah
  • 103
  • 3

2 Answers2

0

The problem here is that you are trying to change a state variable totalVotes from a constant function (getAllVotes).

A constant function can only read data. If you need to do computation inside the function on an array or a struct, you can use the keyword memory. But you cannot change a state variable (variable declared globally in the smart-contract)

//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;
}
Greg Jeanmart
  • 7,207
  • 2
  • 19
  • 35
0

Just a couple of things. You declare totalVotes in contract storage

uint8[] public totalVotes;

The function getallVotes is declared constant but you try to modify totalVotes

//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;
}

And from this answer https://ethereum.stackexchange.com/a/3590, you cannot return a dynamic array.

Ismael
  • 30,570
  • 21
  • 53
  • 96