摘要:对照 ethereum.org 中文 ERC-20「事件」与 Etherscan Logs:读懂 Transfer/Approval 的 topics、spender 与 value;与站内 web3.py balanceOf、Revoke、交易回执文区分。
打开一笔代币转账或授权交易,Logs 里密密麻麻的 topics 和 data 是什么?本文只讲怎么在区块浏览器里读懂 ERC-20 的 Transfer / Approval 事件:topic0 签名、from/to 或 owner/spender、value。不写 ABI 调 balanceOf(见 web3.py 读 ERC-20),不讲 Revoke 操作步骤(见 代币授权怎么撤销),也不展开整份交易回执字段总览(见 交易回执怎么读)。
一、官方:ERC-20 两个核心事件
ethereum.org 中文「ERC-20 代币标准」在「事件」一节写明标准至少定义两个事件:
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
indexed 的参数会出现在 topics 里(便于按地址过滤);未 indexed 的 _value 落在 data。本场实拍该页「事件」小节(简体中文)。

二、在 Etherscan 读 Transfer:topics 与 value
任开一笔主网 USDT 转账,进入交易详情 → Logs。本场示例哈希 0x9d82a2a5…4bcbf5(以你打开的页为准,会随新交易变化):
- topics[0]:事件签名哈希,Transfer 固定为
0xddf252ad…b3ef(即keccak256("Transfer(address,address,uint256)"))。 - topics[1] / [2]:indexed 的 from / to(地址左填充到 32 字节;页上常可切 Dec 看 0x 地址)。
- data:uint256 value。本场页上 Dec 显示 3000000000000;USDT
decimals=6时人类可读约 3,000,000(以页为准)。

| 字段 | ERC-20 含义 | 本场示例怎么认 |
|---|---|---|
| topics[0] | 事件签名(Transfer) | 对照 0xddf252ad…b3ef |
| topics[1] | from(转出地址) | 页上 Dec 成 0x83C4…627e |
| topics[2] | to(转入地址) | 页上 Dec 成 0xE8C1…9596 |
| data / value | 转账数量(最小单位) | 再除以 decimals 才是钱包里看到的数 |
三、读 Approval:owner、spender、授权额度
Approve / increaseAllowance 等会打出 Approval 事件。本场示例哈希 0x52e2f3c0…667c33 的 Logs 中可见:
- topics[0]:Approval 签名
0x8c5be1e5…b925。 - topics[1] owner:授权人;topics[2] spender:被授权合约/地址(常是 DEX 路由、质押合约)。
- data value:授权额度(最小单位)。本场同笔交易内可见多条 Approval(例如 value=113722 与 30000000),说明一笔交易可改多处 allowance——数字会变,以你打开的页为准。

若要撤销某 spender 的额度,属于另一套操作流程,见 代币授权怎么撤销;本文只帮你在浏览器里认出 Approval 长什么样。
四、对照:Read Contract 里的只读字段
Token 页 → Contract → Read Contract 能看到 name、decimals、totalSupply、以及 USDT 合约上常见的 allowed(等价于 allowance(owner,spender))等只读入口。它回答的是「当前状态是多少」,而 Logs 回答的是「这笔交易刚发出了什么事件」。二者互补,不要混成同一步。

五、本机核对 topic0:cast sig-event
不必信页面标签,可自己算签名哈希。本场 Foundry 1.8.5:
cast sig-event "Transfer(address,address,uint256)"
# → 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
cast sig-event "Approval(address,address,uint256)"
# → 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
再把公开 RPC 的 eth_getLogs 结果里的 topic0 与上式对照,即可确认浏览器解码没有指错事件。本场用公开节点抽过 USDT Transfer 样本(块号与哈希会变)。

六、怎么和站内其它文衔接
用 Python 调 balanceOf / decimals 换算见 web3.py 文;本文停在浏览器 Logs。
认出资人/spender 后,若要清额度走 Revoke 文;不要在陌生站点乱连钱包。
整份 receipt 字段总览见交易回执文;本文只放大 ERC-20 两类事件。
- 复制 Tx 哈希 → 浏览器打开 → 切到 Logs。
- 先看 topics[0] 是 Transfer 还是 Approval。
- 再读 indexed 地址与 data 里的 value;value 记得除以 decimals。
- 需要钱包看链上记录时,可用欧易 Web3(创建步骤可填 CHENGXULVTU);买少量 ETH 付 Gas 可在 币安 或 欧易——本场只读公开页与本地 cast,不要求你发交易。
相关阅读
- web3.py 读 ERC-20:balanceOf、decimals 换算与裸 eth_call 核对
- 代币授权怎么撤销:Revoke 步骤
- 以太坊交易回执怎么读:Status、Logs 与 Cumulative Gas 字段核对
- 欧易 Web3 钱包怎么用:创建、导入与转账基础图解
说明:配图为 2026-10-13 ethereum.org 中文文档、Etherscan 公开交易 Logs / Read Contract,以及本机 Foundry cast 真实输出。示例哈希、value、块号会随链上状态变化。本文不构成投资建议。
