Временные замки Биткоина

Биткоин, не имеющий видимых недостатков, оснащен несколькими различными временными блокировками. Эти инструменты позволяют вам указывать временные условия, при которых транзакции действительны. Используя временные блокировки, вы совершаете транзакцию сейчас, которая принесет кому-то оплату на следующей неделе, добавляете обязательный период ожидания для движения монет, настраиваете сложные смарт-контракты, которые охватывают несколько транзакций, или случайно блокируете ваши монеты на века.

Большинство из этих временных блокировок были добавлены в Биткоин совсем недавно. Они встроены в структуру транзакций и имеют немало особенностей, оставшихся от ошибочного кода, написанного нашим любимым анонимным шифропанком г-ном Накамото. Соответствующие предложения по улучшению Биткоина (BIP) прекрасны и подробны, но предполагают наличие большого количества базовых знаний. Это попытка собрать всю информацию, которую я могу найти о временных замках, и объяснить ее подробно.

Временные замки Биткоина

Классификация временных замков

Прежде чем мы углубимся в сами инструменты, давайте разберемся, как описать их работу. Временные блокировки имеют три важных атрибута: местоположение, таргетинг и показатель.

Местоположение: транзакция против скрипта

Время – это самое большое расстояние между двумя местами.

— Теннесси Уильямс

Временные блокировки можно найти в самой транзакции и/или в связанных с ней сценариях входа Pay to Script Hash (P2SH). Каждая транзакция имеет несколько полей блокировки времени (они присутствуют, даже если не используются). С другой стороны, сценарии могут иметь ноль или множество временных блокировок. С точки зрения функциональности блокировки на уровне транзакций и на уровне сценариев внешне похожи, но выполняют совершенно разные роли. Блокировки времени на уровне транзакции делают транзакцию недействительной до определенного момента, независимо от действительности подписей и сценариев. Блокировки времени на уровне сценария приведут к сбою оценки сценария, если транзакция также не заблокирована. Неудачная оценка сценария делает транзакцию недействительной. Короче говоря, блокировки уровня транзакции определяют, когда транзакция может быть подтверждена, тогда как блокировки уровня сценария определяют, действителен ли данный сценарий.

Основное различие между ними заключается в том, что именно они блокируют. Блокировка на уровне транзакции ограничивает только конкретную транзакцию. Думайте о блокировках на уровне транзакций как о чеке, датируемом будущим: я могу выписать вам чек, который станет действительным позже, но дата применяется только к этому чеку, и я могу потратить деньги другими способами, о которых вы не знаете. Блокировки на уровне сценария устанавливают условия для всех транзакций, использующих выходные данные. Другими словами, блокировки уровня транзакции влияют на то, что вы можете делать с транзакцией после ее создания, но блокировки уровня сценария определяют, какие транзакции можно совершать в первую очередь.

Блокировки транзакций не так полезны, как вы думаете. Они не контролируют монеты, а только тратят. Вот почему для всего интересного требовались OP_CLTV и OP_CSV. Используя блокировки уровня сценария и условную логику (OP_IF), мы можем создавать сложные сценарии, которые могут, например, разрешать использование нескольких подписей в любое время или использование одной подписи по прошествии определенного периода времени. Это обеспечивает большую гибкость транзакций P2SH.

Блокировки времени на уровне сценария требуют, чтобы также была включена соответствующая блокировка времени на уровне транзакции. Принудительные блокировки на уровне сценариев основаны на блокировках на уровне транзакций. Вместо проверки времени внутри сценария блокировки на уровне сценария проверяют блокировку транзакции. Это элегантно и экономично, хотя и немного неинтуитивно. Скрипт проверяет, что транзакция заблокирована как минимум на протяжении пути сценария. Он рассматривает блокировку транзакции как гарантию того, что время прошло.

Таргетинг: абсолютный или относительный

Время — иллюзия, а обеденное время — вдвойне.

– Дуглас Адамс

Ну, на самом деле, они оба относительны. Вы можете выбрать произвольную исходную точку или относительно предыдущего результата. Но именно такой бессмысленный педантизм я люблю.

