主页 > 苹果版imtoken图标 > 《精通比特币第二版》中文版第8章比特币网络2/2

《精通比特币第二版》中文版第8章比特币网络2/2

苹果版imtoken图标 2023-11-08 05:07:12

精力有限,后期改版主要基于github。 建议您移至github链接阅读更新版本。 感谢您的理解:

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

邀请你加入和我一起学习

特别提示:栏目早鸟价:99元,11月5日后升级为199元,11月14日0点前报名的朋友将获赠《精通比特币第二版》中文版印刷本.

本文7400字。

8.6 交换“库存清单”

全节点连接到对等节点后,首先要做的是构建完整的区块链。 如果节点是一个全新的节点,那么它不包含任何区块链信息,它只知道一个块——静态嵌入在客户端软件中的创世块。 新节点需要下载从区块 0(创世区块)开始的数十万个区块的所有内容,以便与网络同步并重建整个区块链。

同步区块链的过程从发送版本消息开始,因为消息中包含的 BestHeight 字段表示节点当前的区块链高度(块数)。 一个节点可以从它的对等方那里得到版本信息,知道每一方有多少块,这样它就可以与自己的区块链拥有的块数进行比较。 对等点交换包含其本地区块链的顶部块哈希(指纹)的 getblocks 消息。 如果一个 peer 识别出它收到的 hash 不属于顶块,而是属于一个不属于顶块的旧块,那么它可以推断出它自己的本地区块链比其他 peer 有更长的区块链。

具有较长区块链的对等节点比其他节点拥有更多的块,并且可以识别其他节点需要“补充”哪些块。 它识别可用于共享的前 500 个块,并使用 inv(清单)消息传播这些块的哈希值。 缺少这些块的节点可以通过自己发送的getdata消息请求完整的块信息,并使用inv消息中包含的哈希值来确认是否是正确请求的块,从而读取这些丢失的块。 块。

在下面的例子中,我们假设一个节点只包含创世块。 它从对等节点接收到 inv 消息,其中包含区块链中最后 500 个区块的哈希值。 然后它开始向所有连接的节点请求块,并分散工作负载以防止单个节点被批量请求淹没。 该节点跟踪其每个对等连接上的“传输中”(已请求但尚未收到)块的数量,并检查该数量是否不超过上限(MAX_BLOCKS_IN_TRANSIT_PER_PEER)。 这样,如果一个节点需要更新大量区块,它不会发送新区块请求,直到前一个请求完成,允许对等节点控制更新速率,以免使网络不堪重负。 每个块在收到时都会添加到区块链中,如挖矿章节中所述。 随着本地区块链的逐渐建立,越来越多的区块被请求和接收,整个过程会一直持续下去,直到节点与全网同步。

每当一个节点离线时,无论多长时间,都会触发将本地区块链与对等节点进行比较并恢复丢失块的过程。 如果一个节点只离线几分钟,可能只丢失几个块; 当它离线一个月时,可能会丢失数千个块。 但在任何一种情况下,它都是从发送一条 getblocks 消息开始,接收到一个 inv 响应,然后开始下载丢失的块。 清单列表和块广播协议如图 8-6 所示。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

节点通过从对等节点读取块来同步区块链 图 8-6

8.7 简化支付验证(SPV)节点

并非所有节点都能够存储完整的区块链。 许多比特币客户端被设计为在空间和功率受限的设备上运行,例如智能手机、平板电脑、嵌入式系统等。 对于此类设备,简化支付验证 (SPV) 允许它们在无需存储完整区块链的情况下工作。 这种类型的客户端称为 SPV 客户端或轻量级客户端。 随着比特币使用的热潮,SPV节点逐渐成为比特币节点(尤其是比特币钱包)采用的最普遍的形式。

