tronprotocol / tronweb

Javascript API Library for interacting with the TRON Network
MIT License
423 stars 271 forks source link

`abi.decodeParams` fails to decode, value exceeds width (20 bytes) #540

Open sharifzadesina opened 1 month ago

sharifzadesina commented 1 month ago

Hello,

7e45745226085334dd91ce42a3beb76dcb3b6f164f5ec558a49abac8ba1885a0 this is a valid USDT transaction, but when I am trying to parse contract method data, I am getting the below error:

value exceeds width (20 bytes) (operation="toBeHex", fault="overflow", value=95646081903120159615838154932596471023938966366884, code=NUMERIC_FAULT, version=6.13.1)
    at makeError (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/utils/errors.ts:691:21)
    at assert (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/utils/errors.ts:715:25)
    at toBeHex (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/utils/maths.ts:194:9)
    at AddressCoder.decode (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/abi/coders/address.ts:34:27)
    at <anonymous> (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/abi/coders/array.ts:108:31)
    at Array.forEach (<anonymous>)
    at unpack (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/abi/coders/array.ts:86:12)
    at TupleCoder.decode (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/abi/coders/tuple.ts:66:16)
    at AbiCoder.decode (/home/sina/Projects/pouch-js/node_modules/ethers/src.ts/abi/abi-coder.ts:209:22)
    at decodeParams (/home/sina/Projects/pouch-js/test2.ts:22:19) {
  code: 'NUMERIC_FAULT',
  operation: 'toBeHex',
  fault: 'overflow',
  value: 95646081903120159615838154932596471023938966366884n,
  shortMessage: 'value exceeds width (20 bytes)',
  baseType: 'address',
  type: 'address'
}

You can try:

import { utils as tronUtils } from "tronweb";

tronUtils.abi.decodeParams([], ["address", "uint256"], 'a9059cbb0000000000000000000000417196a564824974842dd03cde3e3020af201baaa400000000000000000000000000000000000000000000000000000000001e8480', true);

It will first throw TypeError: arg.substr is not a function but the value of arg is the above object I provided.

I am using the latest version, 6.0.0-beta.4. this bug existed in beta.3 also, so it is not because of Ethers.js version update.

sharifzadesina commented 1 month ago

This can be related to ethers-io/ethers.js#4446 and ethers-io/ethers.js#4427.

sharifzadesina commented 1 month ago

Web3 is able to decode the data:

import { Web3 } from "web3";

const web3 = new Web3('https://mainnet.infura.io/v3/xxx');

var d = web3.eth.abi.decodeParameters(['address', 'uint256'], '0x0000000000000000000000417196a564824974842dd03cde3e3020af201baaa400000000000000000000000000000000000000000000000000000000001e8480');

console.log(d);

but Ethers.js fails:

import { AbiCoder } from 'ethers';

const abiCoder = new AbiCoder();

var d = abiCoder.decode(["address", "uint256"], "0x0000000000000000000000417196a564824974842dd03cde3e3020af201baaa400000000000000000000000000000000000000000000000000000000001e8480");

console.log(d);
start940315 commented 1 month ago

Since Tron address is not the same as ethereum, you have to change the address data in the method data. For your scenario, you need to change the 41 to 00 and then it will decode the right result. See more at here

sharifzadesina commented 1 month ago

@start940315 what you said has nothing to do with the issue. this issue is for some special transactions where the Ethers package fails to decode ABI. please test using the sample codes I've provided. even the decodeAbi provided by this package also fails, while it works for other transactions. so you either need to update decodeAbi provided by the package (to replace 41 with 00), OR use web3 instead of ethers.

start940315 commented 1 month ago

Your abi contains address-type data. Currently, TronWeb doesn't convert the Tron addresses to Ethereum addresses. You have to replace it yourself. As for using web3, it seems that it is not in our development roadmap.

sharifzadesina commented 1 month ago

@start940315 So you provide decodeAbi method, but that method doesn't support "address" type data?! So what is the point of having decodeAbi while it is not going to support the "address" type?!

start940315 commented 1 month ago

It supports address type, but you must change the data a little. The decoded result of the address type is Tron address.

sharifzadesina commented 1 month ago

@start940315 I understand, I thought the decodeAbi util is supposed to do the required changes.

norbubb commented 1 month ago

Same error