Web3.js: eth.abi.decodeParameters() not decoding uint256[n][] nested array

Created on 24 Oct 2017  路  3Comments  路  Source: ChainSafe/web3.js

I cannot get web3.eth.abi.decodeParameters() to work when one of the types is uint256[5][], i.e. a dynamic array of static arrays of uint256's. As a simple example:

var web3EthAbi = require('web3-eth-abi');

var addressArray = [
  [
    '0x9B305E6C0d77a6Eca5296Efd818e65b2a7458179',
    '0xBC63aCdfafA94bd4D8C2Bb7A8552281f107242c0',
    '0xbdbc010651becC4709bae06327a51f97dCd4989B',
    '0x858140dA0FD83836932DFF6D69Cc2151D724776C',
    '0x539EfE69bCDd21a83eFD9122571a64CC25e0282b'
  ],
  [
    '0x9B305E6C0d77a6Eca5296Efd818e65b2a7458179',
    '0xBC63aCdfafA94bd4D8C2Bb7A8552281f107242c0',
    '0xbdbc010651becC4709bae06327a51f97dCd4989B',
    '0x858140dA0FD83836932DFF6D69Cc2151D724776C',
    '0x539EfE69bCDd21a83eFD9122571a64CC25e0282b'
  ]
];

var uint256Array = [
  [25, 50, 60, 8000000, 10],
  [12, 50, 60, 1222222, 100],
  [25, 21, 60, 9000000, 1000],
  [12, 50, 60, 1444444, 10000],
  [25, 50, 60, 7000000, 100000001]
];

var encodedComposite = web3EthAbi.encodeParameters(['address[5][]', 'uint256[5][]'], [addressArray, uint256Array]);

var decodedComposite = web3EthAbi.decodeParameters(['address[5][]', 'uint256[5][]'], encodedComposite);

console.log(decodedComposite);

which outputs:

Result {
  '0':
   [ [ '0x9B305E6C0d77a6Eca5296Efd818e65b2a7458179',
       '0xBC63aCdfafA94bd4D8C2Bb7A8552281f107242c0',
       '0xbdbc010651becC4709bae06327a51f97dCd4989B',
       '0x858140dA0FD83836932DFF6D69Cc2151D724776C',
       '0x539EfE69bCDd21a83eFD9122571a64CC25e0282b' ],
     [ '0x9B305E6C0d77a6Eca5296Efd818e65b2a7458179',
       '0xBC63aCdfafA94bd4D8C2Bb7A8552281f107242c0',
       '0xbdbc010651becC4709bae06327a51f97dCd4989B',
       '0x858140dA0FD83836932DFF6D69Cc2151D724776C',
       '0x539EfE69bCDd21a83eFD9122571a64CC25e0282b' ] ],
  '1': [],
  __length__: 2 }

I've verified that web3EthAbi.encodeParameter('uint256[5][]', uint256Array) and web3EthAbi.decodeParameter('uint256[5][]', encodedUint256Array) work as intended. I'm having trouble specifically with decodeParameters() when one of the types is uint256[5][].

The above code is a contrived example, but I have a real world use case for this so I'd really appreciate any help on this. I'm trying to decode transaction input data for transactions sent through the 0x Exchange contract, specifically "batch" methods (e.g. batchFillOrders) - see Input Data for https://etherscan.io/tx/0xa1495826e30dbaa49dde788b165304a4cfa1e5ef881dfe6723f71ee84ff97a2f. When I try to decode the input data for that transaction using web3.eth.abi.decodeParameters(), I get the following error message:

Error: Couldn't decode uint256 from ABI: 0x00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fa45c6991a2c3d74ada3a279e21135133ce3da8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000002956356cd2a2bf3202f771f50d3d14a367b48070000000000000000000000000eb71bad396acaa128aeadbc7dbd59ca32263de010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000361a08405e8fd7fff9c0000000000000000000000000000000000000000000000008572e50d6027ff9c000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059dae5d2ac086974d44e92bc94b2a0a72a31320eda281cbd0127a62ee6de30020de6a32a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000d49829b75c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000001701c22aebd65090a07c26948e2c2ccb8d980b649ab1cdabff1a7a3d14babde5b00000000000000000000000000000000000000000000000000000000000000015bb1054d1cfab5b8ef2e7c366a778f1809a3a93ed6634badc4e57ab25205a425
    at SolidityTypeUInt.formatOutputUInt [as _outputFormatter] (/Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/formatters.js:162:15)
    at SolidityTypeUInt.SolidityType.decode (/Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/type.js:252:17)
    at /Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/type.js:234:34
    at SolidityTypeUInt.SolidityType.decode (/Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/type.js:238:11)
    at /Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/type.js:216:34
    at SolidityTypeUInt.SolidityType.decode (/Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/type.js:220:11)
    at /Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/index.js:327:49
    at Array.forEach (<anonymous>)
    at ABICoder.decodeParameters (/Users/user/Documents/data-reader/node_modules/web3-eth-abi/src/index.js:326:13)
    at Object.decodeInput (/Users/user/Documents/data-reader/index.js:38:23)
    at testInput (/Users/user/Documents/data-reader/scratch.js:19:34)
    at <anonymous>

