交易事件数据中的参数顺序错误(智能合约)



我正在查看日志选项卡中的以太坊trx以获取事件详细信息。下面是被调用的函数:

BurnConfirmed (index_topic_1 uint256 nonce, index_topic_2 address requester, uint256 amount, string btcDepositAddress, string btcTxid, uint256 timestamp, bytes32 inputRequestHash)

从描述中,您可以看到inputRequestHash是最后一个参数,而btcTxid位于中间。

但是当你看数据时:

0x000000000000000000000000000000000000000000000000000000746a52880000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000638a1cf7d71eaa8219d43a9ae3659cd0ce3c6d30e4127b810596c00d7c98f6cf717f7177000000000000000000000000000000000000000000000000000000000000002a6263317167656e3833346c73783667397074766c673834333637643865376879663332647630396a617500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004064363634386331373036346561643238633261303230343762656139313732623962346339303333643239343535366533353637303965396137313964363363

解码,你会得到btcTxid而不是inputRequestHash:

print(f"inputRequstHash   : {w3.toText(data[-128:])}")

和输出:

inputRequstHash   : d6648c17064ead28c2a02047bea9172b9b4c9033d294556e356709e9a719d63c

,即btcTxid,您可以在EtherScan网站上看到。我怎么能确定params在他们的位置上?

字符串被视为动态大小的字节数组。所有动态大小的数组至少被分成3个槽(如果数组为空,实际上是2个槽)。

  • 第一个32字节槽是一个指向槽的指针,该槽包含数组的大小
  • 第二个槽包含数组大小
  • 后面接实际值。如果它们不适合一个,它们可以跨越多个插槽。

第一个槽位置始终遵循参数的总体顺序。然后size+值存储在负载的末尾——在固定大小类型之后。

# slot 0, `amount`
000000000000000000000000000000000000000000000000000000746a528800
# slot 1, pointer to location (dec)160 (slot 5) where `btcDepositAddress` size is stored
00000000000000000000000000000000000000000000000000000000000000a0
# slot 2, pointer to location (dec)256 (slot 8) where `btcTxid` size is stored
0000000000000000000000000000000000000000000000000000000000000100
# slot 3, `timestamp`
00000000000000000000000000000000000000000000000000000000638a1cf7
# slot 4, `inputRequestHash`
d71eaa8219d43a9ae3659cd0ce3c6d30e4127b810596c00d7c98f6cf717f7177
# slot 5, size of `btcDepositAddress` == (dec)42
000000000000000000000000000000000000000000000000000000000000002a
# slots 6 and 7, value of `btcDepositAddress`
6263317167656e3833346c73783667397074766c673834333637643865376879
663332647630396a617500000000000000000000000000000000000000000000
# slot 8, size of `btcTxid` == (dec)64
0000000000000000000000000000000000000000000000000000000000000040
# slots 9 and 10, value of `btcTxid`
6436363438633137303634656164323863326130323034376265613931373262
3962346339303333643239343535366533353637303965396137313964363363

文档:https://docs.soliditylang.org/en/latest/abi-spec.html use-of-dynamic-types

我在web3py中找不到任何解码事件日志的功能,但至少这里有一个链接到web3js供参考:https://web3js.readthedocs.io/en/v1.8.1/web3-eth-abi.html#decodelog