最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Smart contract method is not a function in web3 - Stack Overflow

programmeradmin0浏览0评论

I am trying to follow an older tutorial on web3, but am getting errors that I believe are due Solidity being updated. I have the following code shown below

var express = require("express"),
    Web3 = require("web3"),
    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"));
}

web3.eth.defaultAccount = web3.eth.accounts[0];

//define contract variable using ABI from compiled Remix tab.
var myContract = new web3.eth.Contract([abi_data]);

myContract.options.address = 'contract_address';

myContract.methods.totalSupply(function(err,res){
    if(!err){
        console.log(res);
    } else {
        console.log(err);
    }
})

where abi_data is my contract's abi data, contract_address is my contract's actual address in the Roptsen test network, and where totalSupply() is the method in my solidity smart contract on the Ropsten test network that returns the total supply of the token referenced in the contract. When testing this with node app.js to see if this logs properly, this error is returned...

/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693
    throw errors.InvalidNumberOfParams(args.length, this.method.inputs.length, this.method.name);
    ^

Error: Invalid number of parameters for "totalSupply". Got 1 expected 0!
    at Object.InvalidNumberOfParams (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:32:16)
    at Object._createTxObject (/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693:22)
    at Object.<anonymous> (/home/ubuntu/workspace/client/app.js:290:25)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)

And totalSupply is defined in Soldiity as follows...

function totalSupply() constant returns (uint256 totalSupply){
    return _totalSupply;
}

Using Adam's fix, I still get the following error...

Error: Invalid JSON RPC response: ""
at Object.InvalidResponse (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:42:16)
at XMLHttpRequest.request.onreadystatechange (/home/ubuntu/workspace/node_modules/web3-providers-http/src/index.js:73:32)
at XMLHttpRequestEventTarget.dispatchEvent (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:64:18)
at XMLHttpRequest._setReadyState (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:354:12)
at XMLHttpRequest._onHttpRequestError (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:544:12)
at ClientRequest.<anonymous> (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:414:24)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at Socket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1277:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)

I am trying to follow an older tutorial on web3, but am getting errors that I believe are due Solidity being updated. I have the following code shown below

var express = require("express"),
    Web3 = require("web3"),
    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"));
}

web3.eth.defaultAccount = web3.eth.accounts[0];

//define contract variable using ABI from compiled Remix tab.
var myContract = new web3.eth.Contract([abi_data]);

myContract.options.address = 'contract_address';

myContract.methods.totalSupply(function(err,res){
    if(!err){
        console.log(res);
    } else {
        console.log(err);
    }
})

where abi_data is my contract's abi data, contract_address is my contract's actual address in the Roptsen test network, and where totalSupply() is the method in my solidity smart contract on the Ropsten test network that returns the total supply of the token referenced in the contract. When testing this with node app.js to see if this logs properly, this error is returned...

/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693
    throw errors.InvalidNumberOfParams(args.length, this.method.inputs.length, this.method.name);
    ^

Error: Invalid number of parameters for "totalSupply". Got 1 expected 0!
    at Object.InvalidNumberOfParams (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:32:16)
    at Object._createTxObject (/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693:22)
    at Object.<anonymous> (/home/ubuntu/workspace/client/app.js:290:25)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)

And totalSupply is defined in Soldiity as follows...

function totalSupply() constant returns (uint256 totalSupply){
    return _totalSupply;
}

Using Adam's fix, I still get the following error...

Error: Invalid JSON RPC response: ""
at Object.InvalidResponse (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:42:16)
at XMLHttpRequest.request.onreadystatechange (/home/ubuntu/workspace/node_modules/web3-providers-http/src/index.js:73:32)
at XMLHttpRequestEventTarget.dispatchEvent (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:64:18)
at XMLHttpRequest._setReadyState (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:354:12)
at XMLHttpRequest._onHttpRequestError (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:544:12)
at ClientRequest.<anonymous> (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:414:24)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at Socket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1277:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
Share Improve this question edited Feb 3, 2018 at 0:09 Bliz asked Jan 31, 2018 at 16:47 BlizBliz 511 gold badge1 silver badge3 bronze badges 3
  • Try myContract.methods.totalSupply. – Adam Kipnis Commented Jan 31, 2018 at 16:53
  • I made this adjustment. I now get the following error Error: Invalid number of parameters for "totalSupply". Got 1 expected 0! I updated the question to reflect this. – Bliz Commented Jan 31, 2018 at 18:12
  • This stuff is changing so fast each tutorial only has a shelf life of a few months before problems creep in – Paula Livingstone Commented Oct 23, 2022 at 16:45
Add a comment  | 

4 Answers 4

Reset to default 6

Take a closer look at the web3 1.0 documentation for calling methods (it's very different from the 0.2x API). To call a contract method, you need to first create the method object using contractInstance.methods.methodName() replacing "methodName" with the method in the contract you want to call. You also need to pass in the parameters for the contract function to this method (the callback does not get passed in here). With the method object, you can then use either the call method (for constant functions) or send (for transactions). totalSupply should be a constant function, so your code should be:

myContract.methods.totalSupply().call(function(err,res){
    if(!err){
        console.log(res);
    } else {
        console.log(err);
    }
);

Or you can use the returned Promise instead of passing in the callback:

myContract.methods.totalSupply().call().then(function(res){
    console.log(res);
}).catch(function(err) {
    console.log(err);
});

Sending transactions is similar, but uses an event emitter for receiving the transaction hash, receipt, etc.

For anyone else struggling, try to check whether your ABI json actually includes the method you are trying to call. It could have been that you copied the ABI for the wrong contract as Remix would by default list the first contract in the default template rather than your newly created contract.

This is a new language for me so my error came when I copied the abi into my variable and it pasted an extra set of "[]" so it looked something like:

const abi = [[...]];

If I'm correct, it should be:

const abi = [...];

with only single set of the most outer square brackets. This is probably only a mistake for someone like myself who is still learning the syntax of this language.

There is actually a simple fix to this:

I was using express and web3 together but web3 1.0.0-beta was the issue. You just have to install a stable version such as 0.19.0 or 0.20.0

npm install web3@^0.19.0 --save

Then it will work.

发布评论

评论列表(0)

  1. 暂无评论