I've tried every ABI decoder on NPM I could find, and then I jumped into the web3js 1.0 beta code directly (https://github.com/ethereum/web3.js/blob/1.0/packages/web3-eth-abi/src/index.js#L309), and I just can't get it to decode. I think there may be an issue in https://github.com/ethereum/web3.js/blob/1.0/packages/web3-eth-abi/src/type.js#L200, and I'm willing to dig in and see what else I can find, but if anyone can point me in the right direction on this I would greatly appreciate it!

bug

Most helpful comment

Have you tried ethers.js?

// You can launch the interactive ethers console after `npm install -g ethers-cli` and typing `ethers`
mainnet> data = '0x00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fa45c6991a2c3d74ada3a279e21135133ce3da8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000002956356cd2a2bf3202f771f50d3d14a367b48070000000000000000000000000eb71bad396acaa128aeadbc7dbd59ca32263de010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000361a08405e8fd7fff9c0000000000000000000000000000000000000000000000008572e50d6027ff9c000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059dae5d2ac086974d44e92bc94b2a0a72a31320eda281cbd0127a62ee6de30020de6a32a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000d49829b75c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000001701c22aebd65090a07c26948e2c2ccb8d980b649ab1cdabff1a7a3d14babde5b00000000000000000000000000000000000000000000000000000000000000015bb1054d1cfab5b8ef2e7c366a778f1809a3a93ed6634badc4e57ab25205a425'
mainnet> Interface.decodeParams( [ 'uint256[5]' ] , data)
Result {
  '0': 
   [ BigNumber { _bn: <BN: e0> },
     BigNumber { _bn: <BN: 1a0> },
     BigNumber { _bn: <BN: 280> },
     BigNumber { _bn: <BN: 1> },
     BigNumber { _bn: <BN: 2c0> } ],
  length: 1 }

All 3 comments

Have you tried ethers.js?

// You can launch the interactive ethers console after `npm install -g ethers-cli` and typing `ethers`
mainnet> data = '0x00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000fa45c6991a2c3d74ada3a279e21135133ce3da8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000002956356cd2a2bf3202f771f50d3d14a367b48070000000000000000000000000eb71bad396acaa128aeadbc7dbd59ca32263de010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000361a08405e8fd7fff9c0000000000000000000000000000000000000000000000008572e50d6027ff9c000000000000000000000000000000000000000000000001bc16d674ec80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059dae5d2ac086974d44e92bc94b2a0a72a31320eda281cbd0127a62ee6de30020de6a32a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000d49829b75c0000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000001701c22aebd65090a07c26948e2c2ccb8d980b649ab1cdabff1a7a3d14babde5b00000000000000000000000000000000000000000000000000000000000000015bb1054d1cfab5b8ef2e7c366a778f1809a3a93ed6634badc4e57ab25205a425'
mainnet> Interface.decodeParams( [ 'uint256[5]' ] , data)
Result {
  '0': 
   [ BigNumber { _bn: <BN: e0> },
     BigNumber { _bn: <BN: 1a0> },
     BigNumber { _bn: <BN: 280> },
     BigNumber { _bn: <BN: 1> },
     BigNumber { _bn: <BN: 2c0> } ],
  length: 1 }

@ricmoo yes, I tried it out last night, and it decoded no problem! It's also great that I can just install the ethers-contracts package to access Interface.

ethers.js looks really interesting. I'm going to look into using it for the transaction processing I'm doing for the project I'm working on.

@ragnu Will be solved with the new ABICoder (v1.0.0-beta.36) please write a comment here after the release if this issue still occurs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mishell-trickster picture mishell-trickster  路  3Comments

oktapodia picture oktapodia  路  3Comments

imthatcarlos picture imthatcarlos  路  3Comments

zamoore picture zamoore  路  3Comments

xpepermint picture xpepermint  路  3Comments