SPV 节点只需要下载区块头,而不需要下载每个区块包含的交易信息。 没有交易信息的最终区块链只有完整区块链大小的 1/1000。 SPV 节点无法构建所有可供消费的 UTXO 的完整图片,因为它们不知道网络上所有交易的完整信息。 SPV 节点使用略有不同的方法来验证交易,依靠对等节点“按需”提供区块链相关部分的部分视图。

打个比方,每个全节点就像一个陌生城市里的游客,手里拿着每条街道、每一个地址的详细地图。 相比之下,SPV节点就像这个陌生城市里的游客,只知道一条主干道的名字,通过随机询问城市里的陌生人来获取路段方向。 虽然这两种类型的游客都可以通过访问该站点来验证街道的存在,但没有地图的游客不知道每条小巷中有哪些街道或附近有哪些其他街道。 没有地图的游客在“教堂街23号”面前,不知道这个城市还有没有其他“教堂街23号”,也不知道眼前的是不是他们自己正在找。 对他来说,最好的办法就是向足够多的人问路,并希望他们中的一些人不会试图抢劫他。

Easy Payment Verification 通过参考交易在区块链中的深度而不是高度来验证交易。 具有完整区块链的节点构建了一条验证链,该验证链由数千个区块和交易组成,沿着区块链一直按时间倒序一直回到创世区块。 SPV 节点将验证所有区块(但不是所有交易)的链,并将区块链与相关交易链接起来。

例如,如果一个全节点想要在第 300,000 个区块中检查一笔交易,它将从该区块开始的所有 300,000 个区块都链接回创世块,并构建一个完整的 UTXO 数据库,通过确认交易是否有效来验证交易的有效性。 UTXO 尚未支付。 SPV 节点无法验证 UTXO 是否尚未支付。 相反,SPV 节点将使用 merkle 路径(参见“Merkle 树”部分)在交易信息和它所在的块之间建立链接。 然后SPV节点等待序号为300001到300006的6个区块堆叠在交易所在区块的顶部,通过建立交易深度为300006到300001区块来验证交易的有效性。 事实上,根据代理网关协议,如果网络中的每个其他节点都接受区块 300,000 并投入足够的工作在该区块之上再生成六个区块,则可以证明该交易不是双花。

如果一笔交易实际上并不存在,SPV 节点不会误认为该交易存在于一个区块中。 SPV 节点将通过请求 merkle 路径证明和验证区块链中的工作量证明来验证交易的存在。 然而,交易的存在可能对 SPV 节点“隐藏”。 SPV节点无疑可以验证某笔交易的存在,但无法验证某笔交易的不存在(比如同一笔UTXO的双重支付),因为SPV节点没有所有交易的记录。 此漏洞可被拒绝服务攻击或针对 SPV 节点的双花攻击所利用。 为了抵御这些攻击,SPV 节点需要随机连接到多个节点,以增加连接到至少一个可靠节点的概率。 这种对随机连接的需求意味着 SPV 节点也容易受到网络分区攻击或女巫攻击。 在后一种情况下,SPV 节点连接到假节点或假网络,与真实节点或真实比特币网络没有连接。

在大多数实际情况下,连接良好的 SPV 节点足够安全,在资源需求、实用性和安全性之间保持适当的平衡。 当然,如果要确保万无一失的安全性,最靠谱的方法就是运行一个完整的区块链节点。

提示全区块链节点通过检查其下方数千个区块的整个链来验证交易,以确保此 UTXO 尚未支付。 另一方面,SPV 节点通过检查其上方的区块将其推到下方的深度来验证交易。

SPV 节点使用 getheaders 消息而不是 getblocks 消息来获取区块头。 响应方将在一条标头消息中发送最多 2000 个区块标头。 这个过程与全节点获取所有区块的过程没有区别。 SPV 节点还在与对等节点的连接上设置过滤器,以过滤从对等节点发送的未来区块和交易数据流。 通过 getdata 请求读取任何目标事务。 对等节点通过生成包含交易信息的 tx 消息进行响应。 区块头同步流程如图8-7所示。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

