协议演进 / BIP/比特币改进提案 / BIP-65

BIP-65 OP_CHECKLOCKTIMEVERIFY

把 NOP2 重新定义为 OP_CHECKLOCKTIMEVERIFY,让一个输出在达到某个区块高度或时间之前,由脚本本身保证不可花费。本 BIP 目前处于已激活状态。

一、档案卡

档案卡
编号BIP-65
标题OP_CHECKLOCKTIMEVERIFY
作者Peter Todd <[email protected]>
指定日期2014-10-01
层级Consensus (soft fork)(共识(软分叉))
类型Specification(规范类)
状态Deployed(已激活)
阅读版https://bips.dev/65
官方原文https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki

二、放在哪一族

BIP-65 是时间锁族里管“绝对时间”的那一份:锁的界限是一个具体的区块高度或时刻。交易自带的 nLockTime 字段早就存在,但它约束的是整笔交易何时能被挖出,约束不到单个输出“在某时刻之前谁都花不了”。

与它对照的是相对时间锁一族:BIP-68 给 nSequence 赋予“自所花输出被确认起算”的相对锁定语义,BIP-113 则为这类计算定义了中位过去时间(median-time-past)的取法。绝对锁看日历,相对锁看年龄,两者是互补关系。

部署机制上,它复用了 BIP-66 的双门槛 IsSuperMajority() 切换办法(见第四节)。

三、它要解决什么

nLockTime 能证明一件事:一笔花掉某输出的交易被构造出来了,因此“将来有可能花掉它”是成立的。

但 nLockTime 证明不了反过来的事:“在某时刻之前不可能花掉它”。因为无法排除有人已经在私下签好了另一笔花掉它的交易。

原文列的应用都建立在“可证明地暂时花不了”之上:

四、规则本身

4.1 语义:重新定义 NOP2

CHECKLOCKTIMEVERIFY 重新定义已有的 OP_NOP2。执行时,只要下列任一条件成立,脚本解释器就报错终止:

以上都不成立,脚本才像执行了一个 NOP 一样继续。原理是间接比较:nLockTime 本就保证交易在达到某高度或时间前不能被挖出,把脚本参数与 nLockTime 对比一致,就等于验证了期望的高度或时间已经达到;未达到之前,该输出不可花费。

4.2 数值细节

原文给出的参考实现里,CLTV 的参数按 CScriptNum 读取时特别允许最长 5 字节:普通数值操作码限于 4 字节会有 2038 年问题,而 nLockTime 本身是 uint32、要到 2106 年后才失去意义,放宽到 5 字节正好与 nLockTime 的上限对齐。参数若可能因先行运算变为负数,可先用 0 MAX 兜底。

锁类型以 LOCKTIME_THRESHOLD 区分:小于该阈值按区块高度,大于等于按时间,两边类型必须相同才能比较。

4.3 部署

复用 BIP-66 的双门槛 IsSuperMajority() 机制,门槛相同,但对应 nVersion = 4:某高度 H 的区块为 nVersion = 4、且其前 1000 个区块中至少 750 个 nVersion ≥ 4 时,新规则对该区块生效;当前 1000 个区块中 950 个达到 nVersion ≥ 4 后,nVersion < 4 的区块变为无效,此后所有区块强制执行新规则。

原文还提醒 SPV 客户端:它们虽不能整体验证区块,但能验证区块头、从而验证一部分部署规则;在 95% 门槛达到后,应拒绝 nVersion < 4 的区块,以免被未升级的少数矿工给出错误确认。

五、谁必须动

普通持币人:不必动。用不用 CLTV 取决于所用钱包是否构造这类脚本;普通转账不受影响。

钱包开发者:构造带 CLTV 的脚本时,须让花费交易的 nLockTime 与脚本参数同类型且不小于参数值,并保证对应输入的 nSequence 不是 0xffffffff,否则锁定会被绕开式地失效。

全节点与矿工:这是软分叉共识改动——升级后按新语义解释 NOP2 并参与版本门槛部署;未升级节点把 NOP2 仍当无操作,在软分叉的安全模型内跟随升级多数挖出的链。

共识层:脚本语义在此扩展:原本无意义的 NOP2 自激活起成为可使脚本失败的检查操作码,这是本 BIP 的全部共识改动。

六、现在算不算数,以及一个常见误读

状态为 Deployed,站点标注“已激活”。OP_CHECKLOCKTIMEVERIFY 是今天脚本里绝对时间锁的标准做法,托管、退款、通道类脚本中“到期后备路径”的写法都源出于此。

常见误读:

“上了 CLTV 锁的资金,到期会自动解锁、自动转走。”

不对。CLTV 只做一件事:在界限达到之前,让花费该输出的脚本执行失败。它不执行任何转账;到期之后,仍须有人构造一笔 nLockTime 与脚本参数匹配、且签名齐全的花费交易并广播上链,资金才会动。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。