Когда мы блокируем монеты, мы ставим цель их выпуска. Абсолютные  блокировки определяют эту цель в терминах установленного времени. Они выбирают точный момент истечения срока действия блокировки. Блокировки относительного  времени определяют его как количество времени, прошедшее с момента подтверждения предыдущего вывода. В этом разница между «встретимся в 15:00» и «встретимся через 4 часа».

Транзакции, привязанные к абсолютному времени, недействительны, пока это время не истечет. Это означает, что я могу совершить транзакцию на несколько лет вперед, подписать ее, поделиться ею и даже опубликовать ее публично с гарантией, что она не будет подтверждена до истечения срока ее блокировки. Я мог бы использовать абсолютную временную метку, чтобы отправить деньги своим детям или создать сберегательный счет, на который вы можете внести деньги, но не сможете снять их до следующего года.

Относительные блокировки, с другой стороны, помечают транзакцию недействительной до тех пор, пока не пройдет определенное время с момента подтверждения предыдущих выходов транзакции. Это тонкая и мощная функция. Настоящая красота относительного времени блокировки заключается в установке блокировок относительно  нетранслируемых и неподтвержденных  транзакций. Как только транзакция подтверждена, мы всегда можем установить абсолютное время блокировки в будущем. Но для этого вам нужно дождаться подтверждения и узнать время подтверждения. Или заранее установите длинную блокировку, которая становится сроком действия всего вашего смарт-контракта. Относительные блокировки могут быть установлены для неподтвержденных транзакций. Это означает, что вы можете заранее создать и подписать весь многоэтапный смарт-контракт и быть уверенным, что его транзакции будут подтверждены в том порядке, в котором вы ожидаете,  независимо от того, когда вы его выполняете.

Временные замки Биткоина

Метрика: блоки и секунды

Тогда время от времени летит –

Словно время летит стрелой.

— Эдисон Б. Шредер

В Биткоине время — это согласованная галлюцинация, и время обеда никогда не наступает. Транзакции не могут точно смотреть на часы на стене, поэтому нам нужно решить, что такое «время». Биткоин имеет два способа измерения «времени»: номер блока и временную метку блока. Они были реализованы как режимы работы для каждого временного замка, а не как отдельные механизмы блокировки. Вы можете указать количество  блоков  для блокировки или количество  секунд . И то, и другое имеет свои сложности. На практике обе эти метрики достаточно точны для реального использования. Но важно понимать их особенности.

Мы часто говорим, что блоки следуют распределению Пуассона: ожидается, что они будут появляться каждые 10 минут. Но это не совсем правильно. Когда хэш-мощность увеличивается, блоки появляются быстрее, чем ожидалось. Хэш-мощность отключается или направляется на другие цепочки, блоки приходят медленнее. Сложность корректируется каждые 2016 блоков (примерно каждые 2 недели) до целевых 10 минут, но блоки могут значительно отклоняться от того места, где вы ожидаете, из-за условий сети или просто случайности.

Временные метки столь же привередливы. Видите ли, в Биткоине время не всегда движется вперед. Из-за согласованных правил для временных меток блоков время может иногда меняться на один или два блока. Или просто остановитесь на минутку. Для этого есть причины, я обещаю. Оно почти всегда остается в пределах пары часов от «реального» времени. Несмотря на это, чтобы сделать блокировки на основе временных меток надежными, они измеряют с использованием метода «среднего времени прошедшего» (MTP), описанного в  BIP 113 . Вместо использования временной метки текущего блока блокировки на основе временной метки используют медианную временную метку предыдущих 11 блоков. Это сглаживает ход времени и гарантирует, что время никогда не пойдет вспять.

Временные замки Биткоина

Замки

Теперь, когда мы понимаем, о чем говорим, давайте поговорим о самих инструментах. Сейчас существует четыре варианта блокировки по времени: nLocktime, nSequence, OP_CHECKLOCKTIMEVERIFY (OP_CLTV) и OP_CHECKSEQUENCEVERIFY (OP_CSV). Два из них относятся к уровню сценария, два — к уровню транзакции.

nLocktime