图 8-7 SPV 节点同步区块头

由于 SPV 节点需要读取特定交易以选择性地验证交易,这会产生隐私风险。 与收集每个区块中的所有交易的完整区块链节点不同,SPV 节点对特定数据的请求可能会无意中泄露钱包中的地址信息。 例如,监控网络的第三方可以跟踪 SPV 节点上钱包请求的所有交易信息,并使用这些交易信息将比特币地址与钱包用户相关联,从而损害用户的隐私。

在引入 SPV 节点/轻量级节点后不久,比特币开发者添加了一个新特性:布隆过滤器,以解决 SPV 节点的隐私风险。 布隆过滤器允许 SPV 节点通过使用概率而不是固定模式的过滤机制仅接收交易信息的一个子集,而不会确切地透露它们感兴趣的地址。

在引入 SPV/轻量级节点后不久,比特币开发人员添加了一个称为布隆过滤器的功能来解决 SPV 节点的隐私风险。 Bloom 过滤器允许 SPV 节点通过使用概率而不是固定模式过滤机制来接收交易的子集,而无需准确透露它们感兴趣的地址。

8.8 布隆过滤器

Bloom filter 是一种基于概率的过滤方法,它允许用户描述特定的关键字组合,而不必精确地表达它们。 它允许用户有效地搜索关键字,同时保护他们的隐私。 在SPV节点中,该方法用于向对端节点发送交易信息查询请求,交易地址不会暴露。

使用我们之前的示例,没有地图的游客需要询问前往特定地点的路线。 如果他问一个陌生人“教堂街 23 号在哪里”,他会不经意地泄露他的目的地。 布隆过滤器会问,附近有没有“通”字的街道? 这个问题包含的关键字比以前少了一些。 游客可以选择包含多少信息,例如“以‘唐街’结尾的街道”或“以‘角’字开头的街道”。 如果他问的数量越少,得到的可能地址就越多,隐私得到保护,但是这些地址中有很多不相关的结果; 如果他要求非常具体,他也会在获得更准确结果的同时暴露自己的隐私。

布隆过滤器允许 SPV 节点指定交易的搜索模式,可以根据准确性或隐私考虑进行调整。 一个非常具体的布隆过滤器会产生更准确的结果,但也会显示用户钱包中使用过的地址; 反之,如果过滤器只包含简单的关键字,则会搜索到更多对应的交易,在包含几笔无关交易的同时具有更高的隐私性。

8.8.1 布隆过滤器如何工作

布隆过滤器的实现由一个可变长度(N)的二进制数组(N位二进制数组成一个位域)和一个可变数量(M)的一组哈希函数组成。 这些哈希函数的输出值总是在1到N之间,对应二进制数组。 并且这个函数是一个确定性函数,这意味着任何使用同一个布隆过滤器的节点都可以通过这个函数对特定的输入得到相同的结果。 Bloom 过滤器的准确性和隐私性能通过改变哈希函数的长度 (N) 和数量 (M) 来调整。

在图 8-8 中,我们使用一个小的十六进制数组和三个哈希函数来演示布隆过滤器的应用。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

图 8-8。 一个简单的布隆过滤器,由一个 16 位数组和三个哈希函数组成

布隆过滤器数组中每个数字的初始值为零。 关键词在被添加到布隆过滤器之前依次通过每个哈希函数。 输入经过第一个哈希函数运算后,得到一个1~N之间的数,将其在数组中对应的位(编号为1~N)设置为1,从而记录下哈希函数的输出。 然后进行下一个hash函数的运算,将另外一个位置置1; 等等。 所有M个哈希函数计算完后,一共M个比特值从0变成了1,这个关键字也被“记录”在布隆过滤器中。

图 8-9 显示了将关键字“A”添加到图 8-8 中的简单布隆过滤器。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

图 8-9 将关键字“A”添加到一个简单的布隆过滤器

