web3 / web3.js

Collection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.
https://web3js.org/
Other
19.19k stars 4.92k forks source link

TypeError: token.methods.balanceOf(...).call(...).on is not a function #1089

Closed dzarezenko closed 6 years ago

dzarezenko commented 6 years ago

Hi,

I am trying to get ERC20 tokens balance on some address with web3.js lib but received this error:

Unhandled rejection Error: Couldn't decode uint256 from ABI: 0x
    at SolidityTypeUInt.formatOutputUInt (...\node_modules\web3-eth-abi\src\formatters.js:176:15)
    at SolidityTypeUInt.SolidityType.decode (...\node_modules\web3-eth-abi\src\type.js:252:17)
    at ...\node_modules\web3-eth-abi\src\index.js:327:49
    at Array.forEach (native)
    at ABICoder.decodeParameters (...\node_modules\web3-eth-abi\src\index.js:326:13)
    at Contract._decodeMethodReturn (...\node_modules\web3-eth-contract\src\index.js:451:22)
    at Method.outputFormatter (...\node_modules\web3-eth-contract\src\index.js:798:46)
    at Method.formatOutput (...\node_modules\web3-core-method\src\index.js:162:54)
    at sendTxCallback (...\node_modules\web3-core-method\src\index.js:453:33)
    at ...\node_modules\web3-core-requestmanager\src\index.js:144:9
    at XMLHttpRequest.request.onreadystatechange (...\node_modules\web3-providers-http\src\index.js:64:13)
    at XMLHttpRequestEventTarget.dispatchEvent (...\node_modules\xhr2\lib\xhr2.js:64:18)
    at XMLHttpRequest._setReadyState (...\node_modules\xhr2\lib\xhr2.js:354:12)
    at XMLHttpRequest._onHttpResponseEnd (...\node_modules\xhr2\lib\xhr2.js:509:12)
    at IncomingMessage.<anonymous> (...\node_modules\xhr2\lib\xhr2.js:469:24)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)

My code:

var getTokenBalance = function(address) {
    var token = new web3.eth.Contract(contract_data.abi, contract_data.TOKEN_CONTRACT_ADDRESS);
    token.methods.balanceOf(address).call().then(function (result) {
        console.log(result);
    });
}
sponnet commented 6 years ago

I also received this bug - upgrading to ^1.0.0-beta.22 fixed this for me.

thackerronak commented 6 years ago

Same issue facing in "web3": "^1.0.0-beta.23", this.contractObj.methods.balanceOf(address).call(function (err, wieBalance) {}

Error: Couldn't decode uint256 from ABI: 0x
    at SolidityTypeUInt.formatOutputUInt [as _outputFormatter] (formatters.js:162)
    at SolidityTypeUInt.webpackJsonp.../../../../web3-eth-abi/src/type.js.SolidityType.decode (type.js:252)
    at index.js:327
    at Array.forEach (<anonymous>)
    at ABICoder.webpackJsonp.../../../../web3-eth-abi/src/index.js.ABICoder.decodeParameters (index.js:326)
    at Contract.webpackJsonp.../../../../web3-eth-contract/src/index.js.Contract._decodeMethodReturn (index.js:451)
    at Method.outputFormatter (index.js:798)
    at Method.webpackJsonp.../../../../web3-core-method/src/index.js.Method.formatOutput (index.js:162)
    at sendTxCallback (index.js:453)
    at index.js:144
    at XMLHttpRequest.request.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (index.js:64)
    at XMLHttpRequest.wrapFn (zone.js:1166)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
    at ZoneTask.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:499)
    at invokeTask (zone.js:1540)
    at XMLHttpRequest.globalZoneAwareCallback (zone.js:1566)
thackerronak commented 6 years ago

also tried with ^1.0.0-beta.22 but issue remains same

jacobsimon commented 6 years ago

Hey all, I was also receiving this bug and it turned out to be a slight difference in the ABI of my contract and the one I was using in my application. Not sure if there's another cause, but I would make sure that you're using the most recent version of your contract's ABI.

skiral commented 6 years ago

We are getting the same issue, only on Ropsten testnet

guptapriyank commented 6 years ago

no luck yet, anybody have a solution, please list

dzarezenko commented 6 years ago

I have resolved this with enclosing functionality into Promise:

