主页 > imtoken钱包官方苹果 > 第 2 讲:比特币如何运作

第 2 讲:比特币如何运作

imtoken钱包官方苹果 2023-02-07 07:15:07

3.4

比特币区块

到目前为止,在本章中我们已经研究了如何构建和赎回单个交易。 但正如我们在第 2 章中看到的,交易被分组到块中。 为什么会这样? 基本上,这是一种优化。 如果矿工必须单独就每笔交易达成共识,那么系统可以接受的新交易的百分比将会低得多。 另外,区块的哈希链比交易的哈希链要短得多,因为每个区块可以放入大量的交易。 这将使验证区块链数据结构更加高效。

区块链是两种不同的基于哈希的数据结构的巧妙组合。 第一个是块的哈希链。 每个区块都有一个区块头,一个指向某些交易数据的哈希指针,以及一个指向序列中前一个区块的哈希指针。 第二个数据结构是包含该块中所有交易的每块树。 这是一棵 Merkle 树,允许我们以有效的方式汇总块中的所有交易。 正如我们在第 1 章中看到的,为了证明交易包含在特定区块中,我们可以提供一条通过树的路径,该路径的长度是区块中交易数量的对数。 总而言之,一个区块由标头数据和以树状结构排列的交易列表组成。

图 3.8 比特币区块链包含两种不同的哈希结构。 第一个是将不同块相互链接的块哈希链。 第二个是在每个区块内,这是区块内交易的 Merkle 树。

头部主要包含与我们在前一章中简要讨论过的挖矿难题相关的信息,我们将在第 5 章中重新讨论。回想一下,块的哈希头部必须以大量零开头才能使块有效。 标头还包含一个矿工可以更改的“随机数”、一个时间戳和一个“位”,它表示找到该块的难度。 标头是挖矿中唯一的哈希值。 因此,要验证区块链,我们需要做的就是查看头部。 标头中包含的唯一交易数据是交易树的根 - “mrkl_root”字段。

图 3.9 coinbase 交易。 coinbase 交易创建新的硬币。 它不会赎回以前的输出,并且它有一个空的哈希指针来指示这一点。 它有一个可以包含任意数据的 coinbase 参数。 Coinbase 的价值是区块奖励加上该区块包含的所有交易费用。

关于区块的另一个有趣的事情是它们在 Merkle 树中有一个特殊的交易,称为“coinbase”交易。 这类似于 Scroogecoin 中的 CreateCoins。 所以这是比特币中发生的新硬币创造。 它看起来像一个普通的交易,但有一些不同:(1)它总是有一个输入和一个输出,(2)输入不兑换以前的输出,因此包含一个空的哈希指针,因为它是铸造新比特币而不是消耗现有硬币,(3) 目前产出的价值略高于 25 个比特币。 输出值是矿工从区块中获得的收入。 它由两部分组成:由系统设定的平均挖矿奖励,每 210,000 个区块(约 4 年)减半,以及从每个区块的交易中收取的交易费用。 4) 有一个特殊的完全任意的“coinbase”参数——矿工可以把他们想要的任何东西放在那里。

有趣的是,在比特币开采的第一个区块中,“coinbase”参数引用了《泰晤士报》上一篇涉及大臣银行的故事。 这被解释为对比特币创世区块进行政治评论的动机。 这也证明了第一块矿是在2009年1月3日之后开采出来的。使用coinbase参数成为矿工支持不同新特性的一种方式。

比特币加密算法_比特币等加密货币矿机销售_详解比特币挖矿算法

更好地了解块格式和交易格式的最佳方法是自己探索区块链。 有许多网站可以访问这些数据,例如 blockchain.info。 您可以查看交易图,查看哪些交易兑换其他交易,查找具有复杂脚本脚本的交易,并查看区块结构以查看区块如何引用其他区块。 由于区块链是公共数据结构,开发人员构建了漂亮的包装器以图形方式探索它们。

3.5

比特币网络

到目前为止,我们一直在谈论参与者发布交易并将其添加到区块链的能力,这就像变魔术一样发生了。 事实上,这是通过比特币网络发生的。 它是一个 p2p 对等网络,它从对等网络中继承了许多用于其他各种目的的想法。 在比特币网络中,所有节点都是对等的。 没有层次结构,没有特殊节点或主节点。 它在 TCP 上运行并具有随机拓扑结构,其中每个节点都与其他随机节点对等。 新节点可以随时加入。 事实上,您可以下载比特币客户端,将您的计算机作为一个节点启动,它将与比特币网络上的每个其他节点具有相同的权限和能力。

