区块链提供了比特币的公共账本,这是一个有序的、带有时间戳的交易记录。这个系统用于防止重复消费和修改之前的交易记录。
Introduction
比特币网络中的每个完全节点都独立存储只包含该节点验证的块的区块链。当多个节点在他们的区块链中都有相同的块时,他们被认为达成了一致。这些节点遵循的用来保持一致性的验证规则被称为一致性规则。这一部分描述了比特币核心使用的许多一致性规则。
上面的插图展示了区块链的简化版本。一个或多个新的交易信息将会被收集到区块的交易数据部分。然后,每一笔交易都会被复制并进行哈希处理,这些哈希值接着会被配对,再进行哈希处理,如此反复,直到最后留下一个单独的哈希值,也就是 merkle 树的 merkle 根。
Merkle根被存储在区块头中。每个区块还存储了前一个区块头的哈希值,从而将所有区块链接在一起。这确保了无法修改交易记录,除非同时修改记录该交易的区块和所有后续区块。
交易也是相互链接的。比特币钱包软件给人的印象是,satoshis是从一个钱包发送到另一个钱包的,但实际上,比特币是从一个交易移动到另一个交易的。每一个交易都花费了在一个或多个早期交易中先前收到的satoshis,所以一个交易的输入就是前一个交易的输出。
注:"Satoshis"是比特币的最小单位,就像美元的最小单位是分一样。这个单位是为了纪念比特币的创始人中本聪(Satoshi Nakamoto)而得名。1比特币等于100,000,000 Satoshis。
单一交易可以创建多个输出,这就像是向多个地址发送时的情况,但是特定交易的每个输出在区块链中只能被使用一次作为输入。任何后续的引用都是被禁止的双重支出——尝试花费同样的satoshis两次。
输出与交易标识符(TXIDs)相绑定,这些标识符是签名交易的哈希值。
由于特定交易的每个输出只能被花费一次,所以包含在区块链中的所有交易的输出可以被分类为未花费交易输出(UTXOs)或已花费交易输出。要使支付有效,它只能使用UTXOs作为输入。
忽略coinbase交易(稍后会描述),如果交易的输出值超过其输入值,那么交易将被拒绝--但是,如果输入值超过输出值,任何价值的差额可以被创建包含该交易的区块的比特币矿工作为交易费用来获取。例如,在上述插图中,每笔交易消费的satoshis少于它从其合并输入中接收的,有效地支付了10,000 satoshi的交易费用。
Proof Of Work
区块链由网络上的匿名节点共同维护,因此,比特币要求每个区块都证明在其创建过程中投入了大量的工作,以确保那些想要修改已有区块的不信任节点需要比只想新增区块到区块链的诚实节点付出更多的努力。
将区块串联在一起使得修改任何区块中包含的交易无法在不修改所有后续区块的情况下完成。因此,修改特定区块的成本会随着新增到区块链的每个新区块而增加,从而放大了工作证明的效果。
比特币中使用的工作证明利用了密码学哈希的随机性特性。一个好的密码学哈希算法可以将任意数据转变成一个看似随机的数字。如果以任何方式修改了数据并重新运行哈希,就会生成一个新的看似随机的数字,因此,没有办法修改数据使哈希数字变得可以预测。
为了证明你为创建一个区块做了额外的工作,你必须创建一个区块头的哈希值,这个值不能超过某个特定值。例如,如果哈希值的最大可能值是2256 - 1,那么你可以通过产生一个小于2255的哈希值来证明你尝试了两种不同的组合。
在上述例子中,你平均每尝试两次就会成功产生一个哈希值。你甚至可以估计出给定的哈希尝试生成的数值小于目标阈值的概率。比特币假设,当它降低目标阈值时,将需要尝试的哈希尝试次数(平均)将线性增加。
只有当区块的哈希至少与共识协议预期的难度值一样具有挑战性时,新的区块才会被添加到区块链中。每生成2,016个区块,网络便使用存储在每个区块头部的时间戳来计算生成最后2,016个区块的第一个和最后一个之间流逝的秒数。理想的值是1,209,600秒(两周)。
- 如果生成2,016个区块花费的时间少于两周,那么预期的难度值会成比例地增加(最多可增加300%),这样在哈希以相同的速度进行检查的情况下,下一个2,016个区块的生成时间应该正好是两周。
- 如果生成区块的时间超过了两周,那么预期的难度值会成比例地降低(最多可降低75%),原因也是一样。
(注意:比特币核心实现中的一个差一错误导致难度每2016个区块就会更新一次,但是只使用2015个区块的时间戳,因此会产生少许偏差。)
因为每个区块头部必须哈希到目标阈值以下的值,并且因为每个区块都与它之前的区块链接在一起,所以平均来说,传播修改过的区块需要的哈希力量与从创建原始区块到现在的整个比特币网络所耗费的哈希力量相当。只有当你获得了网络哈希力量的大部分,你才能可靠地针对交易历史执行这样的51%攻击(尽管,值得注意的是,即使少于50%的哈希力量也有执行这样的攻击的好机会)。
区块头部提供了几个易于修改的字段,如专用的随机数字段,因此获取新的哈希不需要等待新的交易。另外,只有80字节的区块头部会被用于工作量证明的哈希,所以在一个区块中包含大量的交易数据不会因为额外的I/O减慢哈希速度,并且增加额外的交易数据只需要重新计算默克尔树中祖先哈希。
Block Height And Forking
成功将区块头哈希到目标阈值以下的比特币矿工可以将整个区块添加到区块链(前提是该区块其他方面均有效)。这些区块通常按照它们的区块高度来定位——它们与第一个比特币区块(区块0,通常称为创世区块)之间的区块数量。例如,区块2016是首次可以调整难度的地方。
在一个区块链分叉期间,多个区块可能同时具有相同的区块高度,这种情况通常发生在两个或更多的矿工几乎同时产生一个区块的时候。如上图所示,这在区块链中创建了一个明显的分叉。
当矿工在区块链的末尾同时产生区块时,每个节点都会独立选择接受哪个区块。在没有其他考虑因素的情况下,节点通常会使用他们首先看到的区块。
最终,有一个矿工会产生另一个区块,这个区块只连接到其中一个同时挖掘的竞争区块。这使得分叉的那一侧比另一侧更强。假设一个分叉只包含有效的区块,正常的节点总是遵循最困难的链复原,并抛弃属于较短分叉的陈旧区块。(这些陈旧的区块也有时被称为孤儿或孤儿区块,但这些术语也被用于没有已知父区块的真正的孤儿区块。)
如果不同的矿工做出相反的努力,比如一部分矿工努力延长区块链,而另一部分矽谷试图进行51%攻击来修订交易历史,那么长期的分叉是可能的。
由于在区块链分叉期间,多个区块可以具有相同的高度,因此区块高度不应该被用作全局唯一标识符。相反,区块通常是通过它们的头部的哈希来引用的(通常以字节顺序反转,并以十六进制表示)。
Transaction Data
每个区块都必须包含一个或多个交易。这些交易中的第一个必须是一个coinbase交易,也被称为生成交易,它应该收集和使用区块奖励(由区块补贴和本区块中包含的交易支付的任何交易费用组成)。
Coinbase交易的UTXO有一个特殊条件,那就是它不能被花费(作为输入)至少100个区块。这一点暂时防止矿工花费可能在区块链分叉后被确定为过时的区块的交易费用和区块奖励(因此coinbase交易被销毁)。
区块不需要包含任何非coinbase交易,但矿工几乎总是会包含额外的交易,以收集他们的交易费用。
所有的交易,包括coinbase交易,都被编码成二进制的原始交易格式的区块。
原始交易格式被哈希处理来创建交易标识符(txid)。从这些txid中,通过将每个txid与另一个txid配对,然后一起哈希来构建merkle树。如果txid的数量是奇数,没有伙伴的txid会与其自身的副本一起哈希。
生成的哈希本身每一个都与另一个哈希配对并一起哈希。任何没有配对的哈希会与其自身进行哈希。这个过程重复,直到只剩下一个哈希,也就是Merkle根。
For example, if transactions were merely joined (not hashed), a five-transaction merkle tree would look like the following text
如在简化支付验证(SPV)小节中所讨论的,merkle树允许客户端自己验证交易是否已被包含在块中,这通过获取一个块头的merkle根和一个完整节点的中间哈希列表来实现。完整节点不需要被信任:伪造块头很昂贵,而且如果中间哈希被伪造,验证将会失败。
例如,为了验证交易D已经被添加到块中,一个SPV客户端只需要复制C,AB,和EEEE哈希以及merkle根;客户端不需要了解任何其他交易的信息。如果这个块中的五笔交易都是最大大小,那么下载整个块将需要超过500,000字节 - 但下载三个哈希加上块头则只需要140字节。
注意:如果在同一块中发现相同的txid,可能会因不平衡的merkle树实施方式(复制孤独的哈希)产生碰撞,部分或所有重复项可能被移除。由于完全有相同的交易ID进行分开交易是不切实际的,所以这并不给诚实的软件带来负担,但是如果要缓存一个块的无效状态,就必须进行检查;否则,一个删除了重复项的有效块可能具有相同的merkle根和块哈希,但会因为被缓存的无效结果而被拒绝,导致安全漏洞,如CVE-2012-2459。
Consensus Rule Changes
为了维护共识,所有的全节点都使用相同的共识规则来验证区块。然而,有时候共识规则需要改变以引入新的功能或防止网络滥用。当新规则实施时,可能会有一段时间内部分未升级的节点依然遵循旧的规则,而升级的节点则遵循新的规则,这可能会导致共识的破裂,有两种可能的方式:
- 一个根据新的共识规则生成的区块,被升级的节点接收,但被未升级的节点拒绝。例如,一个区块中使用了新的交易功能:升级的节点理解这个功能并接收它,但未升级的节点会因为它违反了旧规则而拒绝它。
- 一个违反新的共识规则的区块,被升级的节点拒绝,但被未升级的节点接收。例如,一个区块中使用了滥用的交易功能:升级的节点因为它违反了新的规则而拒绝它,但未升级的节点因为它遵循旧的规则而接收它。
在第一种情况下,由于未升级的节点的拒绝,从这些未升级的节点获取区块链数据的挖矿软件拒绝与从升级节点获取数据的挖矿软件建立在同一条链上。这会导致永久分裂的链条——一条为未升级的节点,一条为升级的节点——这被称为硬分叉。
在第二种情况下,由升级的节点拒绝,在升级节点控制大部分哈希率的情况下,有可能防止区块链永久分裂。因为在这种情况下,未升级的节点会接受所有与升级节点一样的有效块,所以升级的节点可以建立一个更强大的链,未升级的节点会把它接受为最好的有效区块链。这就叫做软分叉。
尽管分叉是区块链实际发散的情况,但改变共识规则通常根据其可能导致硬分叉还是软分叉的潜力来描述。例如,“将区块大小提高到1MB以上需要硬分叉。”在这个例子中,实际的区块链分叉并非必需,但它是一种可能的结果。
共识规则的改变可能通过各种方式激活。在比特币的前两年,中本聪通过发布向后兼容的客户端而实现了几次软分叉,这种客户端立即开始执行新的规则。多次软分叉,如BIP30,已经通过预设的时间或区块高度开始执行新规则的标志日来激活。这种类型的分叉被称为用户激活的软分叉(UASF),因为他们依赖于在标志日后有足够的用户(节点)来执行新的规则。
后来的软分叉等待大部分哈希率(通常是75%或95%)来表示他们准备好执行新的共识规则。一旦达到信号阈值,所有节点都将开始执行新的规则。这种类型的分叉被称为矿工激活的软分叉(MASF),因为它们依赖于矿工进行激活。
Detecting Forks
非升级节点可能在两种类型的分叉期间使用并分发错误的信息,这可能导致多种财务损失的情况。特别是,非升级节点可能转发和接受升级节点认为无效的交易,因此永远不会成为公认的最佳区块链的一部分。非升级节点可能也会拒绝转发已经被添加到最佳区块链或即将被添加到的区块或交易,因此提供不完整的信息。
Bitcoin Core 包含一段通过查看区块链的工作证明来检测硬分叉的代码。如果一个非升级的节点接收到展示至少比它认为有效的最佳链多出六个区块的工作证明的区块链头,该节点会在“getnetworkinfo” RPC结果中报告警告,并运行设定的 -alertnotify 命令。这会警告操作者,非升级的节点无法切换到最可能的最佳区块链。
完整节点也可以检查区块和交易版本号。如果在几个最近的块中看到的块或交易版本号比节点使用的版本号高,它可以假设它没有使用当前的共识规则。Bitcoin Core 通过 "getnetworkinfo" RPC 和 如果设置的 -alertnotify 命令报告这种情况。
在任何情况下,如果数据来自一个明显不使用当前共识规则的节点,不应依赖区块和交易数据。
连接到完整节点的SPV客户端可以通过连接到几个完整节点并确保它们都在具有相同区块高度的同一链上,加上或减去几个区块以补偿传输延迟和过期块,来检测可能的硬分叉。如果存在分歧,客户端可以从链较弱的节点断开连接。
SPV客户端也应监视区块和交易版本号的增加,以确保它们使用当前的共识规则处理接收到的交易和创建新的交易。