解码没有abi的交易输入?
decoding input of a transaction without abi?
如果我得到这样的输入
0x18cbafe5000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
如果我有这样的函数签名"swapExactTokensForETH(uint256,uint256,address[],address,uint256)"
没有 ABI 可以解码吗?
我从签名中知道类型
"types": [
"uint256",
"uint256",
"address[]",
"address",
"uint256"
],
但是解码后看起来像这样:
"inputs": [
"1885c663d0035bce2",
"f5666f7fdaa626",
[
"9813037ee2218799597d83d4a5b6f3b6778218d9",
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
],
"c0be713b48822271b362e9fac00479f5134172e8",
"60e93fa9"
]
其中索引0是uint256,索引1是下一个uint256,索引2是地址[],索引3是地址,索引4是uint256
那么有什么逻辑可以知道索引2中的数组是从事务输入末尾的两个地址中拉取的。
如果可能的话,我尽量不需要 ABI 像这样解码输入
我知道我可以像这样拆分交易的输入:
[
'000000000000000000000000000000000000000000000001885c663d0035bce2', '00000000000000000000000000000000000000000000000000f5666f7fdaa626', '00000000000000000000000000000000000000000000000000000000000000a0', '000000000000000000000000c0be713b48822271b362e9fac00479f5134172e8', '0000000000000000000000000000000000000000000000000000000060e93fa9', '0000000000000000000000000000000000000000000000000000000000000002', '0000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9', '000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
]
该数组中的最后两个是上面输入数组中索引 2 显示的地址。但是按照函数签名的顺序是第三,我怎么知道是从最后面的输入中拉出来的呢?
这就是 abi 发挥作用的地方,就像使用 web3 解码一样吗?或者这是否可以在没有 abi 的情况下解码?
is it possible to decode without the ABI?
仅当您至少拥有函数签名或定义时。
如果你不知道有哪些输入类型,你将无法判断这个输入是否正确
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003666f6f0000000000000000000000000000000000000000000000000000000000
是一个字符串foo
或三个连续的无符号整数(十进制值):
32
3
46332796673528066027243215619882264990369332300865266851730502456685210107904
如果您知道输入数据类型,一个简单的方法(没有实际的 ABI JSON)是使用 web3 decodeParameters 函数。
const data = web3.eth.abi.decodeParameters(
["uint256", "uint256", "address[]", "address", "uint256"],
"000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
);
returns
Result {
'0': '28272584972907691234',
'1': '69073998366549542',
'2': [
'0x9813037ee2218799597d83D4a5B6F3b6778218d9',
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
],
'3': '0xc0Be713B48822271b362e9Fac00479f5134172e8',
'4': '1625898921',
__length__: 5
}
这些值已经编码为它们各自的数据类型 - 例如整数是十进制的(而不是你问题中的十六进制)。它们作为字符串返回只是因为 JS 在处理大整数时有时 运行 会出现舍入错误。
请注意前 4 个字节(8 个十六进制字符;在您的情况下 18cbafe5
)是函数选择器 - 而不是参数值。所以你不要将它传递给 decodeParameters()
函数。
Where the last two in that array from this are the addresses that show up for index 2 in the inputs array above. But in the order of the function signature is third, how do I know that it is pulled from the input from the end?
这就是 ABI 的工作原理。如果你有一个动态类型,它的实际插槽包含指向值实际位置的偏移量(包括前置长度)。在你的情况下是 160 (hexa0
) 字节。
所有动态值都排在有效负载的末尾,前面加上部分的长度。
在您的例子中,2
表示此数组中有 2 个值,其余为数组的实际值。
您可以在文档中找到有关排序的更多信息:https://docs.soliditylang.org/en/v0.8.7/abi-spec.html#formal-specification-of-the-encoding
如果我得到这样的输入
0x18cbafe5000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
如果我有这样的函数签名"swapExactTokensForETH(uint256,uint256,address[],address,uint256)"
没有 ABI 可以解码吗?
我从签名中知道类型
"types": [
"uint256",
"uint256",
"address[]",
"address",
"uint256"
],
但是解码后看起来像这样:
"inputs": [
"1885c663d0035bce2",
"f5666f7fdaa626",
[
"9813037ee2218799597d83d4a5b6f3b6778218d9",
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
],
"c0be713b48822271b362e9fac00479f5134172e8",
"60e93fa9"
]
其中索引0是uint256,索引1是下一个uint256,索引2是地址[],索引3是地址,索引4是uint256
那么有什么逻辑可以知道索引2中的数组是从事务输入末尾的两个地址中拉取的。
如果可能的话,我尽量不需要 ABI 像这样解码输入
我知道我可以像这样拆分交易的输入:
[ '000000000000000000000000000000000000000000000001885c663d0035bce2', '00000000000000000000000000000000000000000000000000f5666f7fdaa626', '00000000000000000000000000000000000000000000000000000000000000a0', '000000000000000000000000c0be713b48822271b362e9fac00479f5134172e8', '0000000000000000000000000000000000000000000000000000000060e93fa9', '0000000000000000000000000000000000000000000000000000000000000002', '0000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9', '000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' ]
该数组中的最后两个是上面输入数组中索引 2 显示的地址。但是按照函数签名的顺序是第三,我怎么知道是从最后面的输入中拉出来的呢?
这就是 abi 发挥作用的地方,就像使用 web3 解码一样吗?或者这是否可以在没有 abi 的情况下解码?
is it possible to decode without the ABI?
仅当您至少拥有函数签名或定义时。
如果你不知道有哪些输入类型,你将无法判断这个输入是否正确
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003666f6f0000000000000000000000000000000000000000000000000000000000
是一个字符串foo
或三个连续的无符号整数(十进制值):
32
3
46332796673528066027243215619882264990369332300865266851730502456685210107904
如果您知道输入数据类型,一个简单的方法(没有实际的 ABI JSON)是使用 web3 decodeParameters 函数。
const data = web3.eth.abi.decodeParameters(
["uint256", "uint256", "address[]", "address", "uint256"],
"000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
);
returns
Result {
'0': '28272584972907691234',
'1': '69073998366549542',
'2': [
'0x9813037ee2218799597d83D4a5B6F3b6778218d9',
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
],
'3': '0xc0Be713B48822271b362e9Fac00479f5134172e8',
'4': '1625898921',
__length__: 5
}
这些值已经编码为它们各自的数据类型 - 例如整数是十进制的(而不是你问题中的十六进制)。它们作为字符串返回只是因为 JS 在处理大整数时有时 运行 会出现舍入错误。
请注意前 4 个字节(8 个十六进制字符;在您的情况下 18cbafe5
)是函数选择器 - 而不是参数值。所以你不要将它传递给 decodeParameters()
函数。
Where the last two in that array from this are the addresses that show up for index 2 in the inputs array above. But in the order of the function signature is third, how do I know that it is pulled from the input from the end?
这就是 ABI 的工作原理。如果你有一个动态类型,它的实际插槽包含指向值实际位置的偏移量(包括前置长度)。在你的情况下是 160 (hexa0
) 字节。
所有动态值都排在有效负载的末尾,前面加上部分的长度。
在您的例子中,2
表示此数组中有 2 个值,其余为数组的实际值。
您可以在文档中找到有关排序的更多信息:https://docs.soliditylang.org/en/v0.8.7/abi-spec.html#formal-specification-of-the-encoding