Глоссарий / Протокол и обновления
OP_CHECKLOCKTIMEVERIFY
Другие названия: CLTV, BIP65.
- Что такое OP_CHECKLOCKTIMEVERIFY?
- OP_CHECKLOCKTIMEVERIFY представляет собой опкод скрипта, который не дает потратить монету раньше указанной высоты блока или календарной даты, кто бы ни владел ключом.
Определено в BIP-65.
Блокировка по времени, записанная в самой монете, а не в транзакции, которая ее тратит. Peter Todd описал ее в BIP65, где она заняла место старого опкода-пустышки NOP2, и это правило применяется с блока 388 381 в декабре 2015 года. Если вы когда-либо настраивали план наследования или путь восстановления, этот опкод и есть то, что держит дверь закрытой.
Как это работает
OP_CHECKLOCKTIMEVERIFY читает одно число из стека скрипта, сравнивает его с полем locktime транзакции, которая пытается потратить монету, и прерывает весь скрипт, если трата происходит раньше срока.
BIP65 перечисляет пять случаев, когда проверка не проходит: стек пуст, верхний элемент отрицателен, элемент и locktime транзакции расходятся в том, считают они блоки или секунды, элемент больше locktime транзакции, или номер последовательности входа равен 0xffffffff. Последнее условие закрывает очевидную дыру. Locktime полностью игнорируется, когда все входы помечены как финальные, поэтому без него тратящий мог бы просто отключить срок и забрать деньги.
Две детали удивляют тех, кто впервые читает такой скрипт. Опкод не потребляет проверяемое число, поэтому настоящие скрипты ставят после него OP_DROP, чтобы привести стек в порядок. И он принимает пятибайтовый операнд вместо обычных четырех, потому что наибольшее значение, с которым ему, возможно, придется сравнивать, равно 2**32-1, полный диапазон проверяемого поля.
Механика мягкого форка была обычной. Переопределение опкода-пустышки незаметно для программ, которые не были обновлены: старый узел выполняет опкод, ничего не делает и все равно принимает блок. Активация использовала тогдашние пороги сигнализации майнеров: 750 блоков из 1000, чтобы начать применять правило, и 950 из 1000, чтобы сделать его обязательным.
Где это встречается
OP_CHECKLOCKTIMEVERIFY встречается везде, где деньги должны оставаться на месте до наступления даты.
Кошельки наследования и восстановления являются самым наглядным случаем. Дескриптор может указывать, что ваш собственный ключ тратит в любое время, а резервный ключ тратит только после указанной высоты, что дает наследнику путь, не требующий ничьего содействия и никакого юриста с запечатанным конвертом. Miniscript записывает это как фрагмент after(), а кошельки, которые его поддерживают, показывают вам высоту обычным языком вместо сырого скрипта.
Lightning использует его для абсолютного срока маршрутизируемого платежа. Счет BOLT11 несет конечную дельту истечения, по умолчанию 18 блоков, а хешированные контракты вдоль маршрута выстраиваются над этой цифрой, чтобы каждый переход мог вернуть свои средства в фиксированном порядке, если платеж так и не завершится.
Эскроу и возвраты средств без доверия к контрагенту имеют ту же форму: заплатите в скрипт сейчас, и если контрагент так и не подпишет, верните деньги, когда срок пройдет. Опкод также является честным ответом любому, кто продает «сейф с блокировкой по времени» как продукт, потому что только этим такой продукт и может быть.
OP_CHECKLOCKTIMEVERIFY vs OP_CHECKSEQUENCEVERIFY
OP_CHECKLOCKTIMEVERIFY называет момент; OP_CHECKSEQUENCEVERIFY называет длительность. Один говорит «не раньше декабря», другой говорит «не раньше чем через 144 блока после подтверждения этой конкретной монеты», и только второй запускает свои часы, когда монета поступает. BIP112 определил относительную форму, и она активировалась на блоке 419 328 в июле 2016 года, примерно через семь месяцев после своей абсолютной родственницы. Протоколы контрактов используют обе, часто в одном скрипте: абсолютный срок, ограничивающий все соглашение, и относительная задержка, гарантирующая одной стороне окно для реакции.