Web3.js: Cannot decode receipt log data

Created on 4 Aug 2020  路  14Comments  路  Source: ChainSafe/web3.js

Expected behavior

We were using _decodeEventABI from web3-eth-contract package to decode receipt log data and it had been working for long time. But it's not working as expected for few days! I tried another library abi-decoder which uses web3-eth-abi library under the hood and it has the same problem.

Actual behavior

The decode function produces this error message on decoding data:
(node:55476) UnhandledPromiseRejectionWarning: Error: data out-of-bounds (length=164, offset=192, code=BUFFER_OVERRUN, version=abi/5.0.0-beta.153)
Finally I modified the log data and filled it with zero value except the part I needed and the code workes as before.

It's the code that has modified, if you remove the part that modifies the log.data the error appears

https://github.com/Giveth/feathers-giveth/blob/b164131e588f640a8bd83136ad6c867fb7b6733b/scripts/utils/getHomeTxHash.js#L27-L55

This is the smart contract code and abi: https://rinkeby.etherscan.io/address/0xff9cd5140e79377feb23f6dfaf1f8b558c0fe621#code
And we tried to decode the log data of this transaction: https://rinkeby.etherscan.io/tx/0xa20e3db910d95a5a23692eef523bd6e98152d4759782e6097d3f6eaccf17ff46

Environment

Node v8.17.0
Web3 1.2.11
OS Linux and MacOS

Stale

Most helpful comment

hey sorry this slipped my radar... Thanks for the code snippet. We were going to get a release going this monday, but let me try and squeeze a fix for this before then!

All 14 comments

Any ideas?

It's a sample code to regenerate the error:

const abiDecoder = require('abi-decoder'); // NodeJS
const Web3 = require('web3');

const testABI = [{"constant":true,"inputs":[],"name":"escapeHatchCaller","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"changeOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"mainToken","type":"address"},{"name":"amount","type":"uint256"},{"name":"homeTx","type":"bytes32"},{"name":"data","type":"bytes"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"onTransfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_dac","type":"address"}],"name":"removeOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newOwnerCandidate","type":"address"}],"name":"proposeOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"liquidPledging","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"mainToken","type":"address"},{"name":"tokenName","type":"string"},{"name":"decimals","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"name":"addToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"isTokenEscapable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"escapeHatch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"inverseTokenMapping","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"tokenMapping","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"depositor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newOwnerCandidate","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newEscapeHatchCaller","type":"address"}],"name":"changeHatchEscapeCaller","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"sideToken","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"onApprove","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenFactory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newDepositor","type":"address"}],"name":"changeDepositor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sideToken","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"proxyPayment","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"escapeHatchDestination","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_escapeHatchCaller","type":"address"},{"name":"_escapeHatchDestination","type":"address"},{"name":"_tokenFactory","type":"address"},{"name":"_liquidPledging","type":"address"},{"name":"_depositor","type":"address"},{"name":"mainTokens","type":"address[]"},{"name":"sideTokens","type":"address[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"homeTx","type":"bytes32"},{"indexed":false,"name":"data","type":"bytes"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"mainToken","type":"address"},{"indexed":false,"name":"sideToken","type":"address"}],"name":"TokenAdded","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"}],"name":"EscapeHatchBlackistedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"EscapeHatchCalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"by","type":"address"},{"indexed":true,"name":"to","type":"address"}],"name":"OwnershipRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"OwnershipRemoved","type":"event"}]
abiDecoder.addABI(testABI);

const nodeUrl = 'wss://rinkeby.eth.aragon.network/ws'; // Use any other provider you want
const instantiateWeb3 = url => {
    const provider =
      url && url.startsWith('ws')
        ? new Web3.providers.WebsocketProvider(url, { 
            clientConfig: {
              maxReceivedFrameSize: 1000000000,
              maxReceivedMessageSize: 1000000000,
            },
          })
        : new Web3.providers.HttpProvider(url);
    return new Web3(provider);
  };


const main = async()=> {
    const web3 = await instantiateWeb3(nodeUrl);
    const receipt = await web3.eth.getTransactionReceipt('0x813647d395204e300e70203a9349192e10bb3c9e0ab9041f27a383717c97d0ec');
    const decodedLogs = abiDecoder.decodeLogs(receipt.logs);
    console.log(JSON.stringify(decodedLogs, null, 2));
}

main()

hey sorry this slipped my radar... Thanks for the code snippet. We were going to get a release going this monday, but let me try and squeeze a fix for this before then!

Chainsafe is maintaining web3.js?!?!? You guys are everywhere!

I dont think this is an issue with web3.js, looks like its the decoder. i'll close this for now, please re-open if anything changes

I did a hack to make the decoder work

function eventDecodersFromArtifact(artifact) {
  return artifact.compilerOutput.abi
    .filter(method => method.type === 'event')
    .reduce(
      (decoders, event) => ({
        ...decoders,
        [event.name]: log => {
          const decoder = Contract.prototype._decodeEventABI.bind(event);
          log.data += '0'.repeat(100);
          return decoder(log);
        },
      }),
      {},
    );
}

We use the web3 decoding api, we have used it for years but it has problem for about 10 days. We doubt new version of geth is responsible for such error.

I dont think this is an issue with web3.js, looks like its the decoder. i'll close this for now, please re-open if anything changes

Also fetching past events is another place throws error!

liquidPledging.$contract.getPastEvents('allEvents', {
                fromBlock,
                toBlock: fetchBlockNum,
              })

The error message is:

error: Cannot read property 'Symbol(Symbol.iterator)' of undefined
error: Exit message: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

Also check to make sure you're not reusing a WebSocket provider per this issue as that can cause an expected response element to be undefined.

error: Cannot read property 'Symbol(Symbol.iterator)' of undefined

Not familiar with the notation being used (jquery?) - the er looks like liquidPledging is undefined, or the $ is undefined..

We found the error root cause,
It's related to ethers version 5.x.x maybe and discussed here: https://github.com/ethers-io/ethers.js/issues/992
We had upgraded web3 and ethers version was upgraded from 4.x.x to 5.x.x eventually.

Particularly this comment shows the error concisely:
https://github.com/ethers-io/ethers.js/issues/992#issuecomment-671896346
You may need to downgrade ethers version in web3 project too, or apply some patch on that.

I've added support in ethers 5.0.12 for supporting legacy Solidity 0.4 external event data. I believe web3 depends on the abi package directly, in which case web3 should upgrade to @ethersproject/abi version 5.0.4.

For more details, please see https://github.com/ethers-io/ethers.js/issues/891.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

Was this page helpful?
0 / 5 - 0 ratings