协议演进 / BIP/比特币改进提案 / BIP-68
BIP-68
给交易输入的 nSequence 字段赋予共识强制的相对锁定时间语义,让一笔输入在它所花输出被确认后的一段区块数或时间内不能被挖出。本 BIP 目前处于已激活状态。
一、档案卡
| 编号 | BIP-68 |
|---|---|
| 标题 | Relative lock-time using consensus-enforced sequence numbers |
| 作者 | Mark Friedenbach <[email protected]>, BtcDrak <[email protected]>, Nicolas Dorier <[email protected]>, kinoshitajona <[email protected]> |
| 指定日期 | 2015-05-28 |
| 层级 | Consensus (soft fork)(共识(软分叉)) |
| 类型 | Specification(规范类) |
| 状态 | Deployed(已激活) |
| 阅读版 | https://bips.dev/68 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki |
二、放在哪一族
BIP-68 是相对时间锁的共识地基。它与两份 BIP 捆绑部署、缺一不可(原文部署一节明确要求三者用同一部署机制同时上线):
BIP-112:OP_CHECKSEQUENCEVERIFY,让脚本内部也能检查相对锁定
BIP-113:中位过去时间(Median Time Past)用于 nLockTime 计算——BIP-68 里凡提到 median-time-past,都按 BIP-113 的定义
与 BIP-65 的分工是:BIP-65 管绝对界限(某高度 / 某时刻之前不可花),BIP-68 管相对年龄(所花输出被确认之后还要再等多少块或多久)。双向支付通道与哈希时间锁合约(HTLC)需要的是后者:退款与惩罚路径的时限都是相对押金确认时刻起算的。
三、它要解决什么
每笔交易的每个输入都有一个序列号(sequence number)字段。它最初的设想是交易替换:内存池里的交易可以用同一个输入、更高的序列值替换掉。它没有被正确实现,而且这个设想假定矿工会偏好高序列值、哪怕低序列值的交易更赚钱——只按利润行事的矿工会彻底打破这一假定。
BIP-68 的做法是把序列号改作他用,又不破坏既有功能:当时参考客户端对序列号的唯一实际使用,是“把一笔交易所有输入的 nSequence 都设为最大值以关闭 nLockTime 检查”,这一语义被完整保留(见第四节的禁用标志)。
对比着看就清楚了:nLockTime 防的是“在某个日期之前被挖出”;nSequence 经本 BIP 改作“在所花输出达到某个年龄之前被挖出”。原文说,这一能力连同其他用途,使得双向支付通道成为可能。
四、规则本身
4.1 适用范围
本规范定义的语义只适用于 nVersion ≥ 2 的交易;且不适用于 coinbase 交易输入的 nSequence 字段。
4.2 编码
- 禁用标志(1 << 31):若序列号的这一位被置位,序列号不承载任何共识含义,在一切情形下都可被打进区块。把 nSequence 设为 0xffffffff(SEQUENCE_FINAL)正是借此关闭相对锁、并同时关闭 nLockTime 检查,与原有用法衔接;
- 类型标志(1 << 22):禁用标志未置位时,序列号被解释为编码过的相对锁定时间;这一位决定单位——置位为时间型,未置位为区块型;
- 取值掩码 0x0000ffff:实际只解释序列号的低 16 位,提取时必须施加该掩码。16 位可编码约一年的相对锁定:区块型 0 至 65,535 个区块(原文计约 1.25 年),时间型不足 33,554,431 秒(约 1.06 年)。
未被用到的位是刻意留白:第 16 至 21 位未用,可供将来以软分叉提高粒度或上限;禁用标志未置位时,第 23 至 30 位也没有含义。
4.3 两种相对锁的起算
- 区块型:相对锁定 n 表示该输入可在所花输出被挖出之后第 n 个区块起被包含;n 为 0 则任何区块都可;
- 时间型:以 512 秒为粒度(换算即把 16 位值左移 9 位、乘以 512)。选 512 秒是因为区块平均每 600 秒产生一个,这样区块型与时间型用相同位数能编码相近的时长。起算点是所花输出所在区块的前一区块的中位过去时间(MTP);候选区块的“产生时间”则取其前一区块的 MTP。相对时间锁为 0 表示可进任何区块。
那一位类型标志(1 << 22)同时是 3 字节有符号整数的最高位,原文说这是为了能把同一编码以 3 字节 PUSHDATA 形式与 BIP-112 的 OP_CHECKSEQUENCEVERIFY 配合使用。
4.4 部署
用 BIP-9 的 versionbits 机制、占用 bit 0 部署,且必须与 BIP-112、BIP-113 同时部署。原文给出的参数:主网 starttime 为 2016 年 5 月 1 日午夜 UTC(时间戳 1462060800),timeout 为 2017 年 5 月 1 日午夜 UTC(1493596800);测试网 starttime 为 2016 年 3 月 1 日午夜 UTC(1456790400),timeout 同为 2017 年 5 月 1 日。
五、谁必须动
普通持币人:无直接变化。日常交易的输入序列号通常取终局值,不触发相对锁语义。
钱包与协议开发者:要做相对延迟花费(通道退款、HTLC 等),就要按本规范编码 nSequence:版本至少为 2、禁用标志不置位、按需要选区块型或时间型,并知道时间型只有 512 秒粒度。
全节点与矿工:这是软分叉共识改动:升级节点在验证区块时计算每个输入的相对锁定是否已满足,未满足的交易不能被打进区块。
共识层:nSequence 从“仅用于关闭 nLockTime 的信号位”升级为可强制执行的相对时间锁字段,这是自激活起的共识语义。
六、现在算不算数,以及一个常见误读
状态为 Deployed,站点标注“已激活”。BIP-68 与 BIP-112、BIP-113 一起构成现行相对时间锁的共识基础,支付通道类协议的时限安排建立在它之上。
常见误读:
“相对锁定时间是从我签好这笔交易那一刻开始倒计时的。”
不对。相对锁的起算点是所花输出被确认(被挖出)的时刻——区块型数的是此后的区块数,时间型比的是此后流逝的中位过去时间。交易在内存池里放多久、签得有多早,都不计入这段等待。
七、延伸
- 阅读版:https://bips.dev/68
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
- 相关:BIP-112 OP_CHECKSEQUENCEVERIFY、BIP-113 中位过去时间、BIP-65 绝对时间锁、BIP-9 versionbits 部署
- 仓库总目录:https://github.com/bitcoin/bips