nLocktime — это  блокировка абсолютного времени на уровне  транзакции  . Это также единственный временной замок, который был частью оригинального видения Сатоши (SOV).

Транзакция — это простая структура данных, содержащая поля для версии, входов, выходов и некоторых других вещей. У nLocktime есть свое специальное поле  lock_time. Он указывает номер блока или отметку времени. Транзакция недействительна до истечения этого времени. В транзакциях, совершаемых ядром Биткоина, поле  lock_time по умолчанию установлено на текущий блок, чтобы  предотвратить снятие комиссий . Время выражается как 32-битное целое число без знака. Если  time_lock равен 0, он игнорируется. Если оно равно 500 000 000 или выше, оно рассматривается как временная метка Unix. Таким образом, nLocktime может блокировать транзакции на 9500 лет, используя номера блоков, или до  2106 года  , используя временные метки.

Любопытно, что это  lock_time поле полностью игнорируется, если все входные данные имеют порядковый номер  0xFFFFFFFF (максимум для 32-битного целого числа). Сигналы о добровольной замене по плате (RBF) аналогичны описанным в  BIP 125 . Использование  sequence_no to signal — это артефакт недоделанной реализации блокировки времени Сатоши. И на этом этапе нам придется провести хард-форк, чтобы это изменить. Первоначально предполагалось, что nLocktime и порядковые номера ввода создадут простой механизм обновления транзакций. Идея заключалась в том, что вы могли создать транзакцию со временем блокировки, а затем заменить ее, отправив новую версию хотя бы с одним более высоким порядковым номером.

Майнеры должны были удалять транзакции с меньшими порядковыми номерами из мемпула. Если все входы имели максимальный порядковый номер, это означало, что обновлений больше не было, и транзакция могла быть очищена независимо от временной блокировки. Это так и не было полностью реализовано, а затем от него отказались. Судя по странной ошибке, Сатоши, похоже, принял хорошее поведение, что не является разумным предположением в Биткоине. Невозможно гарантировать, что майнеры увидят обновленные транзакции или удалят старую версию, если увидят новые. Майнеры будут майнить самую прибыльную версию транзакции, а не самую последнюю.

Примеры nLocktime :

# Most of the transaction is omitted. Using decimal for human readability.
# Using hex for sequence numbers due to the presence of flags.

# Transaction is invalid until block 499999999 (this is a Bad Idea)
tx_1:  
  lock_time: 49999999    

# Transaction is invalid until the MTP is 1514764800 (1/1/2018 0:00:00 GMT)
tx_2:  
  lock_time: 1514764800  

# No lock time. Transaction is valid immediately.
tx_3:  
  lock_time: 0           

# nLocktime lock is not in effect, because all sequence numbers are set to 0xFFFFFFFF
tx_4:  
  lock_time: 3928420
  input_1:
    sequence_no: 0xFFFFFFFF

nSequence

nSequence — это  относительная блокировка времени на уровне  транзакции  (технически nSequence на самом деле является уровнем ввода, об этом позже). Он переназначает старое   поле каждого входа для признания транзакций недействительными на основе времени, прошедшего с момента подтверждения предыдущих выходов. Блокировки nSequence были представлены в  BIP 68  и активированы софт-форком в середине 2016 года. Сатоши дал нам лимоны, и мы сделали временные блокировки nSequence.sequence_no

Порядковые номера существуют с самого начала. Но поскольку замена транзакций так и не была реализована (и в любом случае не сработала бы в долгосрочной перспективе), они стали бесполезными. В течение многих лет единственное, что они могли сделать, это отключить nLocktime. Теперь порядковые номера используются для обеспечения блокировки относительного времени на уровне транзакции, как описано в BIP 68. Блокировки последовательности устанавливаются на каждом входе и измеряются по выходным данным, которые потребляет каждый вход. Это означает, что для одной транзакции можно указать несколько разных условий временной блокировки. Для того чтобы транзакция была действительной, должны быть выполнены все условия. Если не будет соблюдена хотя бы одна блокировка последовательности, вся транзакция будет отклонена.

