Представь Timelock как правило «по этому пути — только позже». Оно может опираться на высоту блока, то есть его порядковый номер в цепочке, время из цепочки или задержку с момента подтверждения конкретного выхода. Выход — это сумма с правилами, кто и при каких условиях может её потратить. Ожидание не заменяет подпись или другие требования и само никуда не отправляет деньги. Важно также, ограничивает ли время только одну подготовленную транзакцию или этого требуют правила траты самих средств.
Анна и Павел могут устроить общие средства так, чтобы тратить их вместе в любой момент, а Анна одна — только после задержки. Если Павел перестанет отвечать, отложенная ветвь даст заранее согласованный путь возврата. Ветвь здесь означает один из разрешённых способов траты; у каждого могут быть свои условия. Поэтому блокировка необязательно закрывает все возможности сразу. Правила должны быть частью выхода уже при его создании. Недостаточно позднее добавить в обычном кошельке заметку «разблокировать через неделю». Даже после ожидания Анне понадобятся соответствующий ключ и данные для создания действительной транзакции. Timelock управляет доступом, но не восстанавливает потерянные ключи. [3]
Абсолютная блокировка задаёт фиксированную границу, записанную в поле nLockTime транзакции. Если действующий nLockTime транзакции равен высоте 1 000 000, первый блок, способный выполнить это условие, — 1 000 001: равенства ещё недостаточно. Относительная блокировка отсчитывает задержку с подтверждения расходуемого выхода. Если выход Анны создан в блоке 1 000 000, а нужная ветвь требует задержки 6 блоков, его трата может выполнить это условие не раньше блока 1 000 006. Это примеры чисел, а не текущая высота сети. Условия подписей, других входов и возможные дополнительные блокировки продолжают действовать. Шесть блоков — тоже не ровно час: они появляются через неравные интервалы. Относительное ожидание начинается не с создания кошелька и не с момента, когда Анна решила воспользоваться деньгами. [1] [2] [5]
Допустим, нужная задержка Анны только что истекла. Сеть не начнёт действовать за неё. Кто-то всё ещё должен создать транзакцию или использовать подготовленную, предоставить подписи, заплатить комиссию и передать её сети. Лишь тогда майнер может включить её в блок. Выполненный Timelock — одно выполненное условие, а не резервирование места или автоматический перевод. Обычно он определяет начало возможности потратить, а не момент её самостоятельного прекращения. При реорганизации часть цепочки заменяется другой действительной ветвью. Это может изменить подтверждение выхода и расчёт относительной задержки. Для собственной конструкции нужно заранее проверить все ветви, поддержку со стороны кошелька и резервные копии ключей и правил траты: время не исправит неправильно заданное условие. [2] [5]
Временные условия используют Median Time Past, сокращённо MTP. Для проверяемого блока это медиана временных меток последних 11 блоков, заканчивая предыдущим. Отсортируй времена и возьми среднее по позиции, шестое: это медиана, а не среднее арифметическое. Правило описывает BIP113, а Bitcoin Core применяет GetMedianTimePast. Значит, решающим является не текущее время телефона Анны и не метка предлагаемого блока. Полночь по календарю необязательно совпадает с выполнением блокировки. Условия по высоте ждут блоков, а не отсчитывают секунды. [4]
Теперь можно различить четыре названия из документации. nLockTime — поле всей транзакции для абсолютной границы. nSequence во входе содержит относительную задержку по BIP68. Но сам nLockTime не блокирует UTXO, то есть ещё не потраченный выход, от другой транзакции с иными настройками. Тот, кто вправе тратить, может создать её, если правила выхода не мешают. Bitcoin Script — язык, на котором записывают эти правила траты. Команда OP_CHECKLOCKTIMEVERIFY, или CLTV по BIP65, требует соответствующей абсолютной настройки в выбранной ветви. OP_CHECKSEQUENCEVERIFY, или CSV по BIP112, проверяет относительную настройку, а фактическую задержку обеспечивает BIP68. Ни CLTV, ни CSV не отправляют деньги и не добавляют отсутствующую подпись. Другая разрешённая ветвь может работать при других условиях. [1] [2] [3]
Следующие разделы — технический справочник. Поле означает данные, записанные в транзакции; вход ссылается на расходуемый выход. У каждого входа есть nSequence. Особое значение может отключить действие nLockTime, поэтому просто указать дату недостаточно. nLockTime — беззнаковое 32-битное поле; ноль отключает абсолютное временное условие. Если все входы используют SEQUENCE_FINAL со значением 0xffffffff, невыполненный nLockTime игнорируется. Для действующей абсолютной блокировки хотя бы один вход должен иметь другое значение nSequence. Оценивается эта конкретная транзакция, а не постоянная заморозка её входов. [5] [7]
Одно поле может выражать две разные вещи, разделённые числовым порогом. Unix timestamp — запись времени в секундах от начала 1970 года по UTC. Блок-кандидат — тот, куда должна была бы попасть проверяемая транзакция. LOCKTIME_THRESHOLD равен 500000000. Меньший nLockTime означает высоту блока, равное или большее значение — Unix timestamp. При включённой абсолютной проверке nLockTime должен быть строго меньше высоты блока-кандидата или соответствующего MTP. Равенства недостаточно; это не сумма, средняя высота или дата активации протокола. [5] [8]
Операнд — значение, переданное команде; opcode — сама команда Script. CLTV сравнивает требование ветви с настройкой транзакции. Достаточно ли продвинулась цепочка, определяет отдельная проверка. Это больше, чем сравнение сегодняшней даты с одним числом. OP_CHECKLOCKTIMEVERIFY требует неотрицательный операнд того же типа высота/время, что и nLockTime, со значением не больше nLockTime. Соответствующий расходующий вход не должен иметь nSequence 0xffffffff. Opcode не читает часы или высоту цепочки напрямую; настройки транзакции проверяются отдельно при оценке её временной действительности. Остальные условия Script по-прежнему обязательны. [1] [6]
Число nSequence содержит и срок ожидания, и переключатели его смысла. Бит — ноль или единица в этой записи; его установка может включать определённую возможность. Позиции битов ниже — часть формата, а не количество подтверждений. Для транзакций версии 2 или выше BIP68 включает относительное условие для входов без установленного бита 31. Нижние 16 бит задают задержку; бит 22 выбирает единицы по 512 секунд, иначе используются блоки. Блочная задержка отсчитывается от высоты подтверждения расходуемого выхода. Временная — от MTP блока перед его подтверждением до MTP перед блоком-кандидатом. Это не время с момента создания транзакции в кошельке. [2] [5]
CSV выполняет похожую проверку для относительного ожидания. Маска выбирает нужные биты nSequence, а disable flag — переключатель отключения. Lightning Network — сеть платёжных каналов: участники обновляют согласованное распределение совместно заблокированных средств. Задержка даёт другой стороне время отреагировать, если кто-то опубликует старое, уже отозванное состояние. Commitment transaction фиксирует распределение средств; ключ отзыва позволяет другой стороне потратить соответствующий выход отозванной версии через штрафную ветвь. OP_CHECKSEQUENCEVERIFY с активным неотрицательным операндом требует версию не ниже 2, снятый disable flag входа, одинаковый тип задержки и достаточное значение nSequence после применения маски. Фактический возраст отдельно проверяет BIP68. CSV позволяет отложенную ветвь восстановления. В выходе Lightning to_local задержка to_self_delay ограничивает владельца commitment transaction; другая сторона с правильным ключом отзыва может использовать штрафную ветвь без этой задержки. [3] [9]
Два почти одинаковых числа могут действовать по-разному. Приведённые значения с 0x записаны шестнадцатерично. NOP означает команду, которая здесь не добавляет временного ограничения. Важно и положение переключателя: во входе транзакции или в значении, переданном CSV. Бит 31 — SEQUENCE_LOCKTIME_DISABLE_FLAG; он отключает относительную интерпретацию BIP68 только для данного входа. Значение 0xfffffffe содержит его, но не является SEQUENCE_FINAL: оно допускает действующие nLockTime и CLTV. Значение 0xffffffff является final. Неотрицательный операнд CSV с установленным disable flag ведёт себя как NOP; такой flag во входе, однако, не выполняет активное требование CSV. Эти случаи нельзя смешивать. [3] [7]
RPC — команда для работы со своим узлом — программой, проверяющей блоки и транзакции Биткоина. Декодирование лишь превращает сохранённые данные в читаемый список; тестовая команда проверяет, прошла бы конкретная подписанная транзакция. Mempool — местный список ожидающих транзакций узла. RPC decoderawtransaction в Core 31 показывает version, locktime и sequence каждого входа. Для CLTV/CSV проверь фактически используемый Script и расходуемый выход; само декодирование не доказывает действительности. RPC testmempoolaccept проверяет подписанного кандидата относительно текущей цепочки, правил действительности Биткоина и местных правил приёма транзакций узлом, без приёма в mempool и без трансляции. Проверь allowed и причину отказа; успех не обещает будущего подтверждения. [10] [11] [12]
Для полной картины прочитайте эту статью вместе с CLTV, CSV, Lightning Network, Payment Channel, Транзакция, Bitcoin Script. На эту статью также ссылаются Подтверждение, Bitcoin Script, HTLC, CLTV.