区块头里那枚布隆过滤器想被换掉:EIP-7745 的日志索引树 图 1
区块头里那枚布隆过滤器想被换掉:EIP-7745 的日志索引树 · 图 1

在区块浏览器里按地址过滤事件,或者让工具扫一段区间的日志时,很多查询后端会先翻每个区块头里那枚 2048 位的布隆过滤器,把明显不含目标字段的区块跳过去。它省流量,但天生只会回答“肯定没有”和“可能有”。EIP-7745 想换掉这枚过滤器:用一棵带证明的索引树,让日志查询不仅更快,还能自证答案。布隆过滤器本身的原理可先看 布隆过滤器是什么?区块里快速找交易的捷径

老过滤器卡在哪

提案在动机部分点出要害:布隆过滤器只有在足够稀疏时才有用,而在很长的区块区间里搜日志,现有过滤器基本帮不上忙——你只能逐块问“可能有吗”,然后把候选区块全部拉回来重查。对轻客户端来说这更难受:没有可验证的证明,任何“这个区间里没有你要的事件”的回答都得靠对方节点自觉。

提案的结构:把每条日志编进全局序号

EIP-7745 的做法是从“每个区块一枚独立过滤器”改成“全链一条连续索引”。每条日志事件、每笔交易、每个区块都作为索引条目登记,映射到一个全局线性的序号空间;序号空间按固定长度切成一段段“过滤图”,每张图是 2 的 24 次方宽、2 的 16 次方高的稀疏位图,每张图最多容纳 2 的 16 次方个标记,因此假阳性概率被控制在一个恒定的低水平。每个被检索的值——合约地址、主题、交易哈希、区块哈希——都取 32 字节的哈希后打到图上,查询命中的不再是“可能有”,而是精确的候选位置。这些图再按每 2 的 10 次方张一组组织成“纪元”,配合一棵哈希树,让某条事件在整段历史里的位置可以用默克尔证明高效地取出来。区块头里的 logs_bloom 字段将由一个新的索引根 log_index_root 取代;不关心日志搜索的验证者,只需维护一份有硬上限的小状态就能算出这个根。

成本直觉:为什么旧方案“查得到但查不起”

可以粗算一笔账感受一下:以太坊主网每笔交易动辄留下几条日志,一天七千多个区块层层累积,而布隆过滤器每块只有 2048 位、折 256 字节。想找一个半年前的事件,即便过滤器已把明显不符的区块滤掉,剩下的候选区块仍要整块拉回本地或走接口重查——每块的数据量比那枚 256 字节的过滤器大几个数量级,这就是“过滤器省的是大头里的一小角”的含义。索引树路线把成本曲线倒了过来:先按全局序号直接问图,图上每个标记都带精确位置,验证一头的开销是一小段默克尔证明,而不是成吨的区块原文。当然天下没有免费的午餐——节点为了维护索引要多存一层结构,多花的正是当初为省日志开销而省掉的存储与哈希功夫,提案也正是以“日志应当比写状态便宜”为前提来权衡的。

对用户意味着什么

如果它最终落地,最直接的受益者是事件查询的信任问题:RPC 服务商交回一段 eth_getLogs 式结果时,理论上可以附带你能够离线验证的证明,轻钱包不必再无条件相信服务商说“这段没有你的事件”。相关查询接口的现状见 eth_getLogs如何精确过滤事件?,日志字段本身见 交易回执里的Logs是什么?链上转账“收据”的字段与读法,而今天你依赖的索引后端仍建立在旧机制上,见 轻钱包的后端服务器:它连着谁,哪些信息被验证、哪些只能靠信任

需要冷静的是状态行:按提案仓库的文本,EIP-7745 目前是 Draft(草案),还依赖另一份 SSZ 数据结构提案,没有任何已排期的激活时间表。你在现网浏览器里看到的事件过滤,走的仍是布隆过滤器加索引数据库的老路。

以上内容描述协议机制与查询原理,不构成任何投资建议,也不构成对任何升级排期的预测。