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
Best Answer
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.