4

I followed the following tutorial: https://medium.com/@mvmurthy/full-stack-hello-world-voting-ethereum-dapp-tutorial-part-1-40d2d0d807c2

Now this tutorial is not using the recent version of web3 but I tried to solve this with the web3 documentation.

This is how far I got:

>byteCode = compiledCode.contracts[':Voting'].bytecode       
>deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data:   byteCode, from: web3.eth.accounts[0], gas: 4700000})
>deployedContract.address
>contractInstance = VotingContract.at(deployedContract.address)

I successfully compiled the byteCode and deployed the contract in the following way:

> VotingContract.deploy({ data: byteCode, arguments: [[web3.utils.asciiToHex("name1"),web3.utils.asciiToHex("name2"),web3.utils.asciiToHex("name3")]] }).send({ from: acc1, gas: 4700000, gasPrice: '3000000' }).on('confirmation', function(confirmationNumber, receipt){console.log(confirmationNumber + ' ' + receipt) }).then(function(instance) {contractInstance = instance});

Now I should have a contract instance, shouldn't I? Or is this something else? The author goes on to do the following:

>contractInstance = VotingContract.at(deployedContract.address)

I did this instead:

var contract3 = new web3.eth.Contract(byteCode, contractInstance.options.address, {from: acc1, gasPrice:'3000000'});

Now if I try to call methods on this contract like:

contract3.methods.totalVotesFor(web3.utils.toHex('name1')).call(acc1).then(function(returned, err) {console.log(returned + ' ' + err)});

I receive the following response:

Promise {
  _bitField: 0,
  _fulfillmentHandler0: undefined,
  _rejectionHandler0: undefined,
  _promise0: undefined,
  _receiver0: undefined }
> Unhandled rejection Error: Returned error: Error: VM Exception while executing eth_call: invalid opcode
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:59368:17
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:69306:5
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:11335:9
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:7895:16
    at replenish (C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8415:25)
    at iterateeCallback (C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8405:17)
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8380:16
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:11332:13
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:69302:9
    at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:63982:7
    at Object.ErrorResponse (C:\Path\node_modules\web3-core-helpers\src\errors.js:29:16)
    at C:\Path\node_modules\web3-core-requestmanager\src\index.js:137:36
    at XMLHttpRequest.request.onreadystatechange (C:\Path\node_modules\web3-providers-http\src\index.js:64:13)
    at XMLHttpRequestEventTarget.dispatchEvent (C:\Path\node_modules\xhr2\lib\xhr2.js:64:18)
    at XMLHttpRequest._setReadyState (C:\Path\node_modules\xhr2\lib\xhr2.js:354:12)

What might I be doing wrong?

Thanks for your help!

2
  • Please check this question. It might help.
    – shonjs
    Jan 7, 2018 at 11:17
  • Based on the answer below, I think the issue might be in the contract code. Could you please share that
    – shonjs
    Feb 12, 2018 at 4:00

3 Answers 3

0

I've used this scripts to deploy a contract using web3 v1.0-beta24

const Web3 = require('web3');
const web3 = new Web3('http://127.0.0.1:8545');

const ownerAddress = "0x....";
const contractAbi = [{"constant":false.... }];
const contractCode = "0x606060...";

const MyContract = new web3.eth.Contract(contractAbi);

MyContract.deploy({
  data: contractCode,
})
.send({
  from: ownerAddress,
  gas: 4000000,
  gasPrice: '30000000000000',
})
.then((instance) => {
  console.log(`Address: ${instance.options.address}`);
});

And this other script to send a message and make a query

const Web3 = require('web3');
const web3 = new Web3('http://127.0.0.1:8545');

const ownerAddress = "0x....";
const contractAbi = [{"constant":false.... }];
const contractCode = "0x606060...";
const contractAddress = "0x....";  // <----- previous script output

const myContract = new web3.eth.Contract(contractAbi, contractAddress);

const options = {
  from: ownerAddress,
  gas: 4000000,
  gasPrice: '30000000000000',
};

const message = web3.utils.asciiToHex('hola');

myContract.methods.sendMessage(message)
.send(options, (err, hash) => {
  if (err) {
    console.log(err);
  }
  console.log(`TxHash: ${hash}`);
})
.then((result) => {
  myContract.methods.getMessage().call()
  .then((result) => {
    console.log(web3.utils.hexToAscii(result));
  });
});

The sample contract I've used is very simple

pragma solidity ^0.4.18;

contract Echo {
    bytes32 public message;

    function sendMessage(bytes32 _message) public {
        message = _message;
    }

    function getMessage() view public returns (bytes32) {
        return message;
    }
}
2
  • That didnt work for me, Infact I was getting empty methods{}, because of which web3js throws me error cannot get length of undefined. I am using beta 10
    – NaN
    Feb 15, 2018 at 4:23
  • @siva I was using beta24 when the test was done, you should try with a more recent build. When time permits I'll check if the example is working with latest build.
    – Ismael
    Feb 15, 2018 at 5:23
0

The contract address is returned on receipt or confirmation event. Here is complete code that votes and get result.

const fs = require('fs');
const solc = require('solc');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));

async function deploy() {
    let accounts = await web3.eth.getAccounts();

    let code = fs.readFileSync('Voting.sol').toString();
    let compiledCode = solc.compile(code);
    let abi = JSON.parse(compiledCode.contracts[':Voting'].interface);
    let bytecode = compiledCode.contracts[':Voting'].bytecode;
    let votingContract = new web3.eth.Contract(abi, {from: accounts[0], gas: 47000, data: bytecode});

    let rama = web3.utils.asciiToHex('Rama');
    let nick = web3.utils.asciiToHex('Nick');
    let jose = web3.utils.asciiToHex('Jose');

    let contractInstance = await votingContract.deploy({
        arguments: [[rama, nick, jose]]
    })
    .send({
        from: accounts[0],
        gas: 1500000
    }, (err, txHash) => {
        console.log('send:', err, txHash);
    })
    .on('error', (err) => {
        console.log('error:', err);
    })
    .on('transactionHash', (err) => {
        console.log('transactionHash:', err);
    })
    .on('receipt', (receipt) => {
        console.log('receipt:', receipt);
        votingContract.options.address = receipt.contractAddress;
    });

    console.log('contractInstance.options:', contractInstance.options);

    let result = await votingContract.methods.totalVotesFor(rama).call({from: accounts[0]});
    console.log('result:', result); // 0

    let receipt = await votingContract.methods.voteForCandidate(rama).send({from: accounts[0]});
    console.log('voteForCandidate receipt:', receipt);

    result = await votingContract.methods.totalVotesFor(rama).call({from: accounts[0]});
    console.log('new result:', result); // 1
}

deploy()
.then(() => console.log('Success'))
.catch(err => console.log('Script failed:', err));
0

I had a similar problems. I think there is a bug in web3.0 when it comes to constructor-arguments. The constructor-values must be added as hex at the end of the bytecode, when you create the tx to deploy the contract.

You can use eth-crypto's txDataByCompiled and then submit the transaction manually.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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