区块时间戳的三条规则:矿工能写什么,节点又信几分 图 1
区块时间戳的三条规则:矿工能写什么,节点又信几分 · 图 1

时间戳是矿工填的,不是原子钟

每个比特币区块头占四个字节存放 Unix 时间戳,这个值由组装区块的矿工任意填写——网络里没有中央时钟,协议也不要求它等于真实时刻。矿工确有微调动机:更早的时间戳能让符合条件的相对时间锁交易更早生效,也能影响部分依赖时间的校验顺序。因此协议用一组规则把任意性压进可接受的范围。

第一条:区块时间戳必须严格大于前 11 个区块时间戳的中位数。这条规则被称为中位过去时间(MTP)约束。单个矿工最多少量挪动自己那一格,但中位数由前十一个块多数决定,想系统性把链上时间往前或往后推,就得同时掌握接近一半的出块能力并连续生效,成本远高于收益。第二条:时间戳不能比节点估算的”网络时间”超前两小时以上。比特币核心在握手阶段收集对端各自上报的本地时钟,取偏移中位数来修正”现在几点”,超出修正值两小时的区块会以时间过新的理由被拒收(对应的源码常数是 MAX_FUTURE_BLOCK_TIME,等于两小时)。第三点是对第二条的重要限定:时间过新的区块不是永久无效,它只是暂时不被接受——真实时间赶上来之后,同一个区块可以重新通过校验。这与共识性无效的区块有本质区别,也是它常被误读为”坏块”的原因。

节点自己的钟也必须靠谱

规则约束矿工之前先约束校验者。节点用对端报文的”现在”来校正本地时钟估计:多数对端一致时,采用经偏移校正的网络时间;能交换时间的对端过少时退回本地钟。这意味着一台时钟严重漂移的机器在时间校验上看到的”现在”与全网有偏差,表现为偶发的时间过新拒绝或钱包提前解锁判断失误。排查这类现象先查本机时钟同步服务,再怀疑区块,顺序错了会绕远路。

时间戳反过来定义了什么时刻是”现在”

更有意思的是这些规则的反身性:链上交易的锁定时间判断不读任何节点挂钟,读的是中位时间。绝对时间锁和相对时间锁交易问的不是”现实时间到没到”,而是”链尖的前 11 块中位数过没过那个点”(BIP113 之后内存池规则与此一致)。于是三件事串成闭环:矿工能改自己的时间戳但改不动中位数;中位数决定时间锁何时可花;难度调整也用中位数计算区间耗时,从而对矿工调时免疫。中位数的抗操纵性在这里发挥了关键作用——十一块窗口对应大约六块被改写的深度,而六块回滚在现实网络中几乎不成立。

实际观感:链上时间为什么毛糙

单个时间戳被允许在前后各一段时间带里游走,相邻块间隔的读数就会偏离十分钟均值,区块浏览器上的间隔图因此毛刺很多。把链上时间轴与现实时间轴叠起来看,长期一致、短期抖动,这是设计使然而非测量误差。看时间锁脚本能不能执行时,正确姿势是查目标高度对应的中位时间而不是翻日历;做对账系统时,则不应把区块时间戳当事件发生时刻——它只是”不早于中位数、不超前两小时”的粗粒度声明。

小结

比特币对时间的态度和对余额一样:不信任任何单一来源,用统计量代替权威。中位数守住过去,两小时上限守住未来,反身使用的中位时间锁把矿工的小动作锁死在自己那一格里。理解了这三条线,无论是调试时间锁脚本还是解读出块间隔图,都能找对参照物。