Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode function call #3016

Closed
jgeary opened this issue Aug 8, 2019 · 6 comments
Closed

Decode function call #3016

jgeary opened this issue Aug 8, 2019 · 6 comments

Comments

@jgeary
Copy link

jgeary commented Aug 8, 2019

Description

I cannot figure out how to decode the result of web3.eth.abi.encodeFunctionCall(...) to get the original parameters. Not sure if this is due to lacking functionality or if this is possible but not yet documented.

Expected behavior

After calling

const result = web3.eth.abi.encodeFunctionCall({
    name: 'myMethod',
    type: 'function',
    inputs: [{
        type: 'uint256',
        name: 'myNumber'
    },{
        type: 'string',
        name: 'myString'
    }]
}, ['2345675643', 'Hello!%']);

and getting the result "0x24ee0097000000000000000000000000000000000000000000000000000000008bd02b7b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000748656c6c6f212500000000000000000000000000000000000000000000000000",
I want to call web3.eth.abi.decodeParameters(['bytes4', 'uint256', 'string'], result) to get an array which includes '2345675643' and 'Hello!%'.

Actual behavior

'Uncaught Error: overflow (operation="setValue", fault="overflow", details="Number can only safely store up to 53 bits")'

Versions

  • web3.js: 1.2.1
  • nodejs: 11.15.0
  • browser: Chrome
@nivida
Copy link
Contributor

nivida commented Aug 9, 2019

This error occurs because you're calling the decodeParameters function with the wrong types array. The correct types array would be: ['uint256', 'string'].

Example:

const result = web3.eth.abi.encodeFunctionCall({
    name: 'myMethod',
    type: 'function',
    inputs: [{
        type: 'uint256',
        name: 'myNumber'
    },{
        type: 'string',
        name: 'myString'
    }]
}, ['2345675643', 'Hello!%']);

web3.eth.abi.decodeParameters(['uint256', 'string'], result)

@nivida nivida closed this as completed Aug 9, 2019
@nivida nivida added the support label Aug 9, 2019
@jgeary
Copy link
Author

jgeary commented Aug 13, 2019

@nivida thanks for getting back to me. the code you provided still throws the same exact error.

@sterlu
Copy link

sterlu commented Apr 28, 2021

Hey I just came across a similar error half-asleep last night. I figured it out this morning so I'll share the answer in case someone needs it. @jgeary was encoding a function call and decoding only the argument. Function calls are composed by the function ID (first 4 bytes/8 characters) and then the concatenated parameters.

TLDR just slicing off the first 8 chars from the call data should do what you're looking for.

_web3.eth.abi.decodeParameters(['uint256', 'string'], '0x000000000000000000000000000000000000000000000000000000008bd02b7b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000748656c6c6f212500000000000000000000000000000000000000000000000000')
// > {0: "2345675643", 1: "Hello!%" }

@miljantekic
Copy link

Can confirm that what @sterlu wrote is the way to go. Just slice the function signature out of the transaction input.

@dzimiks
Copy link

dzimiks commented May 11, 2021

Big thanks @sterlu!!! 😎

@defido
Copy link

defido commented Apr 4, 2022

sterlu
@sterlu
I love you with every part of my body right now. This solved this issue for me. MY GOD! Why is this not in the web3js docs!?

For others, this is an ugly solution, but it works: (There is 1000 better ways to remove characters from a string in JS)

let web3 = new Web3('https://bsc-dataseed.binance.org/');
		const a = await web3.eth.getTransaction('0x041e65ab1b3ef192d1e2ae38d167f6293f026b20da980f4987e173c9ffcfc886');
		let find = a.input.slice(2, 10);
		let remove = a.input.replace(find, '');
		const z = await web3.eth.abi.decodeParameters(
			[
				{
					type: 'address',
					name: 'token',
				},
				{
					type: 'uint256',
					name: 'amount',
				},
				{
					type: 'address',
					name: 'receiverAddress',
				},
				{
					type: 'uint256',
					name: 'targetChainId',
				}
			],
			remove <--- The input with the function ID removed.
		);

OPTION 2:

let web3 = new Web3('https://bsc-dataseed.binance.org/');
		const a = await web3.eth.getTransaction('0x041e65ab1b3ef192d1e2ae38d167f6293f026b20da980f4987e173c9ffcfc886');
let remove = `0x${a.input.substr(10)}`; <---- Remove the function ID, add back in the 0x
		const z = await web3.eth.abi.decodeParameters(
			[
				{
					type: 'address',
					name: 'token',
				},
				{
					type: 'uint256',
					name: 'amount',
				},
				{
					type: 'address',
					name: 'receiverAddress',
				},
				{
					type: 'uint256',
					name: 'targetChainId',
				}
			],
			remove
		);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants