区块确认
最后更新于
每个区块包含一个时间戳、一个随机数、一个对上一个区块的引用(即 哈希)和上一区块生成以来发生的所有交易列表。这样随着时间流逝就创建出了 一个持续增长的区块链,它不断地更新,从而能够代表比特币账本的最新状态。
依照这个范式,检查一个区块是否有效的算法如下:
1. 检查区块引用的上一个区块是否存在且有效。
2. 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来 2 小时[2]。
3. 检查区块的工作量证明是否有效。
4. 将上一个区块的最终状态赋于 S[0]。
5. 假设 TX 是区块的交易列表,包含 n 笔交易。对于属于 0……n-1 的所有i,进行状态转换 S[i+1] = APPLY(S[i],TX[i])。如果任何一笔交易 i 在状态转换中出错,退出程序,返回错误。
6. 返回正确,状态 S[n]是这一区块的最终状态。
本质上,区块中的每笔交易必须提供一个正确的状态转换,要注意的是, “ 状态” 并不是编码到区块的。它纯粹只是被校验节点记住的抽象概念,对于任意区块都 可以从创世状态开始,按顺序加上每一个区块的每一笔交易,(妥妥地)计算出当前的状态。另外,需要注意矿工将交易收录进区块的顺序。如果一个区块中有A、 B 两笔交易, B 花费的是 A 创建的 UTXO,如果 A 在 B 以前,这个区块是有效的,否则,这个区块是无效的。
区块验证算法的有趣部分是“ 工作量证明” 概念:对每个区块进行 SHA256 哈希处理,将得到的哈希视为长度为 256 比特的数值,该数值必须小于不断动态调整的目标数值,本书写作时目标数值大约是 2^190。工作量证明的目的是使区块的创建变得困难,从而阻止女巫攻击者恶意重新生成区块链。因为 SHA256 是完全不可预测的伪随机函数,创建有效区块的唯一方法就是简单地不断试错,不断地增加随机数的数值,查看新的哈希数值是否小于目标数值。如果当前的目标数值是 2^192,就意味着平均需要尝试 2^64 次才能生成有效的区块。一般而言,比特币网络每隔 2016 个区块重新设定目标数值,保证平均每十分钟生成一个区块。为了对矿工的计算工作进行奖励,每一个成功生成区块的矿工有权在区块中包含一笔凭空发给他们自己 25BTC 的交易。另外,如果交易的输入大于输出,差额部分就作为“ 交易费用” 付给矿工。顺便提一下,对矿工的奖励是比特币发行的唯一机制,创世状态中并没有比特币。
为了更好地理解挖矿的目的,让我们分析比特币网络出现恶意攻击者时会发生什么。因为比特币的密码学基础是非常安全的,所以攻击者会选择攻击没有被密码学直接保护的部分:交易顺序。攻击者的策略非常简单:
1. 向卖家发送 100BTC 购买商品(尤其是无需邮寄的电子商品)。
2. 等待直至商品发出。
3. 创建另一笔交易,将相同的 100BTC 发送给自己的账户。
4. 使比特币网络相信发送给自己账户的交易是最先发出的。
一旦步骤( 1)发生,几分钟后矿工将把这笔交易打包到区块,假设是第270000个区块。大约一个小时以后,在此区块后面将会有五个区块,每个区块间接地指向这笔交易,从而确认这笔交易。这时卖家收到货款,并向买家发货。因为我们假设这是数字商品,攻击者可以即时收到货。现在,攻击者创建另一笔交易,将相同的 100BTC 发送到自己的账户。如果攻击者只是向全网广播这一消息,这一笔交易不会被处理。矿工会运行状态转换函数 APPLY(S,TX),发现这笔交易将花费已经不在状态中的 UTXO。所以,攻击者会对区块链进行分叉,将第 269999 个区块作为父区块重新生成第 270000 个区块,在此区块中用新的交易取代旧的交易。因为区块数据是不同的,这要求重新进行工作量证明。另外,因为攻击者生成的新的第 270000 个区块有不同的哈希,所以原来的第 270001 到第 270005 的区块不指向它,因此原有的区块链和攻击者的新区块是完全分离的。在发生区块链分叉时,区块链长的分支被认为是诚实的区块链,合法的的矿工将会沿着原有的第 270005 区块后挖矿,只有攻击者一人在新的第 270000 区块后挖矿。攻击者为了使得他的区块链最长,他需要拥有比除了他以外的全网更多的算力来追赶(即 51%攻击)。