_getTokenBalance : function (address) {
        var _this = this;
        return new Promise(function(resolve, reject) {
            var tokenBalance = 0;
            _this.contract.methods.balanceOf(address).call().then(function (result) {
                var tokensWei = result;
                console.log("Tokens Wei: " + tokensWei);
                _this.contract.methods.decimals().call().then(function (result) {
                    var decimals = result;
                    console.log("Token decimals: " + decimals);

                    tokenBalance = parseFloat(tokensWei) / Math.pow(10, decimals);
                    console.log("Token balance: " + tokenBalance);

                    resolve(tokenBalance);
                });
            });
        });
    }

and call it like:

this._getTokenBalance(address).then(function(tokenBalance) {
    // ...
});
jdkanani commented 6 years ago

For now, you can use -

web3.eth.call({
    to: address,
    data: contract.methods.balanceOf(address).encodeABI()
}).then(balance => {})
lionello commented 6 years ago

I disagree with the fix that was introduced in 15ffd55. This should not be handled by such low-level conversion code.

frozeman commented 6 years ago

So to understand that right, the contract returns 0x? If so then this is certainly not a good fix, and i changed it in develop to make sure 0x will fail.

frozeman commented 6 years ago

@lionello you are right. Its actually wrong behaviour. So if it would return 0 the value would look like:

> web3.eth.call({to: '0x6d72f4097b093518114ac0ba54d7c9fd73eecc05', data: '0x39f6ca500000000000000000000000000000000000000000000000000000000000000000'})
"0x0000000000000000000000000000000000000000000000000000000000000000"

Though if it throws, it looks like:

> web3.eth.call({to: '0x4597b8c3b40d96dc0365ced9dc9b56b81247120d', data: '0x39f6ca500000000000000000000000000000000000000000000000000000000000000000'})
"0x"

Therefore the raw value is also empty if it failed. This is a problem of how the token contract is build and not one of web3.js

So you need to catch the errors of the call, as it throws inside the contract, rather then returning anything expected.

lionello commented 6 years ago

@frozeman Yeah, that's more like it.

I'd really like to see some test that warrants the !param.rawValue clauses you've added. For the current tests, those clauses don't appear to changes the behavior at all, suggesting that they might be superfluous.

frozeman commented 6 years ago

I added the !param.rawValue only for int, uint and bool, as here we don't want it to be accidentally interpreted as 0, or false

mobilesite commented 6 years ago

same error in version 1.0-beta.28. How to solve it?

MRHarrison commented 6 years ago

same error in version 1.0-beta.29. Anybody figure this out yet?

dgrant069 commented 6 years ago

I was getting this with beta.26. I figured out that my deployed and compiled contracts were out of sync and that I was calling a function in my contract that didn't exist in the old contract. In other words, I made a change to my contract, compiled and deployed. I hadn't updated the address to my deployed contract (which I used to created instances of another contract that in my web ui was something like "add new "). Once I updated the address, refreshed, and created a new instance through my browser, it worked.

faizan-ali commented 6 years ago

Started getting this error today in beta.29 after I updated my locally deployed Smart Contract with a constructor (it previously had none) Calling any constant function causes the error, other functions work fine. Would very much appreciate some insight. Updating to beta.30 did not help

jamboj commented 6 years ago

Same here... calling a const contract method with web3js 1.0.0-beta.30 intermittently triggers:

Error: Couldn't decode uint256 from ABI: 0x
    at SolidityTypeUInt.formatOutputUInt [as _outputFormatter] (/Users/tu/node_modules/web3-eth-abi/src/formatters.js:174:15)
    at SolidityTypeUInt.SolidityType.decode (/Users/tu/node_modules/web3-eth-abi/src/type.js:252:17)
    at /Users/tu/node_modules/web3-eth-abi/src/index.js:327:49
    at Array.forEach (<anonymous>)
    at ABICoder.decodeParameters (/Users/tu/node_modules/web3-eth-abi/src/index.js:326:13)
    at Contract._decodeMethodReturn (/Users/tu/node_modules/web3-eth-contract/src/index.js:459:22)
    at Method.outputFormatter (/Users/tu/node_modules/web3-eth-contract/src/index.js:811:46)
    at Method.formatOutput (/Users/tu/node_modules/web3-core-method/src/index.js:162:54)
    at sendTxCallback (/Users/tu/node_modules/web3-core-method/src/index.js:453:33)
    at Object.<anonymous> (/Users/tu/node_modules/web3-core-requestmanager/src/index.js:144:9)
    at /Users/tu/node_modules/web3-providers-ws/src/index.js:76:44
    at Array.forEach (<anonymous>)
    at W3CWebSocket.WebsocketProvider.connection.onmessage (/Users/tu/node_modules/web3-providers-ws/src/index.js:53:36)
    at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/tu/node_modules/yaeti/lib/EventTarget.js:107:17)
    at W3CWebSocket.onMessage (/Users/tu/node_modules/websocket/lib/W3CWebSocket.js:234:14)
    at WebSocketConnection.<anonymous> (/Users/tu/node_modules/websocket/lib/W3CWebSocket.js:205:19)
    at WebSocketConnection.emit (events.js:160:13)
    at WebSocketConnection.processFrame (/Users/tu/node_modules/websocket/lib/WebSocketConnection.js:547:26)
    at /Users/tu/node_modules/websocket/lib/WebSocketConnection.js:321:40
    at process._tickCallback (internal/process/next_tick.js:150:11)