网络随着时间的推移而变化,由于节点的进入和离开而变得非常动态。 没有明确的方法可以离开网络。 相反,如果一个节点在一段时间内没有被听到——三个小时是硬编码到普通客户端的截止时间——其他节点开始忘记它。 网络以这种方式优雅地处理离线节点。

回想一下,节点连接到随机节点,并且没有任何类型的地理拓扑。 现在您启动一个新节点并想要加入网络。 你用一个你知道的节点开始一个简单的消息。 这通常称为您的种子节点,有几种不同的方法可以通过查找种子节点列表来尝试连接。 你发送一条特殊的消息说,“告诉我你知道的网络中所有其他节点的地址。” 您可以对想要了解的新节点重复此过程。 然后你可以选择一个与之对应,你将因此成为比特币网络的一个功能齐全的成员。 说到随机性,有几个步骤,理想的结果是你对应到一组随机的节点。 要加入网络,您只需要知道如何联系已经在网络上的节点即可。

联网有什么好处? 当然是为了维护区块链。 所以要发布交易,我们希望整个网络都能听到它。 这是通过简单的泛洪算法(有时称为八卦协议)实现的。 如果爱丽丝想付给鲍勃一些钱,她的客户会创建她的节点并将该交易发送给她的所有同行。 这些节点中的每一个都执行一系列检查以确定是否接受和传达交易。 如果检查通过,则该节点将其发送给所有对等节点。 听到交易的节点将其放入他们听到但尚未出现在区块链上的交易池中。 如果一个节点听到一个已经在它的交易池中的交易,它就不会进一步广播它。 这确保了泛洪协议终止并且交易不会永远循环网络。 请记住,每笔交易都由其哈希值唯一标识,因此在池中查找交易很容易。

当节点听到新交易时,它们如何决定是否应该传播它? 这里有四个检查步骤。 第一个也是最重要的检查是交易验证——交易必须对当前区块链有效。 该节点为每个先前兑换的输出运行脚本并确保脚本返回 true。 其次,他们检查此处赎回的输出是否尚未花费。 第三,如前所述,他们不会转发他们已经看到的交易。 第四,默认情况下,节点只会接受和继承基于一小部分脚本白名单的“标准”脚本。

所有这些检查都只是完整性检查。 行为良好的节点实施这些以保持网络正常运行,但没有规定节点必须遵循这些特定步骤。 由于是点对点网络比特币加密算法,任何人都可以加入,因此,节点可能会转发双花、非标准交易或完全无效的交易。 这就是为什么每个节点都必须自己检查的原因。

比特币等加密货币矿机销售_比特币加密算法_详解比特币挖矿算法

由于网络中的延迟,节点最终可能会看到待处理交易池的不同视图。 当尝试双花时,这变得特别有趣和重要。 假设爱丽丝试图向鲍勃和查理支付相同的比特币,并大致在同一时间发送两笔交易。 一些节点首先听到 AliceBob 的交易,而其他节点首先听到 AliceCharlie 的交易。 当一个节点听到这些交易中的一个时,它会将它添加到它的交易池中,如果它稍后听到另一个交易,它将被视为双花。 该节点将丢弃后一个交易,并且不会传达它或将其添加到其交易池中。 因此,节点将暂时不同意将哪些交易放入下一个区块。 这称为竞争条件。

好消息是,这完全没问题。 谁挖出下一个区块,基本上就打破了平局,并决定两个未决交易中的哪一个将最终永久地扔进一个区块。 假设 AliceCharlie 的交易变成了一个区块。 当 AliceBob 交易的节点听说这个区块时,他们将从内存池中删除交易,因为它是双花。 当 AliceCharlie 交易的节点听到这个区块时,他们将从内存池中删除交易,因为它已经嵌入到区块链中。 因此,一旦这个块传播到网络,就不会再有分歧。

因为节点的默认行为是挂起它们首先听到的任何消息,所以网络位置很重要。 如果在网络中的两个不同位置发布了两个相互冲突的交易或区块,它们将开始在整个网络中泛滥,而节点首先看到的交易将取决于其在网络中的位置。

当然,这假设每个节点都实现了他们首先保留他们听到的任何内容的逻辑。 然而,由于没有中央机构强制执行这一点,节点可以自由实施他们想要选择保留哪些交易以及是否转发它们的任何其他逻辑。 我们将在第 5 章更加关注矿工激励。

