eth_getLogs如何精确过滤事件? 图 1
eth_getLogs如何精确过滤事件? · 图 1

eth_getLogs的topics是按位置匹配的矩阵:外层位置之间是AND,同一位置的嵌套数组是OR,null表示该位置不限。理解这三条,才能构造既不漏也不过宽的事件查询。

本文专门处理过滤器、分段和重组回滚;已有事件解码页继续承担ABI基础。

一个位置化topics例子

假设topic0是事件签名,topic1是indexed用户地址,topic2是indexed资产。过滤器:

{
  "fromBlock":"0x1200000",
  "toBlock":"0x1200fff",
  "address":["0x合约A","0x合约B"],
  "topics":["0x事件签名",["0x用户A","0x用户B"],null]
}

含义是:合约A或B,topic0必须为该事件,topic1可以是用户A或B,topic2任意。未被indexed的参数只在data里,不能放进topics筛选。blockHash用于单个区块查询,使用它时不要再与fromBlock/toBlock混用。

大窗口应按固定区块段查询。每段保存起止区块、端点、返回日志的blockHash与logIndex;新区块确认后推进游标。若链重组导致已存blockHash变化,从共同祖先撤销旧日志再重放,不能只追加。

分段查询实操清单

  1. 固定链、合约地址、事件ABI和topic0
  2. 先用小区间验证topics位置与地址填充
  3. 按服务商上限分段查询并设置重试
  4. 以blockHash、transactionHash、logIndex建立幂等键
  5. 只在安全确认深度后固化,重组时回滚受影响区间

一手规范给出的结论

过滤器字段

eth_getLogs过滤器可以指定区块范围或单个blockHash,并按一个或多个address与位置化topics组合筛选日志。

topics位置矩阵

topics数组中的null表示该位置不限制,嵌套数组表示同一位置的多个可选值;事件参数是否indexed决定能否进入topics过滤。

分段查询

大范围查询可能触发节点限制或超时,且链重组会改变未最终确认日志;可靠索引应分段、保存区块哈希并处理回滚。

过滤器字段如何做双盲复核

作者先依照“固定链、合约地址、事件ABI和topic0”收集一份不含结论的证据包,内容包括目标对象、网络或版本、完整返回、查询时点和使用的工具。复核者收到材料后,按“先用小区间验证topics位置与地址填充”自行解释topics位置矩阵。双方最后才交换结果;如果结论不同,优先比较原始字段与口径,不能用页面颜色或多数意见裁决。

接着建立反例包。反例一只模拟“把多个topic位置写成OR导致范围过宽”,反例二只模拟“用空结果代表事件从未发生,忽略超时或服务商截断”。每个反例必须说明预期拒绝点和实际拒绝点。程序若把错误输入修正后继续执行,应把修正动作完整展示;静默修正会让用户误以为原输入有效,因此仍判为不通过。

为了覆盖重组回滚,还要在状态改变前后各保存一次“按服务商上限分段查询并设置重试”的结果。两份证据必须有独立时间和上下文,不能只留最终快照。若变化由缓存、节点或索引造成,报告应注明观察层级,而不是直接断言链上事实改变。

上线页面把原始证据、解释规则和结果状态拆开呈现。原始栏不做舍入和自然语言改写;解释栏写清公式、版本或字段映射;结果栏允许已确认、被否定和待核验。触发“只保存区块号,不保存blockHash,无法识别重组”时,按“以blockHash、transactionHash、logIndex建立幂等键”重新取证,禁止继续自动处理。

三个容易造成错误结论的做法

  • 不要这样做:把多个topic位置写成OR导致范围过宽
  • 不要这样做:用空结果代表事件从未发生,忽略超时或服务商截断
  • 不要这样做:只保存区块号,不保存blockHash,无法识别重组

来源、增量与风险边界

  1. Ethereum Execution APIs:正式接口、字段与规范语义。
  2. Ethereum JSON-RPC:实现路径、兼容性或安全边界。

本文资料读取于2026-07-20。不同服务商的最大范围和返回条数不一致,无法取得完整窗口时不得把空结果写成事件从未发生。

站内相邻主题可继续阅读:事件解码确认与重组。RPC服务商对窗口和条数限制不同。查询不完整或发生重组时,页面必须显示待同步,不能把空数组当成最终事实。