Разработчики биткоинов великолепно умеют перерабатывать, но иногда у вас остается несколько сучков на дереве. Поскольку временные блокировки nSequence переназначают существующее  sequence_no поле, у них есть несколько особенностей. Поле последовательности имеет длину 32 бита, но мы не можем использовать их все, так как это будет мешать передаче сигналов nLocktime и RBF. Кроме того,  sequence_no это одно из немногих мест, где у нас есть возможность вносить будущие изменения. Чтобы сбалансировать эти требования, nSequence был создан для использования только 18 из 32 битов. Это сохраняет 14 бит для любого будущего использования, которое мы можем придумать.

Два бита — это флаги, которые сообщают узлу, как интерпретировать  sequence_no поле. Самый важный бит — это флаг отключения. Если установлен флаг отключения, блокировки nSequence отключены. Если флаг отключения не установлен, остальная часть поля  sequence_no интерпретируется как относительное время блокировки. Бит 22 (23-й наименее значимый бит) — это флаг типа. Если флаг типа установлен, блокировка указывается в секундах. Если флаг типа не установлен, блокировка указывается в блоках.

Младшие 16 битов  sequence_no используются для кодирования целевого времени. В отличие от nLocktime, nSequence использует только 16 бит для кодирования времени блокировки. Это означает, что время блокировки nSequence ограничено 65 535 единицами. Это позволяет блокировать примерно до 455 дней при использовании блоков, но в секундах это позволит заблокировать только около 18 часов. Чтобы смягчить это, nSequence не измеряет время в секундах. Вместо этого он использует фрагменты по 512 секунд. Если установлен флаг типа и время блокировки установлено на 16 единиц, вход будет заблокирован до тех пор, пока не истечет 16 * 512 секунд.

По умолчанию для транзакций, совершаемых Bitcoin Core, для  sequence_no каждого входа установлено значение  0xFFFFFFFE. Это позволяет nLocktime препятствовать снятию комиссий, как описано выше, и отключает функцию замены по комиссии. В транзакциях «Замена по комиссии»  sequence_no для каждого входа обычно установлено значение  0xFFFFFFFD. На этом этапе стоит отметить, что RBF — это  не  изменение протокола, а всего лишь изменение политики майнинга по умолчанию. Однако, поскольку блокировки nSequence требуют, чтобы  sequence_no поле было установлено меньше, чем  0xFFFFFFFD оно имело смысл, все заблокированные транзакции nSequence выбирают RBF.

Примеры последовательностей :

# Most of the transaction is omitted. Using decimal for human readability.
# Using hex for sequence numbers due to the presence of flags.

# This transaction is locked for 4096 second. Just over 1 hour.
tx_1:  
  input_1:
    sequence_no: 0x00400008
    # Disable flag is not set, type flag is set. Input locked for 8 * 512 seconds.

# This transaction is not nSequence locked, but may be nLocktime locked, and allows RBF.
tx_2:  
  input_1:
    sequence_no: 0xFEDC3210
    # Disable flag is set. nSequence locking disabled.


# This transaction is invalid until 16 blocks have elapsed since input_1's prevout confirms.
tx_3:  
  input_1:
    sequence_no: 0x00000010  
    # Disable flag is not set, type flag not set. This input locked for 16 blocks.
  input_2:
    sequence_no: 0xFFFFFFFF  
    # Disable flag is set.

# This transaction is not time locked, but has opted to allow Replace-By-Fee.
tx_4:  
  lock_time: 0
  input_1:
    sequence_no: 0xFFFFFFFE  
    # nSequence is disabled, nLocktime is enabled, RBF is not signaled.
  input_2:
    sequence_no: 0xFFFFFFFD  
    # nSequence is disabled, nLocktime is enabled, RBF is signaled.

# This transaction is not valid until block 506221
# It is also not valid until 87040 seconds have passed since the confirmation of input_1's previous output
tx_5:  
  lock_time: 506221
  input_1:
    sequence_no: 0x004000AA
Временные замки Биткоина

OP_CLTV

OP_CHECKLOCKTIMEVERIFY (OP_CLTV) — это  абсолютная блокировка времени на уровне  сценария  . Он был подробно описан в  BIP 65  и был реализован в основной сети в конце 2015 года. OP_CLTV включал  хэшированные контракты с временной блокировкой  и, следовательно, был жестким требованием для первой версии каналов Lightning.

