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);
})
});
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);
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";
}
see above
see above
[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]
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
dataparameter. It would help if you shared theImooc.jsonfile for repeatability. It is calling thegetName()function, but since the constructor might have been ignored(?),0xis returned for unset storage (due to default behavior). That is,namewas 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.
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
awaitthe deploy. Everything works fine, but you were doingeth_callbefore the code was actually deployed. You can send aneth_callto an empty address and you will still get0xfor 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.