TrejGun commented 6 years ago

same here

akucheruk-vareger commented 6 years ago

same here

srameshr commented 6 years ago

This still remains :(

haydenadams commented 6 years ago

Did this never get fixed? Still getting it in beta 33...

mustafakemal16 commented 6 years ago

same here! Latest version: 1.0.0-beta.33

VulgarnyKarlson commented 6 years ago

same here! Latest version: 1.0.0-beta.33

akucheruk-vareger commented 6 years ago

So, I have fixed this and number of other things with just better ethereum js lib https://github.com/ethers-io/ethers.js

sponnet commented 6 years ago

@jamboj Error: Couldn't decode uint256 from ABI: 0x This is not a problem in web3js - it happens when the contractAddress is wrong, or the bytecode of the contract does not implement the ABI you provide.

Example :

 const web3 = new Web3(new Web3.providers.WebsocketProvider("wss://ropsten.infura.io/ws"));
 const contractInstance = new web3.eth.Contract(abi, contractAddress);
 contractInstance.methods.yourMethod().call().then((res) => { ... });

Double check your contractAddress and the abi

dacarley commented 6 years ago

That appears to be an incorrect statement. I have a token contract that works fine for most calls to balanceOf, but sometimes, I receive “0x” as the result, rather than “0x0000000000000000000000000000000000000000000000000000000000000000”. It’s inconsistent in it’s behavior, and has nothing at all to do with the ABI - this is the RAW value coming back over the RPC connection.

On March 29, 2018 at 11:10:35 AM, Stefaan Ponnet (notifications@github.com) wrote:

@jamboj https://github.com/jamboj Error: Couldn't decode uint256 from ABI: 0x -> This is not a problem in web3js - it happens when the contractAddress is wrong, or the bytecode of the contract does not implement the ABI you provide.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ethereum/web3.js/issues/1089#issuecomment-377323913, or mute the thread https://github.com/notifications/unsubscribe-auth/AA60g1ffgKEvWWmknhcQteT4JLlj6jd_ks5tjSOZgaJpZM4PsL_n .

akucheruk-vareger commented 6 years ago

No, this issue isn’t depend on abi or address. I have every 10 seconds call that just read a balance, and in ~5-10% I’ve got this error.

sponnet commented 6 years ago

Let me rephrase : providing a non-matching contract / ABI throws the same error as above , so that could be something you want to check.

I'll try to reproduce the error you describe - and see if I can come up with something. Thanks for pointing that out.

GoodBoy962 commented 6 years ago

same here

noprom commented 6 years ago

version 1.0.0-beta.33 still has this problem. Anyone has already solved this problem?

ArjunBhuptani commented 6 years ago

Still having this problem here as well

yzhang1994 commented 6 years ago

Has this problem - turns out my metamask was on a different network (mainnet), where the contract was not deployed. Fixed after switching back to ropsten.

frozeman commented 6 years ago

@dacarley @sponnet I would like to get to the bottom of this. It doesn't look like its a problem of web3.js, in fact it should error on a wrong output. Maybe this problem lies withing geth, or its an out of gas issue. More input would be welcome.

RobinBlaesing commented 6 years ago

Using web3 1.0 and MetaMask. Simple call of a getter function with

var MyContract = new web3.eth.Contract(abi, address);
MyContract.methods.myFunction().call().then(console.log);

Same issue.

sponnet commented 6 years ago

@frozeman , my findings up to now

Using a local nodeJS script ( not in a browser )

In a browser

I'll try to look if I can isolate or reproduce the issue using the Metamask provider.

Slals commented 6 years ago

TL;DR : I got this issue because of the provider I ran.

In case it can help anyone on this issue.

I got the error Error: Couldn't decode uint256 from ABI: 0x, everything was correctly setup : good ABI, good contract address.

I'm using geth to run my private blockchain in order to test.

My issue was because I didn't start any miner, the network was responding but it didn't return the expected response, it returned something like "0x", thus the error. Remix doesn't seem to be bothered much about this format so Remix is not really helping.

I think the error is because of the provider in 100% of cases, the origin of the issue can be multiple : no miner, bad contract address, ABI not corresponding to the deployed contract, etc.

Maybe Web3 should let the user handle this issue, I wasn't able to handle/catch this error.

davidmoradi commented 6 years ago

I had the same problem, upgrading to 1.0.0-beta.34 from 1.0.0-beta.33 fixed it for me.

haydenadams commented 6 years ago

@Slaals can you expand on

I think the error is because of the provider in 100% of cases

I am using infura and am not running my own node.

Slals commented 6 years ago

@haydenadams Infura is retuning you an empty response for some reasons (most probably, must investigate more on that). This error could be raised for some reasons I'm not aware of.

I don't know how you can fix this since you have no control on Infura, Make sure your ABI is the good one and you call the good contract address on the good provider URL.

I had the issue because I didn't correctly setup my private provider using Geth.

quantumproducer commented 6 years ago

@Slaals can you explain? I'm running geth, but no miner. I didn't think we needed a from: address to call contracts with.

Slals commented 6 years ago

@quantumproducer I didn't go deeper about this issue, I just found why I had this one in the first place. AFAIK you have to run a miner in order to make this work.

When you run geth make sure you open the console; once you're in the console, simply type miner.start(), it will start to mine (sync and mine if it's desync). After that you shouldn't have this error again.

