When I encode my abi data in web3js or web3.py for a uni v2 trade I get the following:
0x
00000000000000000000000000000000000000000000000000000000000000a0
0000000000000000000000000000000000000000000000000000000064c809a5
00000000000000000000000000000000000000000000000ad78ebc5ac6200000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000010693794192ce3e67394d6aa
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d
000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
But when I use remix to encode/decode I get an extra 32 byte field added. Solidity will not decode on chain without this field.
0x
0000000000000000000000000000000000000000000000000000000000000020 // this guy
00000000000000000000000000000000000000000000000000000000000000a0
0000000000000000000000000000000000000000000000000000000064c809a5
00000000000000000000000000000000000000000000000ad78ebc5ac6200000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000010693794192ce3e67394d6aa
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d
000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
What is this extra 32 byte field 0000000000000000000000000000000000000000000000000000000000000020
and why is it only added with an encode through solidity? I'm assuming it has something to do with the array of addresses but I'm not sure what.
Thanks!
Code to reproduce ethers/web3js
const ethers = require('ethers'); // "ethers": "^5.7.2",
const Web3 = require("web3"); // "web3": "^1.8.1"
const web3 = new Web3();
let types = [ 'address[]', 'uint256', 'uint256', 'uint256', 'uint160' ]
let values = [
[
"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
],
1690831269,
ethers.BigNumber.from("200000000000000000000"),
0,
ethers.BigNumber.from("5078959830289813231285622442"),
];
web3.eth.abi.encodeParameters(types, values)
Code to reproduce solidity
pragma solidity 0.8.18;
contract Test {
struct ExactInputSingleParams {
address[] path;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function encode() external pure returns (bytes memory) {
address[] memory addresses = new address[](2);
addresses[0] = 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d;
addresses[1] = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
ExactInputSingleParams memory _params = ExactInputSingleParams({
path: addresses,
deadline: 1690831269,
amountIn: 200000000000000000000,
amountOutMinimum: 0,
sqrtPriceLimitX96: 5078959830289813231285622442
});
return abi.encode(_params);
}
function decode(bytes memory message) external pure returns(uint256) {
ExactInputSingleParams memory _params = abi.decode(
message,
(ExactInputSingleParams)
);
return _params.deadline;
}
}