添加第二个密钥只是重复前面的步骤。 关键字依次被各个哈希函数运算后,对应的位变为1比特币的节点数量,布隆过滤器记录关键字。 需要注意的是,当布隆过滤器中的关键字增加时,其对应的哈希函数输出值的位可能已经为1,此时该位不会再发生变化。 也就是说,随着越来越多的关键字指向重复的位,布隆过滤器会随着位 1 的增加而饱和,结果准确性会降低。 过滤器之所以是基于概率的数据结构,是因为关键字的增加会导致准确率的下降。 准确性取决于键的数量和数组的大小 (N) 以及散列函数的大小 (M)。 更大的数组和更多的哈希函数将记录更多的关键字以提高准确性。 但是,小数组和有限的哈希函数只能记录有限的关键字,从而降低了准确性。

图 8-10 显示了向这个简单的布隆过滤器添加第二个关键字“B”。

!图 8-10 为简单布隆过滤器添加第二个关键字“B”](%7CimageView2/2/w/1240)

为了测试某个关键字是否记录在布隆过滤器中,我们将关键字逐一代入到每个哈希函数中,并将结果与​​原始数组进行比较。 如果所有结果对应的位都变成了1,说明这个关键词可能已经被过滤器记录下来了。 之所以这个结论不确定,是因为这些byte 1也可能是其他关键字运算的重叠结果。 简单来说,布隆过滤器正匹配意味着“可能”。

图8-11是验证关键字“X”是否在上述布隆过滤器中的例子。 相应的位都设置为 1,因此关键字很可能是匹配的。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

图8-11 验证布隆过滤器中是否存在关键字“X”。 如果结果可能是正匹配,则表示“可能是”

另一方面,如果我们代入关键字后的计算结果中有一位为0,则表示该关键字没有被记录在过滤器中。 负匹配的结果不是可能的,而是确定的。 也就是说,负匹配意味着“一定不能”。

图 8-12 是验证关键字“Y”在简单布隆过滤器中是否存在的示例。 如果图中某个结果字段为0,则该字段一定不匹配。

怎么搭建比特币节点_2021年5月比特币持币地址数量_比特币的节点数量

图8-12 验证布隆过滤器中是否存在关键字“Y”。 如果结果是必要的否定匹配,则表示“一定不是”

8.9 SPV 节点如何使用布隆过滤器

布隆过滤器用于过滤 SPV 节点从其对等方接收的交易(以及包含它们的块),仅选择 SPV 节点感兴趣的交易,而不会泄露其感兴趣的地址或密钥。

SPV节点会将“filter”初始化为“null”; 在那种状态下,布隆过滤器不会匹配任何模式。 然后,SPV 节点将列出所有感兴趣的地址、密钥和哈希值,这将通过从其钱包控制的任何 UTXO 中提取公钥哈希值和脚本哈希值以及交易 ID 来实现。 然后,SPV 节点将这些模式中的每一个添加到布隆过滤器中,这样如果交易中存在这些模式,布隆过滤器将“匹配”而不自动显示模式。

然后,SPV 节点将向对等方发送过滤器加载消息,其中包含要在连接上使用的布隆过滤器。 在对等节点上,布隆过滤器会针对每个传入交易进行检查。 全节点根据布隆过滤器检查交易的几个部分,寻找匹配项,包括:

交易编号

每个交易输出的锁定脚本的数据组件(脚本中的每个键和散列)

每笔交易输入

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

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

构建过滤器后,节点将针对布隆过滤器测试每笔交易的输出。 只有匹配过滤器的交易才会被发送到节点。

为了响应来自节点的 getdata 消息,对等方将发送一个 merkleblock 消息,其中仅包含与过滤器匹配的块和每个匹配事务的 merkle 路径(参见 [merkle_trees])的块头。 然后,对等方还将发送一条 tx 消息,其中包含与过滤器匹配的交易。

