Chi*_*ipe 5 transactions ethereum
如果我得到这样的输入
0x18cbafe5000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
如果我有这样的函数签名,"swapExactTokensForETH(uint256,uint256,address[],address,uint256)"
是否可以在没有 ABI 的情况下进行解码?
我从签名中知道类型
"types": [
"uint256",
"uint256",
"address[]",
"address",
"uint256"
],
Run Code Online (Sandbox Code Playgroud)
但解码后看起来像这样:
"inputs": [
"1885c663d0035bce2",
"f5666f7fdaa626",
[
"9813037ee2218799597d83d4a5b6f3b6778218d9",
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
],
"c0be713b48822271b362e9fac00479f5134172e8",
"60e93fa9"
]
Run Code Online (Sandbox Code Playgroud)
其中索引0是uint256,索引1是下一个uint256,索引2是address[],索引3是地址,索引4是uint256
那么有什么逻辑可以知道索引2中的数组是从交易输入末尾的两个地址中拉取的。
如果可能的话,我尝试不需要 ABI 来解码输入
我知道我可以像这样分割交易的输入:
['000000000000000000000000000000000000000000000001885c663d0035bce2','000000000000000000000000000000000000000000000000000f566 6f7fdaa626', '0000000000000000000000000000000000000000000000000000000000000a0', '000000000000000000000000c0be713b48822271b362e 9fac00479f5134172e8','0000000000000000000000000000000000000000000000000000000060e93fa9','0000000000000000000000000000000000000 000000000000000000000000002', '0000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9', '000000000000000000000000c02 aaa39b223fe8d0a0e5c4f27ead9083c756cc2']
该数组中的最后两个是上面输入数组中索引 2 显示的地址。但是函数签名的顺序是第三,我怎么知道它是从最后的输入中拉出来的呢?
这是 abi 发挥作用的地方,就像使用 web3 进行解码一样?或者没有abi 也可以解码吗?
是否可以在没有 ABI 的情况下解码?
仅当您至少具有函数签名或定义时。
如果你不知道有哪些输入类型,你就无法判断这个输入是否是
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003666f6f0000000000000000000000000000000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
是一个字符串foo
或三个连续的无符号整数(十进制值):
32346332796673528066027243215619882264990369332300865266851730502456685210107904如果您知道输入数据类型,一个简单的方法(无需实际的 ABI JSON)是使用 web3decodeParameters函数。
const data = web3.eth.abi.decodeParameters(
["uint256", "uint256", "address[]", "address", "uint256"],
"000000000000000000000000000000000000000000000001885c663d0035bce200000000000000000000000000000000000000000000000000f5666f7fdaa62600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000c0be713b48822271b362e9fac00479f5134172e80000000000000000000000000000000000000000000000000000000060e93fa900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009813037ee2218799597d83d4a5b6f3b6778218d9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
);
Run Code Online (Sandbox Code Playgroud)
回报
Result {
'0': '28272584972907691234',
'1': '69073998366549542',
'2': [
'0x9813037ee2218799597d83D4a5B6F3b6778218d9',
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
],
'3': '0xc0Be713B48822271b362e9Fac00479f5134172e8',
'4': '1625898921',
__length__: 5
}
Run Code Online (Sandbox Code Playgroud)
这些值已经编码为各自的数据类型 - 例如整数是十进制的(而不是您问题中的十六进制)。它们以字符串形式返回只是因为 JS 在处理大整数时有时会遇到舍入错误。
请注意,前 4 个字节(8 个十六进制字符;在您的情况下18cbafe5)是函数选择器 - 而不是参数值。所以你不要将它传递给函数decodeParameters()。
该数组中的最后两个是上面输入数组中索引 2 显示的地址。但是函数签名的顺序是第三,我怎么知道它是从最后的输入中拉出来的呢?
这就是 ABI 的工作原理。如果您有动态类型,则其实际槽包含指向值的实际位置的偏移量(包括前置长度)。在您的情况下,这是 160 (十六进制a0)字节。
所有动态值都在有效负载的末尾排序,前面加上该部分的长度。
在您的情况下,2该数组中有 2 个值,其余的是数组的实际值。
您可以在文档中找到有关排序的更多信息:https://docs.soliditylang.org/en/v0.8.7/abi-spec.html#formal-specification-of-the-encoding
| 归档时间: |
|
| 查看次数: |
7796 次 |
| 最近记录: |