区块链自问自答 day5
区块链自问自答 day5
区块中的时间戳是怎么运作的?
“时间戳”是指从格林尼治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,通常是一个字符序列(Unix时间)。当区块被创造出来时,获得记账权的节点需要在区块头加盖时间戳,用于记录当前区块数据的写入时间。这个时间必须比之前的11个块时间的中间值大,并且比当前网络校准时间小2h。当前网络校准时间是指与你的节点相连的其他节点时间的中间值。当一个节点连接另外一个节点时,它会收到对方的Unix时间并保存与本地时间的偏差,最终的网络校准时间就是所有偏差的中间值加上本地时间,不过比特币协议规定偏差最大为70min。
需要注意的是,比特币的时间戳系统并非单调递增的,如块139793的时间戳是1312599459,而块139792的时间戳是1312599808,比139793大。这样产生的原因一方面可能是矿工节点时间未及时与标准时间同步;另一方面是在挖矿时,有时结果难以算出,矿工会通过调整时间戳的方式来降低挖矿难度。
比特币的时间有什么问题?
人们可能认为时间对于比特币网络并不是一项重要的考虑因素,因为每个区块都引用前一个区块的哈希值,所以这些区块已经有先后顺序。比特币区块还包含交易(输入、输出和值)、推导区块头的默克尔树(Merkle Tree)和区块哈希值本身,用于证明工作量。从表面上看,这对于交易和一致性系统也许已经足够。但是,存在调整难度的问题如果太多的矿工加入网络,区块时间可能变得太快,又或者如果太多的矿工离开,区块时间可能变得太慢,使得网络不可靠。为了解决这个问题,每两星期调整一次采矿难度,以实现区块之间十分钟的目标时间。遗憾的是,为了对两星期的时间进行计算,需要将时间概念引入区块链并成为一致性系统的一部分。因此区块必须含有时间戳,人们可以将比特币看作世界上第一个分布式电子时钟。
所以比特币的时间问题是发生在难度调整上,矿工通过调整时间戳的方式拉长区块的生成时间,欺骗难度调整机制将难度下调。
比特币是如何解决时间问题的?
在比特币区块产生时,实质上涉及两个时间:
- 区块头中的时间,是由矿工放置的
- 区块产生的实际时间。
当然,这两个时间应当几乎相同。毕竟,矿工们肯定有合理准确的时钟,他们为什么会在时间上撒谎呢?
矿工的确存在在时间上撒谎的诱因。比如,不法矿工可能会添加一个将来的时间戳。举例,如果生产一个区块要 10 分钟,矿工可以通过向将来添加 5 分钟的时间戳来声称花了 15 分钟。如果这种增加 5 分钟的做法在整个两星期的难度调整周期都持续 ,平均区块时间会看起来像是 15 分钟,而实际上比这要短。那么下一个周期的难度可能会向下调整,由于区块时间加快,增加采矿收入。当然,这种方法的问题在于,比特币时钟的移动继续与真实时间越来越远。
为了解决或减轻上述问题,比特币有两个机制防止矿工篡改时间戳。
过去时间中值(MPT)规则 - 时间戳必须比过去 11 个区块的中值更靠前。11 个区块的中值意味着可以对 6 个区块进行重组并且时间仍不会向后移动,有人可能认为这与 Meni Rosenfeld 的 2012 年报告中提供的例子是一致的,即对于拥有 10% 网络算力的攻击者,必须进行六次确认才能将攻击的成功概率降低到 0.1% 以下。
未来区块时间规则根据 - MAX_FUTURE_BLOCK_TIME 常量,相比来自同等节点的中值时间,时间戳不能出现在未来 2 小时以上。节点提供的时间与当地系统时钟之间的最大允许差是 90 分钟(又一个安全保障措施)。需要注意的是,不同于上面的 MPT 规则,这不是一个完全达成共识的规则。具有在未来太远时间点的时间戳的区块是无效的,但随着时间向前移动它们可能变得有效。
规则一确保区块链在时间方面继续向前 移动 ,而规则二确保区块链不会向前移动 太远。这些时间保护规则并不完美 ,例如,矿工仍可以在两星期时间内通过生成未来的时间戳,从而将时间戳向前移动,但这种操作的影响有限。
由于两个小时只是两星期中很小的一部分,此操作对网络可靠性和挖矿盈利 能力的影响可能有限。这相当于在难度调整后的两星期内,将区块之间的时间从 10 分钟减少至 9 分 54 秒。矿工在向前移动两个小时之前,可能会考虑安全边际,以减少区块被网络拒绝的风险。
多个矿工同时挖出下一个区块怎么办?
比特币中根据区块链的长度和工作量累积(消耗时间长度)决定哪一条链为主链,所以当多个矿工同时挖出区块时,长度相同其他矿工就会根据工作量指标选择在哪一个区块为父区块计算下一个区块。
当出现这种情况时区块链出现分叉的情况,也分为硬分叉和软分叉。通俗的说硬分叉的情况,是在区块链版本升级后,旧区块生成的区块后,更新版本的新区块拒绝验证旧节点的区块,或者新节点生成的区块旧节点拒绝验证。
软分叉的情况是更新版本后的区块无法验证旧节点生成的区块,但是旧节点能够全部或部分验证新节点生成的区块,导致新节点生成的区块能够组成更长的链,旧节点的短链则被放弃。