当全节点向 SPV 节点发送交易时,SPV 节点会丢弃任何误报并使用正确匹配的交易更新其 UTXO 集和钱包余额。 当它更新 UTXO 集的视图时,它还会修改布隆过滤器以匹配任何引用它刚刚发现的 UTXO 的交易。 然后全节点使用新的布隆过滤器来匹配新的交易,并重复整个过程。

设置布隆过滤器的节点可以通过发送 filteradd 消息以交互方式向过滤器添加模式。 要清除布隆过滤器,节点可以发送过滤器清除消息。 因为不可能从布局过滤器中删除模式,如果不再需要该模式,节点必须清除并重新发送新的布隆过滤器。

BIP-37(Peer Services)定义了SPV节点的网络协议和布隆过滤器机制。

8.10 SPV 节点和隐私

实施 SPV 的节点比全节点具有更弱的隐私性。 全节点接收所有交易,因此不会透露有关地址是否在其钱包中使用的信息。 SPV 节点会收到一份与其钱包地址相关的过滤列表。 结果,它减少了所有者的隐私。

布隆过滤器是减少隐私损失的一种方法。 没有它们,SPV 节点将不得不明确列出它感兴趣的地址,从而造成严重的隐私侵犯。 然而,即使有过滤器,监控 SPV 客户端流量的对手或与其直接相连的 P2P 网络中的节点也可以随时随地收集到足够的信息,从而知道 SPV 客户端钱包中的地址。

8.11 加密和认证连接

大多数比特币新用户都认为比特币节点的网络通信是加密的。 事实上,比特币最初的实现显然是完整的。 虽然这不是全节点的主要隐私问题,但 SPV 节点是一个大问题。

作为增加比特币 P2P 网络隐私和安全的一种方式,有两种解决方案通过 BIP-150/151 提供通信加密:Tor 传输和 P2P 身份验证和加密。

8.11.1 Tor 传输

Tor,代表洋葱路由网络,是一个软件项目和网络,它通过提供匿名性、不可追踪性和隐私的随机网络路径提供数据加密和封装。

Bitcoin Core 提供多种配置选项,允许您运行通过 Tor 网络传输流量的比特币节点。 此外,Bitcoin Core还可以提供Tor隐藏服务,让其他Tor节点通过Tor直接连接到你的节点。

从比特币核心版本 0.12 开始,如果节点能够连接到本地 Tor 服务,它们将自动提供隐藏的 Tor 服务。 如果您安装了 Tor 并且比特币核心进程以具有足够权限访问 Tor 身份验证 cookie 的用户身份运行,这应该会自动运行。 使用调试标志开启Bitcoin Core对Tor服务的调试,如下:

$ bitcoind --daemon --debug=tor

您应该在日志中看到“tor: ADD_ONION success”,表明 Bitcoin Core 已将隐藏服务添加到 Tor 网络。

您可以在比特币核心文档 (docs/tor.md) 和各种在线教程中找到有关将比特币核心作为 Tor 隐藏服务运行的更多说明。

8.11.2 对等认证和加密

两个比特币改进程序 BIP-150 和 BIP-151 在比特币 P2P 网络中增加了对 P2P 身份验证和加密的支持。 这两个 BIP 定义了可由兼容的比特币节点提供的可选服务。 BIP-151 支持对支持 BIP-151 的两个节点之间的所有通信进行协商加密。 BIP-150 提供可选的点对点身份验证,允许节点使用 ECDSA 和私钥验证彼此的身份。 BIP-150要求在认证之前比特币的节点数量,两个节点按照BIP-151建立加密通信。

截至 2017 年 1 月,BIP-150 和 BIP-151 尚未在比特币核心中实施。 然而,这两项提议都已由至少一个名为 bcoin 的替代比特币客户端实施。

BIP-150 和 BIP-151 允许用户运行连接到可信全节点的 SPV 客户端,使用加密和身份验证来保护 SPV 客户端的隐私。

