eth_getLogs 区块过滤怎样选? 图 1
eth_getLogs 区块过滤怎样选? · 图 1

使用 eth_getLogs 查询合约事件时,返回空数组不一定表示合约从未发出过事件,报错也不一定表示过滤器字段写错。方法按过滤对象返回匹配日志,过滤器可以涉及地址、topics 和区块参数;查询是否可复现,还取决于如何指定区块以及 RPC 服务允许处理多大的查询。服务端范围或响应限制不能误写成以太坊协议统一数字。

本文解决两个实际问题:要扫描一段区块时怎样保存范围条件;只核对某个特定区块时怎样避免高度引用在后续重组或复查时指向不同区块。现有文章eth_getLogs如何精确过滤事件侧重过滤条件,本篇强调区块范围与 blockHash 查询口径。若需对照另一类按区块固定状态的读取方法,可看eth_getBalance如何查历史余额。

过滤对象里有哪些信息

JSON-RPC 文档将 eth_getLogs 定义为按过滤对象返回匹配的日志。地址条件可用于限定合约来源,topics 用于筛选事件主题及相应位置;区块条件可以采用区块范围,也可以在支持的形式下指定单个区块哈希。返回值是一组与过滤条件匹配的日志,而不是对某个合约所有业务状态的完整快照。

因此,空数组应先解释为“在这次请求条件和节点所提供的数据下,没有返回匹配记录”。要把它解释成更强的业务结论,还得核对地址、topics 的编码、查询区间、目标网络和数据源。过滤条件中的任何一个字段设错,都可能使合法事件被排除。

区块范围适合扫描,代价由服务端决定

用 fromBlock 与 toBlock 表达一个区间,适合索引器按窗口拉取日志。为了便于复查,每次请求应记录起止参数、地址、topics、网络、RPC 来源和响应结果。增量任务还应保存上一次成功处理到的区块位置,明确下一次从哪里继续;若请求失败,保留失败窗口供重试,避免静默跳过。

不要照搬网上某个服务商的最大区块跨度,假定所有节点都一样。供应商可能对范围、返回体积、速率或历史数据作不同限制,而以太坊通用 JSON-RPC 文档并未提供一个所有服务统一适用的区间上限。使用前要检查目标服务的当前说明,并以实际响应验证自身任务的请求规模。

如果返回错误,先保留原始 JSON-RPC error、请求参数和服务端标识,再缩小查询窗口进行诊断。缩小窗口后成功,只能说明较小请求在当时被接受,不能直接证明原因一定是跨度限制;也可能有其它服务策略或瞬时负载因素。本文没有对实时节点做请求测试,因此不报告任何当前可查询的最大范围。

blockHash 适合锁定单个区块

EIP-234 为 eth_getLogs 增加按 blockHash 指定查询区块的方式,使调用方可以把日志查询绑定到某一个具体区块哈希,而不是只写一个可能随链状态变化的区块高度。使用 blockHash 时,不应同时提供 fromBlock 和 toBlock。这样做适用于需要对某个已知区块重新核验日志的场景,但前提是你已经保存了目标区块哈希,并确认节点支持该参数形式。

区块高度更易读,哈希则更明确地指向一个区块实体。若高度对应区块在链发生变化后被替换,重跑同一高度请求可能得到不同区块的内容;按哈希查询有助于保持目标一致。不过,哈希查询也不保证目标节点永久保留对应历史数据。目标节点的历史能力仍需单独核实。

排查“空结果”与“查询失败”

先区分协议层返回:有效响应中 logs 数组为空,和 JSON-RPC 请求错误不是一回事。空数组时,复核 network、地址校验和大小写规范、topics 位置、from/to 是否颠倒以及区块是否符合预期。错误时,核对参数组合,特别是 blockHash 与区块范围字段是否同时出现,并查看服务商关于查询能力的说明。

对于重要事件,保存查询原文与返回值,并对照区块浏览器或另一数据来源做交叉核验。交叉来源也要使用相同网络、地址、topics 和区块目标。如果一个来源有结果、另一个没有,差异可能来自节点历史数据、服务限制、索引状态或重组处理,不能只依据一份空结果删除业务记录。

建议的可复现日志格式

每次调用至少记下:chain/network 标识、endpoint 供应方、地址、topics、fromBlock/toBlock 或 blockHash、请求时间、RPC 错误或日志条数,以及目标区块的哈希和状态信息。对连续扫描任务,还应记录窗口边界与上次确认完成的位置。记录原始参数可以让后续工程师复现查询,而不是从一条“没查到日志”的告警里猜原因。

区块重组会影响按高度引用的历史上下文;某个事件是否已达到业务要求的最终性,需要再结合目标区块状态核验。事实包没有提供实际区块或合约地址,所以本文不声称某个事件存在或不存在,也不提供实时链上数据。

使用边界

基础方法与过滤对象来自 ethereum.org JSON-RPC 文档,区块哈希查询口径来自 EIP-234,JSON-RPC 背景参考 EIP-1474。服务端具体区间和响应限制请查你当前使用的节点服务文档。若日志用于资产核算或合约安全判断,应通过可审计的数据来源重复核验。本文解释的是查询接口,不构成交易或投资建议。