术语表 /协议与升级
OP_CHECKLOCKTIMEVERIFY
又称 CLTV、BIP65。
- OP_CHECKLOCKTIMEVERIFY 是什么?
- OP_CHECKLOCKTIMEVERIFY 是一种脚本操作码,无论由谁持有密钥,它都能阻止一枚比特币在指定的区块高度或日历日期之前被花费。
规定于 BIP-65。
这是一种写入币本身、而不是写入花费它的交易中的时间锁。Peter Todd 在 BIP65 中提出了该规范,它取代了旧的空操作码 NOP2 的位置,这条规则自2015年12月的区块388,381起一直在执行。如果您设置过继承方案或恢复路径,让这扇门保持关闭的就是这个操作码。
运作方式
OP_CHECKLOCKTIMEVERIFY 从脚本堆栈中读取一个数字,将其与试图花费该币的交易的 locktime 字段比较,如果花费过早,就中止整个脚本。
BIP65 列出了检查失败的五种情形:堆栈为空,栈顶元素为负数,该元素与交易的 locktime 在按区块计数还是按秒计数上不一致,该元素大于交易的 locktime,或者输入的序列号被设置为0xffffffff。最后一个条件堵住了一个明显的漏洞。当所有输入都被标记为最终状态时,locktime 会被完全忽略,因此如果没有这一条件,花费者只需关闭截止时间,就能带着资金离开。
初次阅读此类脚本的人会对两个细节感到意外。该操作码不会消耗它所检查的数字,因此实际脚本会在其后加上 OP_DROP 来整理堆栈。它还接受五字节的操作数,而不是通常的四字节,因为它可能需要比较的最大值是2**32-1,即它所检查的字段的完整取值范围。
软分叉的机制属于常规类型。重新定义一个空操作码,对尚未升级的软件是不可见的:旧节点执行该操作码,什么也不做,仍然接受该区块。激活采用了当时的矿工信号阈值,每1,000个区块中有750个开始执行,每1,000个区块中有950个则强制执行。
在哪里会遇到它
凡是资金必须保持不动、直到某个日期到来的地方,都会用到 OP_CHECKLOCKTIMEVERIFY。
继承钱包和恢复钱包是最明显的例子。描述符可以规定,您自己的密钥随时可以花费,而备份密钥只有在指定区块高度之后才能花费,这为继承人提供了一条无需任何人配合、也无需律师保管密封信封的路径。Miniscript 将其写成 after() 片段,支持它的钱包会用通俗的语言向您显示区块高度,而不是原始脚本。
闪电网络用它来设定路由支付的绝对截止时间。BOLT11 发票带有最终到期增量,默认为18个区块,沿路由设置的哈希合约叠加在该数值之上,这样一来,如果支付始终未能完成,每一跳都可以按固定顺序收回自己的资金。
担保托管和无需信任的退款也是同样的结构:现在向脚本付款,如果对手方一直不签名,截止时间过后即可取回资金。对于任何把“时间锁保险库”当作产品出售的人,这个操作码也是诚实的回答,因为此类产品所能做的就是这些。
OP_CHECKLOCKTIMEVERIFY vs OP_CHECKSEQUENCEVERIFY
OP_CHECKLOCKTIMEVERIFY 指定的是一个时刻,OP_CHECKSEQUENCEVERIFY 指定的是一段时长。前者表示“12月之前不行”,后者表示“在这枚币确认后的144个区块之前不行”,只有后者的计时从币到账时开始。BIP112 定义了相对形式,它在2016年7月的区块419,328激活,比其绝对形式的同类操作码晚了大约七个月。合约协议两者都会用,常常出现在同一个脚本中:用绝对截止时间限定整个协议的期限,用相对延迟保证一方有时间做出反应。