轻量级客户端如何使用布隆过滤器

轻量级客户端使用布隆过滤器来过滤从其对等节点接收的交易(以及包含这些交易的区块),仅选择对轻量级客户端感兴趣的交易,而不会准确地揭示感兴趣的地址或密钥。

轻量级客户端将初始化一个布隆过滤器为“空”的状态;在这种状态下,布隆过滤器不会匹配任何模式。然后,轻量级客户端会列出其感兴趣的所有地址、密钥和哈希值。它会通过从其钱包控制的任何未花费交易输出(UTXO)中提取公钥哈希、脚本哈希和交易ID来执行此操作。然后,轻量级客户端将每个值添加到布隆过滤器中,以便如果这些模式存在于交易中,则布隆过滤器会“匹配”,而不会揭示模式本身。

然后,轻量级客户端将向对等节点发送一个filterload消息,其中包含用于连接的布隆过滤器。在对等节点上,布隆过滤器与每个传入交易进行匹配。完整节点会针对所有这些组件检查布隆过滤器,以寻找匹配,包括:

  • 交易ID

  • 每个交易输出脚本中的数据组件(脚本中的每个密钥和哈希)

  • 每个交易输入

  • 每个输入签名数据组件(或见证脚本)

通过检查所有这些组件,布隆过滤器可以用于匹配公钥哈希、脚本、OP_RETURN值、签名中的公钥,或者智能合约或复杂脚本的任何未来组件。

建立了过滤器后,对等节点将对每个交易输出进行布隆过滤器测试。只有与过滤器匹配的交易才会发送给客户端。

作为对客户端的getdata消息的响应,对等节点将发送一个merkleblock消息,其中包含与过滤器匹配的块头以及每个匹配交易的merkle路径(见“默克尔树”第252页)。然后,对等节点还会发送包含由过滤器匹配的交易的tx消息。

当完整节点发送交易给轻量级客户端时,轻量级客户端会丢弃任何误报,并使用正确匹配的交易来更新其UTXO集合和钱包余额。当它更新其自己的UTXO集合视图时,它还会修改布隆过滤器,以匹配任何引用它刚刚找到的UTXO的未来交易。然后,完整节点使用新的布隆过滤器来匹配新的交易,整个过程重复进行。

客户端设置布隆过滤器可以通过发送filteradd消息来交互式地添加模式到过滤器中。要清除布隆过滤器,客户端可以发送filterclear消息。因为不可能从布隆过滤器中删除模式,所以如果不再需要某个模式,则客户端必须清除并重新发送新的布隆过滤器。

轻量级客户端使用的网络协议和布隆过滤器机制在BIP37中定义。

不幸的是,在部署了布隆过滤器之后,很明显它们并没有提供太多的隐私。从对等节点接收到布隆过滤器的完整节点可以将该过滤器应用于整个区块链,以找到所有客户端的交易(以及误报)。然后,它可以查找交易之间的模式和关系。随机选择的误报交易不太可能具有从输出到输入的父子关系,但是来自用户钱包的交易很可能具有该关系。如果所有相关交易具有某些特征,例如至少一个P2PKH输出,则不具备该特征的交易可以假定不属于该钱包。

还发现,特殊构造的过滤器可能会迫使处理它们的完整节点执行大量工作,这可能导致拒绝服务攻击。

由于这两个原因,Bitcoin Core最终限制了对布隆过滤器的支持,仅允许节点运营者明确允许的IP地址上的客户端使用。

这意味着需要一种替代方法来帮助轻量级客户端找到它们的交易。

Last updated