You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python解码以太坊交易日志中的Topics?

解决以太坊交易日志topics解码问题

问题原因

你尝试用abi.decode直接解码整个topics列表失败的原因有两个:

  1. topics的第一个元素是ERC20 Transfer事件的签名哈希(对应Transfer(address,address,uint256)的Keccak256哈希),不属于要解码的参数;
  2. abi.decode要求传入连续的字节数据,而非分开的HexBytes数组。

另外要注意:Transfer事件中,from和to是indexed参数(会放在topics里),而value是非indexed参数,存储在日志的data字段中,不在topics内。

正确处理代码

1. 解析转出/转入地址

topics的第2、3个元素是填充了前导0的32字节格式地址,直接截取后20字节并转换为校验和地址:

# 转出地址
from_address = w3.toChecksumAddress(rec[4]["topics"][1].hex()[26:])
# 转入地址
to_address = w3.toChecksumAddress(rec[4]["topics"][2].hex()[26:])

2. 解析转账金额

从日志的data字段解码uint256类型的金额:

from web3 import abi

value = abi.decode(['uint256'], rec[4]["data"])[0]
# 若是ERC20代币,需根据代币小数位数转换为可读单位
# value_in_token = value / (10 ** token_decimals)

完整示例

rec = w3.eth.getTransactionReceipt('0x034...').logs
target_log = rec[4]

# 解析地址
from_addr = w3.toChecksumAddress(target_log["topics"][1].hex()[26:])
to_addr = w3.toChecksumAddress(target_log["topics"][2].hex()[26:])

# 解析金额
transfer_value = abi.decode(['uint256'], target_log["data"])[0]

print(f"转出地址: {from_addr}")
print(f"转入地址: {to_addr}")
print(f"转账金额: {transfer_value}")

内容的提问来源于stack exchange,提问作者Peter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:20:46