5

using web3 javascript library how do you get the current value of a public property. e.g.

contract MyContract {
    address public owner;
    ...
}

Here's a snippet of the abi:

[{
  "constant": true,
  "inputs": [],
  "name": "owner",
  "outputs": [
    {
      "name": "",
      "type": "address"
    }
  ],
  "payable": false,
  "type": "function"
},
...
]

I've tried several methods, but to no avail:

    var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    var contract = new web3.eth.Contract([...], "0x1234...");

    // These don't work:
    var owner = contract.owner;
    console.log(owner); // "undefined"

    contract.methods.owner.call(function(error, result) {
        console.log("This doesn't get called");
    });

    contract.methods.owner(function(error, result) {
        // Displays an error to console:
        // Error: Invalid number of parameters for "owner". Got 1 expected 0!
    });

    var x = contract.methods.owner();
    console.log(x); // Displays the contract object below:

The last line displays the contract object. Here's a snippet:

{ call: { [Function: bound _executeMethod] request: [Function: bound 
_executeMethod] },
  send: { [Function: bound _executeMethod] request: [Function: bound 
_executeMethod] },
  encodeABI: [Function: bound _encodeMethodABI],
  estimateGas: [Function: bound _executeMethod],
  _method:
  { constant: true,
     inputs: [],
     name: 'owner',
     outputs: [ [Object] ],
     payable: false,
     type: 'function',
     signature: '0x8da5cb5b' },
  _parent:
   Contract {
       // etc...

EDIT: Using version 1.0.0-beta.4 (later packages don't install properly with dependency lerna). Docs: http://web3js.readthedocs.io/en/1.0/web3-eth-contract.html

7

According to the Web3 API documentation, the way to retrieve a contract instance and to call a method is:

1. Contract Definition

var MyContract = web3.eth.contract(abi);

2. Get the instance of the contract at the address

var myContractInstance = MyContract .at('0x**********');

3. Execute a call

var owner = myContractInstance .owner.call();

Full code:

var abi = [
    {
      "constant": true,
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "name": "",
          "type": "address"
        }
      ],
      "payable": false,
      "type": "function"
    },
    {
      "inputs": [],
      "payable": false,
      "type": "constructor"
    }
  ];


var MyContract = web3.eth.contract(abi);

// initiate contract for an address
var myContractInstance = MyContract .at('0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4');

// call constant function (synchronous way)
var owner = myContractInstance .owner.call();

console.log("owner="+owner);

Works fine:

owner=0x13a0674c16f6a5789bff26188c63422a764d9a39

  • Sorry, I should have specified the version of web3 that I'm using: 1.0.0-beta.4 web3js.readthedocs.io/en/1.0/web3-eth-contract.html for a new contract you do this: new web3.eth.Contract(jsonInterface[, address][, options]) – mkaj Jul 23 '17 at 20:05
  • 1
    Haven't touched yet. But according to the documentation, it should be myContract.methods.owner().call().then(console.log); – Greg Jeanmart Jul 23 '17 at 20:41
  • I have not played with 1.0 yet either, but please remember it is BETA software and not well tested in production at this point. – Thomas Clowes Jul 23 '17 at 21:58
  • myContract.methods.owner().call().then(console.log); displays an error message: TypeError: Cannot read property 'length' of undefined and myContract.methods.owner.call().then(console.log); displays error message: TypeError: myContract.methods.owner.call(...).then is not a function I'll assume the beta isn't ready for this yet. – mkaj Jul 24 '17 at 0:04
  • Thanks for the detailed answer! :) Could you add how to do it in the asynchronous way? – shamisen Apr 21 '18 at 1:54
4

This code is correct: myContract.methods.owner().call().then(console.log); The error is a bug, and will be fixed in the next version.

  • Yes, myContract.methods.owner().call().then(console.log); it's working like a charm ! – Chirag Maliwal May 16 '18 at 9:12
  • Can you explain how the returned value (from the call function) can be shown on a HTML page? Your answer only logs the return value in the console which is hidden from the users. – Ay. Jan 15 at 18:19
1

I found a workaround after upgrading to version 1.0.0-beta.11 and modifing the installed package here:

\node_modules\web3\packages\web3-eth-contract\src\index.js

change line 356 from:

if(json.inputs.length !== args.length) {

to:

if(args && json.inputs.length !== args.length) {

and changed my code above to:

var result = myContract.methods.owner.call().call((error, result) => {
    console.log(result);
});

You have to call `call() twice. meh.

  • I was going to log an issue on github, but found a similar one here: github.com/ethereum/web3.js/issues/948 – mkaj Jul 26 '17 at 5:13
  • Issue will be resolved in version 1.0.0-beta.12 – mkaj Jul 26 '17 at 19:47
  • bug still exists on 1.0.0-beta.18 – bitsanity Aug 29 '17 at 23:01
  • the bug still exists even today (version 1.0.0-beta.30) unfortunately... mkaj said that you have to call call() twice meh but it looks like you can actually use myContract.methods.owner().call() .. for me it works like a charm.. you can actually use methods.methodName(arg).call({from:fromAccount}) – Andy B. Mar 25 '18 at 23:19
0

@mkaj if you are using version 1.x firstly you have to set the address properties as

var MyContract = web3.eth.contract(abi);
myContract.options.address = '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4';

var output = myContract.methods.owner.call((error, result) => {
    console.log(result); 
});

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.