此外,身份验证可用于创建受信任的比特币节点网络并防止中间人攻击。 最后,P2P 加密(如果广泛部署)将加强比特币对流量分析和隐私侵犯监视的抵抗力,尤其是在互联网使用受到严格控制和监控的极权主义国家。

该标准在 BIP-150(对等身份验证)和 BIP-151(对等通信加密)中定义。

8.12 交易池

几乎比特币网络中的每个节点都维护着一个未确认交易的临时列表,称为内存池或交易池。 节点使用这个池来跟踪网络已知但尚未包含在区块链中的交易。 例如,保管用户钱包的节点会使用这个交易池来记录网络已经收到但尚未确认的属于用户钱包的预付款信息。

当交易被接收和验证时,它们被添加到交易池中并通知相邻节点,从而传播到网络中。

一些节点实现还维护一个单独的孤立交易池。 如果一笔交易的输入与未知交易有关,比如父交易缺失,则孤儿交易会暂时存放在孤儿交易池中,直到父交易的信息到达。

当一个交易被添加到交易池中时,会同时检查孤儿交易池,看是否有孤儿交易引用了这个交易的输出(子交易)。 验证任何匹配的孤立交易。 如果有效,它们将从孤立交易池中移除并添加到交易池中,从而完成以其父交易开始的链。 对于新加入交易池的交易,它不再是孤儿交易。 递归地重复上述过程寻找更多的后代,直到找到所有后代。 通过这个过程,父交易的到来将整个链中的孤立交易与它们的父交易重新结合起来,触发了整个独立交易链的级联重构。

交易池和孤立交易池(如果已实现)都存储在本地内存中,而不是存储在硬盘等持久性存储设备上。 更准确地说,它们是动态填充来自网络的传入消息。 当节点启动时,两个池都是空闲的; 随着网络中不断收到新的交易,两个池逐渐被填满。

一些比特币客户端实现还维护一个 UTXO 数据库,也称为 UTXO 池,它是区块链中所有未支付交易输出的集合。 “UTXO 池”听起来类似于交易池,但它代表不同的数据集。 UTXO 池不同于交易池和孤儿交易池,它在初始化时并不是空的,而是包含数百万个未花费的交易输出条目,其中一些甚至可以追溯到 2009 年。UTXO 池可能被放置在在本地内存中,或作为持久存储中的索引数据库表。

交易池和孤立交易池代表单个节点的局部视角。 根据节点启动或重新启动的时间,不同节点上的两个池的内容可能会有很大差异。 相反,UTXO 池代表了网络的显着共识,因此不同节点之间 UTXO 池的内容相差不大。 此外,交易池和孤儿交易池只包含未确认的交易,而 UTXO 池只包含已确认的交易。

本章结束。

参考内容:

1、本文部分内容摘自《精通比特币》第一中文译本,特此说明,谢谢。

我正在发起“和我一起精通比特币第二版”活动。

我声明,这不是讲座,而是讨论,是学习,所以需要你们的参与,更需要你们的参与。

我把这种学习方法作为一种认知学习方法的实践[注]。

希望大家能和我一起尝试通过认知学习法结合《精通比特币第二版》的学习,总结出一套可行的区块链知识技能快速入门方法。

尝试、反思、总结、生成、结合实践、检验、逐步迭代升级,这就是我们的经验,也是我们的结果。

这个结果也将成为我们大家合写的一本书《认知学习比特币》的原型(所有有价值的讨论都将成为本书的素材)。

也希望通过这种认知学习方法论的实践和迭代升级,让大家把这种实践出来的学习方法迁移到更多领域的学习中。

所以希望我们携手进入第二季,第三季……

欢迎扫描二维码加入。

2021年5月比特币持币地址数量_怎么搭建比特币节点_比特币的节点数量

了解更多信息,请扫描二维码