工作模式 - 比特币开发指南
原文链接: https://bitcoin.org/en/developer-guide#operating-modes
翻译: terryc007
版本:1.0
比特币开发指南
目前以客户端方式来验证区块链,有两种方式: 全节点和SPV节点。 其他方式,比如服务器端信任方式,不做推荐使用,这里就不作讨论。
全节点
比特币内核,是为大家所知的全链客户端,它是第一个也是最为安全的模型。这个安全模型通过下载,验证从创世区块到最近发现的所有区块的有效性,来确保区块链有效性。这也就是大家熟知的,从客户端角度,使用特定区块高度来验证整个网络。
要欺骗一个客户端,欺骗者需要提供另外一条区块链,且这条区块链难度要大于当前的“真”区块链。但是这需要很多累积的工作量证明,昂贵的算力。因为在区块链上生成一个新的区块的算力难度,在区块获得6个确认后,要欺骗一个全节点成本极高。这种验证方式极大的防止了女巫攻击。 要接收,验证“真”区块链的完整状态,仅需要一个诚实的网络节点即可。
简单支付验证(SPV)
在比特币白皮书中,描叙了另外一个验证区块的方法,就是全节点在初始同步时,先下载区块头,然后根据需要,再请求下载交易记录。 这使得下载数据的大小,跟区块大小无关,以每个区块头80字节,按区块高度线性增长,每年最多需要下载4.2MB。
如白皮书中所述,在SPV客户端,区块头中的默克树根跟它的一个默克尔树分支一起,证明交易是否包含在区块中。这并不保证这交易的有效性,而是证明双花攻击所需要的工作量证明。
某个特定区块深度表示该区块在区块中相应的累计难度所需要的工作量证明。 SPV知道默克尔树根,以及相应的交易信息,并从全节点获取相应的默克树分支。一但收到默克树分支,证明交易存在于区块中,然后,SPV客户端就可以以区块深度为代理来验证交易的有效性,安全性。 [?] 对于攻击用户的欺骗节点,它想在区块链中插入无效的交易,所要付出的代价随着区块上累计的难度,会不断的增加,因为欺骗节点需要在伪造的区块链上独自挖矿。
SPV潜在的缺点
如果只是简单地实现SPV功能,那么SPV客户端有几个缺点:
第一个,想欺骗SPV客户端,让它相信一个交易不在区块中的交易在区块中,是不那么容易的,但是,反过来,却不是。一个全节点可以说谎,遗漏了交易,这会导致SPV客户端相信这个交易没有发生过。这可以被认为是一种拒绝服务。一个稳妥的方案是,可以跟一定数量的全节点连接,然后给每一个节点请求数据。 然而这会被全节点认为这是分割比特币网络或女巫攻击,因为验证交易实际上免费的,过多的验证交易,可能会导致整个比特币网络带宽拥堵。因此了必须小心确保SPV客户端不要被全节点踢掉。
第二, SPV客户端仅会从全节点获取与自己密钥相关的交易。如果SPV客户端下载所有的区块,然后丢弃掉无用的区块,这会导致极大的带宽紧张。如果SPV客户端简单的从全节点那里获取指定的交易,这就让全节点了解到这个用户的地址上所有相关的情况。这会导致大量的隐私泄露,考虑到对客户端拒绝服务攻击,那些运行的全节点会不怎么欢迎这些用户或地址 。客户端可以很简单的发起很多垃圾交易请求,但是这会对SPV客户端带来很大负担,最终完全没有达到轻客户端的目的。
Bloom过滤器通过混淆,压缩区块数据请求次数来缓解第二个问题。
Bloom过滤器
Bloom过滤器是一个空间高效概率数据结构。它被用来测试元素关系。这个数据结构以牺牲指定的误判率为价,实现极大的数据压缩。
Bloom过滤器先把一个n比特位的数组设置为0. 然后随机选K个哈希函数, 每个哈希函数都会输出一个范围在1 ~ n的整数。
当在Bloom过滤器加入一个元素时,这个元素分别被k个哈希函数哈希k次,以每次哈希输出的整数,作为数组索引,并把数组上相对应的bit位设置为1.
对输入元素,使用同样的哈希函数来查询Bloom过滤器。 如果Bloom过滤器中所有k个比特位都是1,这就证明这个元素大概率在这个集合中。 很明显,在这个区域内,通过另外一个其他元素的组合,也可以把K个索引位置的值设为1,但是这些参数允许用户选择一个可接受的误报率。
要删除Bloom过滤器中的元素,只能丢弃这个bloom过滤器,然后在重新创建一个。
Bloom过滤器应用
Bloom过滤器不以追求误报率为其职责, 而是被用来创建一个可信的参数,来达到所期望的隐私级别,带宽上的平衡。SPV客户端创建Bloom过滤器,然后使用filterload
消息把它发送到全节点。在这个消息里面的过滤器中,设置了它所期望的交易。命令filteradd
,可以在不需要发送一个全新的Bloom过滤器,就可以添加一些额外的数据到之前的过滤器中,filterclear
允许SPV跟全节点当前的连接,从Bloom过滤器区块发现机制,切换到标准区块发现机制。如果过滤器已被加载,全节点会发送一个修改形式的区块,也叫做默克尔区块。默克尔区块就是带有默克尔树分支的区块头,以及一个挂载默克尔树分子上的Bloom过滤器。
SPV客户端不仅可以把交易,还有公钥,签名脚本中的数据,公钥脚本,等等数据以元素的方式添加到过滤器。这可以实现P2SH交易查找。
如果用户很关心隐私,他可以把Bloom过滤器的误报率提高,不过对发现交易而言,那就需要更多的带宽。如果用户带宽预算紧张,他可以把Bloom过滤器的误报率减低,但这允许全节点对客户上相关的交易一个清晰的了解。
资源: BitcoinJ是一个使用JAVA实现的,基于SPV安全模型,Bloom过滤器的比特币客户端。在很多Anroid的钱包中用到。
通过BIP37,Bloom过滤器已经被标准化使用。 具体实现请查阅BIP37.
未来提案
有一些未来的提案,比如,区块链的未花掉交易(UTXO)委托[?],在需要任一份完整区块链拷贝, 或相信与客户端连接的主要节点不会撒谎之间,寻找一个更满意的方案。 UTXO委托可以允许一个非常安全的客户端,使用一个在区块链中被授权的数据结构,使用有限的存储空间。 不过,这些提案还处于非常早期阶段,且需要通过软分叉来实现这些提案。
在这些运行模式实现之前,需基于可能的危险模型,算力跟带宽限制,以及在于比特币价值中的责任,来选择模型。
资源: UTXO委托源帖, 授权前缀树BIP提案
声明:
文中带有[?]的地方,表示我对此翻译明显感觉不太对的,后续会不断修正。
有些地方可能会翻译的不好,不地道,甚至错误,如果有发现,还请留言,指出,以便我好修正,谢谢!