侧边栏零确认交易和更换费用。 在第 2 章中,我们研究了零确认交易,一旦它们在网络上广播,接收者就会接受。 这并不是为了防止双重支出而设计的。 但正如我们所见,在发生冲突交易的情况下,矿工的默认行为是包括他们首先收到的交易,这使得双花对于零确认交易来说相当困难。 因此,由于方便,零确认交易变得普遍。

自 2013 年以来,人们一直有兴趣将默认政策更改为替代费用 (RBF),据此,如果节点听到包含更高费用的冲突交易,它们将替换其交易池中的待处理交易。 这是矿工的理性行为,至少在短期内可以给他们带来更好的费用。 然而,在实践中,替代费用将使双重支出更容易抵御零确认攻击。

因此,无论是RBF世界中防止或防止双花的技术问题,还是比特币应尽可能支持零确认,还是放弃的哲学问题,替代费用的问题都引起了争议。 我们不会深入讨论这场旷日持久的辩论,但比特币最近通过了 RBF 网络的“选择加入”,在该网络中,交易可以(使用序列号字段)将自己标记为有资格被更高费用取代交易。

到目前为止,我们一直在讨论交易广播。 每当矿工发现新区块时,宣布新区块的逻辑几乎与传播新交易的逻辑相同,并且两者都受制于相同的竞争条件。 如果同时挖出两个有效区块,则只有其中一个可以被纳入长期共识链。 最终将包含哪些块将取决于其他节点构建在哪些块上,而不会进入共享链的块将被孤立。

验证区块比验证交易更复杂。 除了验证标头并确保哈希值在可接受的范围内之外,节点还必须验证块中包含的每笔交易。 最后,如果一个节点建立在最长的分支上,它只会转发一个块,基于块视图(实际上是一个块树)的样子。 这样就避免了分叉的建立。 但就像交易一样,节点可以根据需要实现不同的逻辑——它们可能会传达无效的块或从区块链中较早的点构建的块。 这将建立一个分叉,但没关系。 该协议旨在容忍这一点。

详解比特币挖矿算法_比特币等加密货币矿机销售_比特币加密算法

图 3.10 区块传播时间 该图显示了一个区块到达网络中不同百分比的节点所需的平均时间。

洪水算法的延迟是多少? 图 3.10 中的图表显示了新块传播到网络中每个节点的平均时间。 该线显示了传播时间的第 25 个、第 50 个和第 75 个百分位数。 可以看出,传播时间基本上与块大小成正比。 这是因为网络带宽是瓶颈。 较大的块需要超过 30 秒才能传播到网络中的大多数节点。 所以它不是一个特别有效的协议。 在互联网上,30 秒是相当长的时间。 比特币在设计上,网络简单,结构简单,节点平等,可以随时进出,效率优先。 因此,一个区块可能需要经过许多节点才能到达网络中最远的节点。 如果网络是自上而下设计的效率,我们可以确保任何两个节点之间的路径是短的。

网络规模 很难衡量一个网络有多大,因为它是动态的,没有中央权威。 一些研究人员提出了一些估计。 在高端,据说在给定的一个月内,超过一百万个 IP 地址将充当比特币节点,至少是暂时的。 另一方面,似乎只有大约 5,000 到 10,000 个节点永久连接并完全验证他们听到的每笔交易。 这似乎是一个令人惊讶的低数字,但在撰写本文时,没有证据表明完全验证节点的数量正在增加,事实上它可能正在下降。

存储要求完整的验证节点必须保持永久连接才能听到所有数据。 节点离线的时间越长,它就越需要重新加入网络。 此类节点还必须存储整个区块链,并且需要良好的网络连接才能听到每个新交易并将其转发给对等方。 存储需求目前低于数十 GB(见图 3.11),这完全在单个商务桌面的能力范围内。

图 3.11。 区块链的大小。 完全验证节点必须存储整个区块链,截至 2014 年年底为 26 GB。

最后,完全验证节点必须维护一整套未花费的交易输出,这些输出是可以花费的硬币。 理想情况下,这应该存储在 RAM 中,以便当听到网络上的新交易时,节点可以快速查找它试图声明的交易输出,运行脚本,查看签名是否有效,然后添加交易到交易池。 截至 2014 年年中比特币加密算法,区块链中有超过 4400 万笔交易,其中 1200 万笔未花费。 幸运的是,它仍然足够小,可以以高效的数据结构容纳不到 1G 的 RAM。

轻量级节点。 与完整验证节点相反,存在轻量级节点,也称为瘦客户端或简单支付验证 (SPV) 客户端。 事实上,比特币网络上的绝大多数节点都是轻量级节点。 这与完整验证节点不同,因为它们不存储整个区块链。 他们只存储他们需要验证的部分,他们关心的具体交易。 如果您使用钱包程序,它通常会包含一个 SPV 节点。 该节点下载代表支付到您地址的区块头和交易。

