Web3.js: Error: Invalid bytes string given: 0x [web.1.0.0-beta.47]

Created on 3 Mar 2019  路  9Comments  路  Source: ChainSafe/web3.js

Use solidity contract instance's public property or method error in web3js.

Course.sol:

pragma solidity ^0.5.0;

contract Course {
    string public name;

    constructor(string memory _name) public {
        name = _name;
    }

    function getName() public view returns (string memory) {
        return name;
    }
}

Course.sol is compiled to Imooc.json by solc.

/test/course.spec.js:

const path = require('path');
const assert = require('assert');
const Web3 = require('web3');

const web3 = new Web3('ws://localhost:8545');
const Imooc = require(path.resolve(__dirname, '../src/compiled/Imooc.json'));

let accounts;

describe('test', () => {
  before(async () => {
    accounts = await web3.eth.getAccounts();

    myCourse = await new web3.eth.Contract(Imooc.Course.abi, accounts[0]);

    myCourse.deploy({
      data: Imooc.Course.evm.bytecode.object,
      arguments: ['vue course']
    }).send({
      from: accounts[0]
    });
  });

  it('test 1', async () => {
    // const name = await myCourse.methods.name().call({from: accounts[0]});  // error too
    const name = await myCourse.methods.getName().call(from: accounts[0]);
    console.log(name);
  })
});

Expected behavior

I want to get course name with:

const name = await myCourse.methods.getName().call(from: accounts[0]);

or

const name = await myCourse.methods.name().call({from: accounts[0]});
mocha --watch

test1 
  "vue course" // console.log(name);

Actual behavior

But I got the error:

Error: Invalid bytes string given: 0x
      at AbiCoder.decodeParameters (node_modules\web3-eth-abi\dist\web3-eth-abi.cjs.js:64:15)
      at CallContractMethod.afterExecution (node_modules\web3-eth-contract\dist\web3-eth-contract.cjs.js:740:32)
      at CallContractMethod._callee$ (node_modules\web3-core-method\dist\web3-core-method.cjs.js:354:35)
      at tryCatch (node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:288:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules\@babel\runtime\node_modules\regenerator-runtime\runtime.js:114:21)
      at asyncGeneratorStep (node_modules\@babel\runtime\helpers\asyncToGenerator.js:3:24)
      at _next (node_modules\@babel\runtime\helpers\asyncToGenerator.js:25:9)
      at process._tickCallback (internal/process/next_tick.js:68:7)

If I return a constant, it work well.

    function getName() public pure returns (string memory) {
        return "vue course";
    }

Steps to reproduce the behavior

see above

Error Logs

see above

Versions

[NPM 6.4.1, Node v10.14.2, Web3.js beta.47, OS windows, ganache-cli: ^6.3.0, mocha: ^6.0.1, solc: ^0.5.0]

support

All 9 comments

My first impression is that the problem is around the deploy method, and more specifically the data parameter. It would help if you shared the Imooc.json file for repeatability. It is calling the getName() function, but since the constructor might have been ignored(?), 0x is returned for unset storage (due to default behavior). That is, name was never assigned.

My first impression is that the problem is around the deploy method, and more specifically the data parameter. It would help if you shared the Imooc.json file for repeatability. It is calling the getName() function, but since the constructor might have been ignored(?), 0x is returned for unset storage (due to default behavior). That is, name was never assigned.

constructor parameter is pass by arguments: ['vue course'], ref: How to pass arguments to the constructor while testing an contract using web3

Imooc.json is too long, more detail the output of .sol compiled by solc here

Maybe you could share the solc output in a gist? I saw that you passed the string in the constructor, but if the function is correctly called with a hardcoded string in solidity, the problem is somewhere around the constructor. It would really help with repeatability.

Maybe you could share the solc output in a gist? I saw that you passed the string in the constructor, but if the function is correctly called with a hardcoded string in solidity, the problem is somewhere around the constructor. It would really help with repeatability.

Here the gist

Found the issue. You need to await the deploy. Everything works fine, but you were doing eth_call before the code was actually deployed. You can send an eth_call to an empty address and you will still get 0x for all calls.

Maybe a warning about non-existing code should be included, or alternatively a pre-check. @nivida

Working solution:

await myCourse.deploy({
  data: Imooc.Course.evm.bytecode.object,
  arguments: ['vue course']
}).send({
  from: accounts[0]
}).catch(console.error);

Found the issue. You need to await the deploy. Everything works fine, but you were doing eth_call before the code was actually deployed. You can send an eth_call to an empty address and you will still get 0x for all calls.

Maybe a warning about non-existing code should be included, or alternatively a pre-check. @nivida

Working solution:

await myCourse.deploy({
  data: Imooc.Course.evm.bytecode.object,
  arguments: ['vue course']
}).send({
  from: accounts[0]
}).catch(console.error);

OMG, you are true.

    setTimeout(async () => {
      const name = await myCourse.methods.name().call();
      console.log(name); // "vue course"
    }, 5000);

I tried setTimeout 300millisecond before, but it still no deployed. It is slow, I should try setTimeout long time.
Thanks for your kindly help! You are cool.

Damn, guys. These web3 changes are driving me in unexpected issues. The previous version did not have this problems

It seems weird cause I also encountered this issue when I switched from Infura to self hosted Geth node.

Still facing the same issue.

Was this page helpful?
0 / 5 - 0 ratings