Ich versuche, meinen allerersten Ethereum Smart Contract bereitzustellen/mit ihm zu interagieren, testrpc
aber wenn ich versuche, eine Transaktion an meinen bereitgestellten Vertrag zu senden, erhalte ich die folgende Fehlermeldung.
Error: VM Exception while executing eth_call: invalid opcode
Ich verwende web3 v0.14.0
, solc v0.4.11
zum Kompilieren und ethereumjs-testrpc ^4.0.1
als meinen Client.
Hier ist mein Soliditätscode..
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;
}
}
und hier ist meine JavaScript-Datei..
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
Irgendwelche Ideen, was ich falsch mache? Bitte teilen Sie mir auch mit, ob meine Sprache korrekt ist.
Wenn Sie weitere Informationen benötigen, finden Sie mein Repo hier: https://github.com/iMuzz/hello-world-ethereum-contract
deployContract.address ist undefiniert, da VotingContract.new ein asynchroner Aufruf ist.
Sie können so etwas tun . Ich weiß nicht, warum es die Funktion zweimal aufruft, ich denke, es ruft einmal auf, um die Transaktions-ID zurückzugeben, und das zweite, um die Vertragsadresse festzulegen.
Sie können sich auch Truffle-Contract für einen besseren Web3-Wrapper ansehen.
Bin auf das gleiche Problem gestoßen. Ausgezeichnete Antwort. Die Async-Anforderung muss abgeschlossen sein, bevor die deployedContract.address aufgerufen werden kann. Mein überarbeiteter Code unten:
//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)
}
);
imuzz