2

I trying to use nodejs with web3.js to do the full process of compile,delpoly and method call.After read the api here. I found the contract-methods.

myContractReturned.call().getCount();

But when I use it like this, I always got following error:

myContractReturned.call().getCount();
                   ^


TypeError: myContractReturned.call is not a function
    at Object.<anonymous> (/Users/admin/develop/blockchain_workspace/truffle3/main/web3InAction.js:70:20)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:420:7)
    at startup (bootstrap_node.js:139:9)
    at bootstrap_node.js:535:3

After search the internet,I found here that web3.js with javascript seems good.Did anybody have used nodejs with web3.js,any help will appreciate.Environment are as following:

$ node -v
v7.2.0
$ testrpc
EthereumJS TestRPC v3.0.3

Solidity source here:

pragma solidity ^0.4.0;

contract Calc{
  //simple storage
  uint count;

  //change state
  function add(uint a, uint b) returns(uint){
    count++;
    return a + b;
  }

  //no state change
  function getCount() constant returns (uint){
    return count;
  }
}

Full code as following:

let Web3 = require('web3');
let web3;

if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
} else {
    // set the provider you want from Web3.providers
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

let from = web3.eth.accounts[0];

let source = "pragma solidity ^0.4.0;contract Calc{ uint count;  function add(uint a, uint b) returns(uint){    count++;    return a + b;  }  function getCount() returns (uint){    return count;  }}";

let calcCompiled = web3.eth.compile.solidity(source);

console.log(calcCompiled);
console.log("ABI definition:");
console.log(calcCompiled["info"]["abiDefinition"]);

let abiDefinition = calcCompiled["info"]["abiDefinition"];
let calcContract = web3.eth.contract(abiDefinition);

let deployCode = calcCompiled["code"];

let deployeAddr = web3.eth.accounts[0];

let myContractReturned = calcContract.new({
    data: deployCode,
    from: deployeAddr
}, function(err, myContract) {
    if (!err) {

        if (!myContract.address) {
            console.log("contract deploy transaction hash: " + myContract.transactionHash) 

        } else {
            console.log("contract deploy address: " + myContract.address) 
        }
    }
});


console.log("returned deployed didn't have address now: " + myContractReturned.address);

//nodeJS?
myContractReturned.call().getCount();
  • please add your solidity in a formatted separate file and show accordingly, otherwise it's hard to read. – Validity Labs - Sebastian Apr 2 '17 at 13:52
  • Thank you for your comment,sorry for that. I have add the solidity source file. – hh3755 Apr 2 '17 at 14:16
2

A few things:

  1. Your function getCount should be constant (function getCount() constant returns (uint) should be constant. Otherwise

    a) you pay for gas and

    b) since you anyway don't change any state, this doesn't even make sense

    c) in web3.js you get a transaction hash back when calling a non-constant function and not a return value, I don't think you want that.

  2. You don't need call. You invoke a smart contract function call via myContractReturned.getCount(function(error, result) { console.log('result: ' + result + , error: ' + error); } ); as described

  3. You need to place this inside the callback handler function(err, myContract) { and check if you got an address. spoiler alert: the callback handler is being called twice: first time when you got a txHash, second time when your contract get mined! Check the example in the doc and basically check that you got an address. Only then proceed to interacting with the contract.

  • Hi, @Sebastian, just now I add the constant to the getCount(), but still got the error of myContractReturned.getCount is not a function. Before that, I have print the return object, there is a call() method here.But I don't known how can I use it. any way, thank you for your answer. – hh3755 Apr 2 '17 at 14:22
  • I edited my answer, you have issues with the double callback upon contract deployment. Just in case you're wondering: Yes, I also think thats a design flaw and this will hopefully be fixed in web3.js release 1.0 – Validity Labs - Sebastian Apr 2 '17 at 14:52
  • Yep,@Sebastian,you are right,I should use the contract method in the function callback.I was misleaded by the api which focused on the address to be set.I didn't even known the contract method is to be set as well, or maybe any other error. – hh3755 Apr 2 '17 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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