Его  исходный код  прост и элегантен и содержит менее 20 строк чистого, великолепно прокомментированного кода. Проще говоря: OP_CLTV сравнивает верхний элемент стека с nLocktime транзакции. Он проверяет, что верхний элемент стека имеет допустимое время в секундах или блоках, и что сама транзакция заблокирована как минимум на этот срок с помощью соответствующего файла  lock_time. Таким образом, OP_CLTV проверяет, что транзакция не может быть подтверждена до определенного времени.

OP_CHECKLOCKTIMEVERIFY приводит к немедленному сбою оценки сценария в следующих пяти ситуациях:

  1. Стек пуст (т.е. для OP_CLTV не указано целевое время для проверки).
  2. Элемент верхнего стека меньше 0 (блокировки с отрицательным временем не имеют смысла).
  3. Время nLocktime измеряется в блоках, а верхний элемент стека использует секунды или наоборот (яблоки и апельсины).
  4. Элемент верхнего стека больше элемента транзакции  lock_time (прошло недостаточно времени).
  5. В поле nSequence этого входа установлено значение  0xFFFFFFFF (таймлок может быть отключен).

OP_CLTV заменяет OP_NOP2, который (как и следовало ожидать) ничего не сделал. Разработка OP_CLTV для замены OP_NOP2 в качестве софтфорка обеспечила интересное ограничение: OP_CLTV должен покинуть стек точно в том виде, в каком он его нашел. По этой причине OP_CLTV считывает элемент стека, но не  использует  его. Он проверяет блокировку времени, но затем оставляет целевое время в стеке. Таким образом, за ним почти всегда следует OP_DROP, который удаляет верхний элемент стека.

Сравнение времени блокировки, указанного в скрипте, со временем блокировки транзакции является очень умной реализацией, поскольку время проверяется только косвенно. Он передает соблюдение консенсусных правил nLocktime, в то же время позволяя сценариям указывать несколько различных условий блокировки по времени. Это позволяет в любое время проверить достоверность подписи скрипта и  кэшировать его . Обратной стороной является то, что если в сценарии используется OP_CLTV,  lock_time его необходимо указать в транзакции расходов, а   во входных данных должно присутствовать sequence_no значение меньше  . 0xFFFFFFFFЭто может показаться нелогичным для новых разработчиков, так что имейте это в виду.

Примеры OP_CLTV :

# Most of the transaction is omitted. Using decimal for human readability.
# Using hex for sequence numbers due to the presence of flags.

# Anyone can spend, at or after block 506391
tx_1:  
  lock_time: 506391
  input_1:
    sequence_no: 0xFFFFFFFE
    script:
      506391 OP_CHECKLOCKTIMEVERIFY OP_DROP

# This transaction is invalid:
# The lock_time is in blocks, and the CLTV is in seconds
# The sequence_no is 0xFFFFFFFF
tx_2:  
  lock_time: 506391
  input_1:
    sequence_no: 0xFFFFFFFF
    script:
      1514764800 OP_CHECKLOCKTIMEVERIFY OP_DROP

# This transaction is invalid
# The top stack item is greater than the lock_time
tx_3:  
  lock_time: 506391
  input_1:
    sequence_no: 0xFFFFFFFE
    script:
      600000 OP_CHECKLOCKTIMEVERIFY OP_DROP

# This transaction is valid at block 512462, but only if at least 32 * 512 seconds have passed since its previous output confirmed.
# A separate transaction could be constructed to spend the coins between 506391 and 512462
tx_4:  
  lock_time: 512462
  input_1:
    sequence_no: 0x00400020
    script:
      506391 OP_CHECKLOCKTIMEVERIFY OP_DROP

# This transaction becomes valid at block 506321
# The script allows an alternate execution path using 2-of-2 multisig.
# A separate transaction can be created that will not be time locked.
tx_5:  
  lock_time: 506321
  input_1:
    sequence_no: 0xFFFFFFFE
    scriptsig:
      OP_TRUE
    script:
      OP_IF
        506321 OP_CHECKLOCKTIMEVERIFY OP_DROP
      OP_ELSE
        OP_2 <pubkey_1> <pubkey_2> OP_2 OP_CHECKMULTISIG
      OP_ENDIF

