我的任务是从部署在 Polygon 网络上的合约中调用视图函数,仅使用函数的十六进制选择器。我通过 eth_call 做到了这一点。我得到的回复如下:
0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000cf43616c6c207468697320636f6e747261637420776974682066756e6374696f6e207369676e6174757265202730786464633234626533272070726f766964696e672061202775696e743235362720617267756d656e74206f662076616c75653a20323237383137393730393238363831363932383837323536343431383433323338313336303133363830363431383135313932383334363635383039363531373931303039303331383138383720416c736f2073656e6420736f6d65207765693a203432303030303030303030300000000000000000000000000000000000
考虑到没有可用的 ABI,我如何解码此响应?
来自 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”