SPV 节点不具备完全验证节点的安全级别。 由于节点有区块头,它可以检查这些区块是否难以挖掘,但它无法检查区块中包含的每笔交易是否真正有效,因为它没有交易历史,也不知道未使用的交易输出集。 SPV 节点只能验证实际影响它们的交易。 因此,他们基本上信任完整的验证节点来验证所有其他交易。 这不是一个糟糕的安全交易。 他们假设有完整的验证节点在做艰苦的工作,如果矿工在挖掘区块时遇到困难,这是一个非常昂贵的过程,他们可能也会进行一些验证以确保该区块不会被拒绝。

作为 SPV 节点的成本节省是巨大的。 区块头只有区块链大小的 1/1000 左右。 所以不需要存储几十G的字节,几十兆就可以了。 即使是智能手机也可以轻松充当比特币网络中的 SPV 节点。

比特币等加密货币矿机销售_详解比特币挖矿算法_比特币加密算法

由于比特币依赖于开放协议,理想情况下会有许多不同的实现无缝交互。 这样,如果其中存在错误,则不太可能导致整个网络瘫痪。 好消息是该协议已成功重新实施。 有 C++ 和 Go 的实现,人们也在做很多其他的事情。 坏消息是,网络上的大多数节点都在运行用 C++ 编写并由比特币核心开发人员维护的比特币库,其中一些节点运行的是以前未更新的旧版本。 无论如何,大多数人都在运行这个普通客户端的一些变体。

3.6

限制和改进

最后,我们将讨论比特币协议的一些内在限制,以及改进这些限制所面临的挑战。 当比特币于 2009 年推出时,在任何人真正意识到它可能成长为一种全球重要的货币之前,比特币协议中存在许多硬编码限制。 这些包括每个区块的平均时间、区块的大小、区块中签名操作的数量以及货币的可分割性、比特币的总数以及区块奖励结构的限制。

现有比特币总量的限制和挖矿奖励的结构可能永远不会改变,因为改变它们对经济的影响太大了。 假设比特币的奖励结构和比特币的有限供应将保持原计划的方式,矿工和投资者对该系统下了很大的赌注。 如果这种情况发生变化,将对人们产生巨大的经济影响。 所以社会基本上同意这些方面,无论选择是否明智,都不会改变。

还有其他一些变化似乎让每个人都变得更好,因为一些最初的设计选择似乎并不是事后才想到的。 其中最主要的是影响系统吞吐量的限制。 比特币网络进程每秒可以处理多少笔交易? 此限制来自块大小的硬编码限制。 每个块限制为一兆字节,大约一百万字节。 每个事务至少为 250 字节。 将 1,000,000 分成 250 份,我们可以看到每个区块有 4000 笔交易的限制,每 10 分钟发现一次,这样每秒大约有 7 笔交易,这是比特币网络所能处理的。 更改这些限制似乎只是调整源代码文件中的常量的问题。 然而,在实践中很难做出这样的改变,我们稍后会解释原因。

那么每秒七笔交易怎么样? 与任何主要信用卡处理器的吞吐量相比相当低。 据说 Visa 的网络平均每秒处理约 2,000 笔交易,在繁忙时段每秒处理 10,000 笔交易。 即使是比 Visa 更新、规模更小的 Paypal,在高峰时段每秒也能处理 100 笔交易。 这比比特币高出一个数量级。

人们长期担心的另一个局限性是比特币加密算法的选择是固定的。 只有少数几种哈希算法可用,并且只有一种签名算法,ECDSA,在特定的椭圆曲线上,称为 secp256k1。 人们担心比特币的生命周期会很长——算法可能会被破解。 密码学家可能想出一种我们没有预见到的聪明的新攻击,使算法不安全。 哈希函数也是如此; 事实上,哈希函数在过去十年中在密码分析方面取得了稳步进展。 包含在比特币中的 SHA-1 有一些已知的加密缺陷,但并不致命。 为了改变这一点,我们必须扩展比特币脚本语言以支持新的加密算法。

更改协议。 我们如何将新功能引入比特币协议? 您可能认为这很简单——只需发布一个新版本的软件,并告诉所有节点升级即可。 实际上,这很复杂。 实际上,不可能假设每个节点都会升级。 网络中的某些节点将无法获得或无法及时获得新软件。 虽然一些节点运行的是旧版本,但大多数节点升级的影响在很大程度上取决于软件更改的性质。 我们可以区分两种类型的变化:导致硬分叉的变化和导致软分叉的变化。