# This is a variation of an HTLC.
# This transaction is valid at block 507381 assuming:
# 1. The secret for input_2's script matches the expected secret hash
# 2. Valid signatures and pubkeys are provided for input_2
# 3. input_2's nSequence time-lock is respected.
tx_6:  
  lock_time: 507381
  input_1:
    sequence_no: 0xFFFFFFFE
    script:
      507381 OP_CHECKLOCKTIMEVERIFY OP_DROP
  input_2:
    sequence_no: 0x000000A0
    scriptsig:
      <signature> <pubkey> <secret>
    script
      OP_HASH160 <secret hash> OP_EQUALVERIFY
      OP_DUP OP_HASH160 <pub keyhash> OP_EQUALVERIFY OP_CHECKSIG

OP_CSV

OP_CHECKSEQUENCEVERIFY (OP_CSV) — это  относительная блокировка времени на уровне  сценария  . Он был описан в  BIP 112  и внедрен вместе с измерениями nSequence и MTP в середине 2016 года.

Функционально OP_CSV очень похож на OP_CLTV. Вместо проверки времени он сравнивает верхний элемент стека с  sequence_no полем ввода. OP_CSV анализирует элементы стека так же, как nSequence интерпретирует время блокировки. Он учитывает флаг отключения и флаг типа nSequence и считывает спецификации продолжительности 16-битной блокировки из последних 16 бит элемента стека. Ошибки OP_CSV, если:

  1. Стек пуст (время блокировки не указано).
  2. Верхний элемент стека меньше 0 (отрицательное время глупо).
  3. Флаг отключения элемента верхнего стека не установлен и выполняется хотя бы одно из следующих условий:
    • Версия транзакции меньше 2 (транзакция не сигнализирует о совместимости OP_CSV).
    • sequence_no Установлен флаг отключения входа  (относительное время блокировки отключено).
    • Флаги типа входного  sequence_no и верхнего элемента стека не совпадают (не используют одну и ту же метрику).
    • 16-битная длительность верхнего элемента стека превышает длительность, указанную в поле ввода  sequence_no (прошло недостаточно времени).

OP_CSV заменяет OP_NOP3 и (как и OP_CLTV) должен оставлять стек неизмененным при выполнении для обеспечения совместимости со старыми клиентами. Он считывает верхний элемент стека, но не потребляет его. Итак, опять же, он часто сочетается с OP_DROP. Если установлен флаг отключения верхнего элемента стека, OP_CSV ведет себя как OP_NOP3.

Как было описано ранее при обсуждении относительного времени блокировки, OP_CSV — замечательный инструмент для объединения цепочек транзакций. Если бы вместо этого мы использовали OP_CLTV, вся цепочка транзакций имела бы абсолютную дату истечения срока действия. OP_CSV позволяет нам установить дату истечения срока действия относительно первой широковещательной транзакции. Таким образом, цепочка транзакций может создаваться и храниться неопределенно долго, сохраняя при этом гарантии временной блокировки.

Транзакции, однажды подтвержденные, не могут быть отозваны без реорганизации цепочки. Но объединение транзакций в цепочку с помощью относительного времени блокировки OP_CSV позволяет нам создавать пути оценки скриптов, которые почти обеспечивают эту функцию, создавая взаимоисключающие будущие пути. Используя OP_IF, мы можем создать несколько транзакций, использующих один и тот же предыдущий вывод (который сам может быть результатом неподтвержденной транзакции), и гарантировать, что у одной из них есть относительная временная блокировка. Затем, если заблокированная версия будет транслироваться во время блокировки, разблокированная версия сначала подтвердит и потратит монеты. Это означает, что мы можем давать определенным транзакциям приоритет над другими и контролировать выполнение сложных смарт-контрактов. Сеть Lightning широко использует это.

Примеры OP_CSV