quantumproducer commented 6 years ago

@Slaals I don't want to mine, I just want to use geth to read from transactions. I tried miner.start() then running my code, same issue.

Aniket-Engg commented 6 years ago

facing this problem in web3 version 1.0.0-beta.34 with metamask & Ropsten Does anyone have a proper solution?

k06a commented 6 years ago

@Aniket-Engg this problem means you try to call the method of a contract which is not existing on this address.

drewstaylor commented 6 years ago

I have this issue on Kovan at the moment and I can confirm I am using the correct ABI. I have recompiled it so many times, and I always get the same result. I also deployed my contract in web3 in the same closure and I still can't call the method.

drewstaylor commented 6 years ago

After some review, I seem to have been having an issue similar to @Slaals I didn't realize my Kovan node had stopped silently syncing. Although I could see the transaction on Etherscan, I didn't have the block yet.

barakman commented 6 years ago

Same problem when working with Parity (on a local host).

However, this seems to be due to an incorrect usage of Web3, and I was able to resolve it as follows:

First, I added these two helper functions:

async function call(transaction) {
    let success = await web3.eth.personal.unlockAccount(OWNER_ADDRESS, OWNER_PASSWORD);
    let gas = await transaction.estimateGas({from: OWNER_ADDRESS, gasPrice: GAS_PRICE});
    return await transaction.call({from: OWNER_ADDRESS, gasPrice: GAS_PRICE, gas: gas});
}

async function send(transaction) {
    let success = await web3.eth.personal.unlockAccount(OWNER_ADDRESS, OWNER_PASSWORD);
    let gas = await transaction.estimateGas({from: OWNER_ADDRESS, gasPrice: GAS_PRICE});
    return await transaction.send({from: OWNER_ADDRESS, gasPrice: GAS_PRICE, gas: gas});
}

Then, in order to invoke an onchain-stateless function, I use:

await call(myContract.methods.myMethod(put your args here if needed));

And in order to invoke an onchain-stateful function, I use:

await send(myContract.methods.myMethod(put your args here if needed));

Of course, in the helper functions, you may get rid of the unlockAccount part and / or the estimateGas part if they are not necessary for your system behavior requirements.

fritzmatias commented 6 years ago

i found the same problem, but was because the address of the contract was wrong. So, for me the real issue is "an invalid contract can be mapped to an object without throw an exception". Then, when you try to call the method the exception is throwed.

    "web3": "^1.0.0-beta.34",
    "web3-core-requestmanager": "^1.0.0-beta.34",
    "web3-eth": "^1.0.0-beta.34",
    "web3-eth-contract": "^1.0.0-beta.34"
ramxis commented 6 years ago

I am having the same issue, My dapp is using infura ropsten node as geth provider, Its a Nodejs app, and I have triple checked my Contract ABI and address, If i downgrade to Web3 0.20 i do not see this error with the same provider, and setup. I only encounter this problem if i use web 1.0