术语表 /挖矿与共识
默克尔区块
又称 Merkle block、部分默克尔分支。
- 默克尔区块是什么?
- 默克尔区块是轻钱包请求过滤后的区块内容时收到的回复:80字节的区块头,加上刚好足以证明哪些交易匹配的哈希值。
规定于 BIP-37。
BIP37 让钱包向节点提交一个过滤器,并只接收匹配的内容,同时附有一份证明,表明没有任何内容是伪造的。这一设计在隐私和负载方面都失败了:Bitcoin Core 在2019年11月发布的0.19.0版本中默认关闭了该功能。如果您使用的是现代轻钱包,它几乎可以肯定使用的是紧凑区块过滤器。
运作方式
**状态:**BIP37 的布隆过滤,以及为其提供服务的 merkleblock 消息,因隐私和拒绝服务方面的原因,已在2019年11月发布的 Bitcoin Core 0.19.0中默认禁用。BIP157 和 BIP158 中规定的紧凑区块过滤器取代了它,Bitcoin Core 自2021年1月发布的0.21.0版本起已能向对等节点提供这类过滤器。
默克尔区块是一份证明,而不是摘要。它的结构由四部分组成:区块头、区块中的交易总数、一份有序的哈希列表,以及一个紧凑的标志位字段。这些标志描述了对区块默克尔树的一次深度优先遍历,告诉接收方钱包是继续深入某个分支,还是取列表中的下一个哈希来代表其下的全部内容。钱包重放这一遍历过程,得出一个根,并将其与所收到区块头中的根进行比较。
这一比较正是关键所在。恶意的对等节点只要不提及某些交易,就可以向您隐瞒它们,任何过滤协议都无法阻止这一点。但它无法凭空捏造一笔您从未收到的交易,因为伪造的哈希无法重构出一个与带有真实工作量证明的区块头相匹配的根。
请求一个默克尔区块分为两步。钱包先用 filterload 消息上传一个过滤器,然后使用过滤区块的清单类型(而不是普通类型)来请求区块。默克尔区块先返回,随后是完整的匹配交易,以单独的消息发送。一个包含2,000笔交易、只有一笔匹配的区块,对钱包来说只需一个区块头、约十几个哈希和一笔交易,而不是1 MB 或更多的数据。
在哪里会遇到它
默克尔区块属于一代已基本退出使用的移动钱包。
BitcoinJ 库使它们得以普及,基于该库构建的安卓钱包在2010年代的大部分时间里都以这种方式同步。仍在使用这些应用旧版本的用户,可能还在发出 filterload 消息,却悄悄地找不到愿意响应的对等节点,因为提供服务需要运营者手动重新开启 peerbloomfilters。
取代它们的方案颠倒了请求的方向。使用紧凑区块过滤器时,节点为每个区块发布一个小型过滤器来描述该区块的内容,钱包下载这些过滤器,在本地判断哪些区块值得关注,再获取这些区块的完整内容。钱包的任何地址信息都不会离开设备。lnd 的 Neutrino 后端以及基于它构建的移动闪电网络钱包采用的就是这一模式。
隐私方面的失败值得直说,因为这正是改用新方案的原因。Arthur Gervais 及其合著者在2014年发表的研究表明,为使用布隆过滤的客户端提供服务的节点,可以恢复该客户端的绝大部分地址,而用同一个过滤器请求两个区块会泄露更多信息。本应隐藏钱包的误报填充并没有起到隐藏作用。
默克尔区块 vs 布隆过滤器
布隆过滤器是钱包上传的内容;默克尔区块是返回的内容。过滤器是对某人关注的地址和 outpoint 的一种概率性、有损的描述,存放在提供服务的节点上。默克尔区块是针对某一特定区块的确定性证明,存在于回复之中。二者是作为一对被弃用的,但隐私问题只出在过滤器上。默克尔证明本身依然可靠,这也是紧凑区块过滤器保留了证明思路,却舍弃了向陌生人说明自己持有什么这一环节的原因。