比特币加密算法_详解比特币挖矿算法_比特币等加密货币矿机销售

硬分叉。 我们可以进行的一种更改会引入以前被认为无效的新功能。 也就是说,较新版本的软件会将块识别为有效,而较旧的软件将拒绝其有效性。 现在考虑当大多数节点升级但有些节点没有升级时会发生什么。 不久之后,最长的分支将包含被旧节点视为无效的块。 因此,旧节点会脱离并在区块链中使用分叉来排除具有新特征的块。 在他们升级软件之前,他们会认为他们的(较短的)分支是最长的有效分支。

这种变化被称为硬分叉变化,因为它分裂了区块链。 网络中的每个节点都将位于一侧或另一侧,具体取决于它运行的协议版本。 当然,这些分支永远不会再连接在一起。 这被社区认为是不可接受的,因为如果旧节点不升级他们的软件,它们实际上将被从比特币网络中删除。

软分叉。 我们可以对比特币进行的第二种更改是添加使验证规则更严格的功能。 也就是说,它们限制有效交易集或有效块集,以便旧版本将接受所有块,而新版本将拒绝一些。 这种变化被称为软分叉,它避免了硬分叉引入的永久分裂。

想象一下当我们引入一个改变软件版本的新软分叉时会发生什么。 运行新软件的节点将执行一些新的更严格的规则。 如果大多数节点切换到新软件,这些节点将能够执行新规则。 引入软分叉依赖于足够多的节点切换到协议的新版本,以便他们可以执行新规则,因为他们知道旧节点将无法执行新规则,因为他们还没有听说过。

老矿工冒着挖掘无效区块的风险,因为它们包括一些在新的、更严格的规则下无效的交易。 然而,较老的节点至少会发现他们的一些区块被拒绝了,即使他们不明白为什么。 这可能会促使他们的运营商升级他们的软件。 此外,如果他们的叉子被新矿工取代,老矿工将转向使用它。 这是因为新矿工认为有效的区块也被老矿工认为有效。 因此,不会有硬分叉; 相反,会有许多小的临时叉子。

通过软分叉进行更改的一个典型示例是 pay-to-script-hash,我们在本章前面讨论过。 Pay-to-script-hash 并未包含在比特币协议的第一个版本中。 这是一个软分叉,因为从旧节点的角度来看,有效的脚本支付哈希交易仍然会被正确验证。 正如旧节点所解释的那样,脚本很简单——它对数据值进行哈希处理并检查哈希值是否与输出脚本中指定的值匹配。 旧节点不知道(现在需要)运行值本身以查看它是否是有效脚本的额外步骤。 我们依靠新节点来执行脚本实际赎回此交易的新规则。

那么我们可以用软分叉添加什么? 支付给 Script Hash 成功。 也可以通过软分叉添加新的加密方案。 我们还可以向 Coinbase 参数添加一些额外的元数据以使其有意义。 今天,coinbase 参数接受任何值。 但是,将来我们可以说这个 coinbase 必须有一些特定的格式。 提出的一个想法是,在每个新区块中,coinbase 包含整个未花费交易集的树的 Merkle 根。 这只会导致软分叉,因为旧节点可能会在不需要新的 coinbase 参数的情况下挖掘被网络拒绝的区块,但它们会赶上并加入网络中正在挖掘的主链。

其他更改可能需要硬分叉。 诸如向比特币添加新的操作码、更改块或交易大小限制或各种错误修复之类的事情。 修复我们之前讨论的错误,MULTISIG 指令从堆栈中弹出一个额外的值,两者都需要硬分叉来实现。 这就是为什么,即使有一个严重的错误,将其放入协议并让人们解决它比对比特币进行硬分叉更改更容易。 即使它们很好,在当前的比特币气候下也不太可能发生硬分叉变化。 但是,从头开始,这些想法已经在替代加密货币中经过测试并证明是成功的。 我们将在第 10 章中更详细地讨论它。

侧边栏:比特币区块大小难题。 由于比特币越来越受欢迎,到2016年初,1M的区块被填满已经很普遍(特别是因为随机性,一个区块需要10多分钟才能找到) 一是导致部分交易需要等待对于一个或多个附加块进入区块链。 增加块大小限制将需要硬分叉。

是否以及如何解决区块链有限的交易带宽问题已经引起了比特币社区的足够重视。 这场讨论始于多年前,但已经升级为马戏团,在达成共识方面进展甚微,变得更加激进。 我们在第 7 章讨论比特币的社区、政治和治理。