在没有给定 ABI 的情况下解码 eth_call 响应

问题描述 投票:0回答:1

我的任务是从部署在 Polygon 网络上的合约中调用视图函数,仅使用函数的十六进制选择器。我通过 eth_call 做到了这一点。我得到的回复如下:

0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000cf43616c6c207468697320636f6e747261637420776974682066756e6374696f6e207369676e6174757265202730786464633234626533272070726f766964696e672061202775696e743235362720617267756d656e74206f662076616c75653a20323237383137393730393238363831363932383837323536343431383433323338313336303133363830363431383135313932383334363635383039363531373931303039303331383138383720416c736f2073656e6420736f6d65207765693a203432303030303030303030300000000000000000000000000000000000

考虑到没有可用的 ABI,我如何解码此响应?

ethereum polygon ethers.js
1个回答
0
投票

来自 Solidity 文档

编码不是自我描述的,因此需要一个模式才能解码。

因此不可能 100% 确定地解码此 ABI。然而,鉴于上下文我们能够对 ABI 架构做出有根据的猜测

为了说明这一点,将响应分成 32 字节段(提供偏移标签以便于阅读):

000: 0000000000000000000000000000000000000000000000000000000000000020
020: 00000000000000000000000000000000000000000000000000000000000000cf
040: 43616c6c207468697320636f6e747261637420776974682066756e6374696f6e
060: 207369676e6174757265202730786464633234626533272070726f766964696e
080: 672061202775696e743235362720617267756d656e74206f662076616c75653a
0a0: 2032323738313739373039323836383136393238383732353634343138343332
0c0: 3338313336303133363830363431383135313932383334363635383039363531
0e0: 373931303039303331383138383720416c736f2073656e6420736f6d65207765
100: 693a203432303030303030303030300000000000000000000000000000000000

查看以这种方式呈现的数据,该 ABI 几乎可以肯定编码了

string
类型:

  • 000
    似乎是指向槽
    020
    的指针。
  • 020
    似乎包含数据的长度 (
    0xcf == 207
    )。
  • 从槽
    040
    开始到槽
    100
    中间结束的207个字节在UTF-8解码时是清晰的英文。

您可以像这样在 JavaScript 中解码 207 个字节:

const str = '43616c6c207468697320636f6e747261637420776974682066756e6374696f6e207369676e6174757265202730786464633234626533272070726f766964696e672061202775696e743235362720617267756d656e74206f662076616c75653a20323237383137393730393238363831363932383837323536343431383433323338313336303133363830363431383135313932383334363635383039363531373931303039303331383138383720416c736f2073656e6420736f6d65207765693a20343230303030303030303030';
new TextDecoder().decode(Uint8Array.from(str.match(/.{2}/g), v => parseInt(v, 16)));

上述代码的结果:

“使用函数签名“0xddc24be3”调用此合约,提供“uint256”参数值:22781797092868169288725644184323813601368064181519283466580965179100903181887同时发送一些wei:4 20000000000”

© www.soinside.com 2019 - 2024. All rights reserved.