5

I'm trying to deploy/interact with my first ever Ethereum Smart Contract on testrpc but when I try to 'send a transaction' to my deployed contract I'm getting the following Error..

Error: VM Exception while executing eth_call: invalid opcode

I'm using web3 v0.14.0, solc v0.4.11 to compile, and ethereumjs-testrpc ^4.0.1 as my client.

Here's my solidity code..

pragma solidity ^0.4.11;

contract Voting {
  mapping (bytes32 => uint8) public votesReceived;

  bytes32[] public candidateList;

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

  function totalVotesFor(bytes32 candidate) returns (uint8) {
    if (validCandidate(candidate) == false) throw;
    return votesReceived[candidate];
  }

  function voteForCandidate(bytes32 candidate) {
    if (validCandidate(candidate) == false) throw;
    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's my JavaScript file..

const fs = require('fs');
const solc = require('solc')
const Web3 = require('web3');
const web3 = new Web3();

web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

const address = web3.eth.accounts[0];

const code = fs.readFileSync('Voting.sol').toString()
const compiledCode = solc.compile(code)

const abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface)
const byteCode = compiledCode.contracts[':Voting'].bytecode

const VotingContract = web3.eth.contract(abiDefinition)
const deployedContract = VotingContract.new(['Rama','Nick','Jose'], {
  data: byteCode,
  from: web3.eth.accounts[0], gas: 4712388
});

const contractInstance = VotingContract.at(deployedContract.address)


contractInstance.totalVotesFor.call('Rama') // Error: Error: VM Exception while executing eth_call: invalid opcode

Any ideas on what I'm doing wrong? Also, please let me know if my language is correct..

If you need any more information my repo is here: https://github.com/iMuzz/hello-world-ethereum-contract

2

deployedContract.address is undefined, since VotingContract.new is an asynchronous call.

You can do something like this. I don't know why it is calling the function twice, I think it calls once for returning the transaction id and the second to set the contract address.

You can also have a look at truffle-contract for a better web3 wrapper.

  • Thanks so much Fynn! Didn't realize that it was an async call – imuzz Jul 24 '17 at 20:04
0

Ran into the same issue. Excellent answer. The Async request needs to finish before the deployedContract.address can be called. My revised code below:

//creating a new instance of contract, this is an async call - hence the need to wait otherwise invalid opcode error will occur
deployedContract = VotingContract.new([],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000},
        (err, contract) =>
        {
        if (contract.address !== undefined)
                console.log(contract.address)
        }
);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.