# Most of the transaction is omitted. Using decimal for human readability.
# Using hex for sequence numbers due to the presence of flags.

# Anyone can spend, 255 blocks after the previous output confifrms.
tx_1:  
  lock_time: 0
  input_1:
    sequence_no: 0x000000FF
    script:
      0x000000FF OP_CHECKSEQUENCEVERIFY OP_DROP

# Anyone can spend, so long as both of the following are true:
# a) 16,384 seconds have passed since input_1's previous output was confirmed
# b) 255 blocks have passed since input_2's previous output was confirmed
tx_2:  
  lock_time: 0
  input_1:
    sequence_no: 0x00400020
    script:
      0x00400020 OP_CHECKSEQUENCEVERIFY OP_DROP
  input_2:
    sequence_no: 0x000000FF
    script:
      0x000000FF OP_CHECKSEQUENCEVERIFY OP_DROP


# Anyone can spend, so long as 256 blocks have passed since input_1's previous output.
# Note that a separate transaction can be created to spend these coins.
# The alternate path would specify a lock_time of at least 506321.
# The script allows either an absolute or relative time lock, whichever is shorter.
tx_3:  
  lock_time: 0
  input_1:
    sequence_no: 0x00000100
    scriptsig:
      OP_FALSE
    script:
      OP_IF
        506321 OP_CHECKLOCKTIMEVERIFY
      OP_ELSE
        0x00000100 OP_CHECKSEQUENCEVERIFY
      OP_ENDIF
      OP_DROP


# This transaction is invalid until 1/1/2020,
# AND until 31457280 seconds after the previous output confirmed.
# It also specifies a single approved spender by their pubkey.
tx_4:  
  lock_time: 1577836800
  input_1:
    sequence_no: 0x0004F000  # type flag is set
    scriptsig:
      <signature> <pubkey>
    script:
      1577836800 OP_CHECKLOCKTIMEVERIFY OP_DROP
      0x0004F000 OP_CHECKSEQUENCEVERIFY OP_DROP
      OP_DUP OP_HASH160 <pubkey hash> OP_EQUALVERIFY
      OP_CHECKSIGVERIFY

# This transaction is invalid 3 ways:
# 1) input_1's script fails because the stack item's 16-bit lock duration is greater than specified in the sequence_no.
# 2) input_2's script fails because the sequence_no's type flag is not set, while the stack item's type flag is set.
# 3) input_3's script fails because the stack is not empty at the end.
tx_5:  
  lock_time: 0
  input_1:
    sequence_no: 0x0004F000
    script:
      0x0004FFFF OP_CHECKSEQUENCEVERIFY OP_DROP
  input_2:
    sequence_no: 0x0000FFFF
    script:
      0x0004FFFF OP_CHECKSEQUENCEVERIFY OP_DROP
  input_3:
    sequence_no: 0x00000001
    script:
      0x00000001 OP_CHECKSEQUENCEVERIFY

Обзор

Временные блокировки Биткоина — мощные инструменты, но они могут сбивать с толку. Вот краткий список важных вещей, которые следует запомнить:

  • ОП идут в скриптах.
  • «Locktime» означает абсолютный.
  • «Последовательность» означает относительную.
  • Все временные блокировки могут выполнять блоки или секунды, но у них разные способы сигнализации.
  • Не стоит случайно запирать вещи на века.
  • Для блокировки времени на уровне сценария требуется блокировка на уровне транзакции того же типа в передаче расходов.

А вот удобная таблица:

Блокировка времениРасположениеТаргетингМетрикаТип сигнала
nLocktimeТехасАбсолютныйБлоки/СекундыСекунды, если >=500000000
nПоследовательностьВходРодственникБлоки/СекундыСекунды, если установлен флаг типа
OP_CLTVСкриптАбсолютныйБлоки/СекундыСекунды, если >=500000000
OP_CSVСкриптРодственникБлоки/СекундыСекунды, если установлен флаг типа

Дальнейшее чтение


Telegram: https://t.me/polynonce

GitHub: https://github.com/polynonce

YouTube: https://www.youtube.com/@polynonce

Временные замки Биткоина Bitcoin’s Time Locks

От