| Механизм | Где записан | От какой точки считает | Главная проверка |
|---|---|---|---|
| nLockTime | В spending transaction | Абсолютная height или MTP | Транзакция final для следующего блока |
| CLTV | В выполняемой script-ветке prevout | Operand против tx.nLockTime | Тип совпадает, operand ≤ nLockTime, input non-final |
| BIP-68 / CSV | nSequence input + script operand | Возраст подтверждённого UTXO | version ≥2, флаги/тип/маска и достаточный age |
- Механизм
- nLockTime
- Где записан
- В spending transaction
- От какой точки считает
- Абсолютная height или MTP
- Главная проверка
- Транзакция final для следующего блока
- Механизм
- CLTV
- Где записан
- В выполняемой script-ветке prevout
- От какой точки считает
- Operand против tx.nLockTime
- Главная проверка
- Тип совпадает, operand ≤ nLockTime, input non-final
- Механизм
- BIP-68 / CSV
- Где записан
- nSequence input + script operand
- От какой точки считает
- Возраст подтверждённого UTXO
- Главная проверка
- version ≥2, флаги/тип/маска и достаточный age
nLockTime — абсолютная граница всей транзакции
Значение nLockTime меньше 500 000 000 трактуется как высота блока, не меньше порога — как Unix time. По текущей consensus-реализации оно обозначает последнюю ещё недопустимую height/time: для следующего блока nLockTime должен быть строго меньше проверяемой высоты или MTP. Если все inputs имеют nSequence 0xffffffff, IsFinalTx игнорирует nLockTime. Поэтому число в поле без последовательностей inputs не даёт ответа.
BIP-113 использует Median Time Past — медиану timestamp предыдущих 11 блоков — вместо локальных часов. MTP движется дискретно и может отставать от календарного времени. Подтверждения и финальность также важны для исходного UTXO: неподтверждённый prevout ещё не даёт стабильной height, от которой можно надёжно считать относительную ветку.
CLTV связывает script operand с nLockTime
Когда выполняется OP_CHECKLOCKTIMEVERIFY, верхний элемент stack должен быть неотрицательным, иметь тот же тип height/time, что tx.nLockTime, и быть не больше tx.nLockTime. У проверяемого input nSequence не может быть final 0xffffffff. CLTV сам не выбирает ветку и не проверяет текущую цепь напрямую: он заставляет spending transaction нести подходящий nLockTime, который затем ограничивает включение блока.
Если CLTV находится под IF/ELSE, условие действует только для реально исполняемой ветки. Адрес или descriptor должен раскрыть точный script и условия подписей; один txid prevout показывает сумму, но не намерение выбранного пути. Начните с модели UTXO и сдачи, затем сопоставьте outpoint с полным locking script.
CSV считает возраст конкретного input
BIP-68 при transaction version не ниже 2 интерпретирует nSequence input как относительный lock, если старший disable bit не установлен. Type flag выбирает blocks или time; значимы младшие 16 бит. Time-based значение умножается на 512 секунд и сравнивается через MTP предыдущих блоков. Для block-based значения исходная точка — height блока, подтвердившего spent output.
OP_CHECKSEQUENCEVERIFY сравнивает operand ветки с masked nSequence этого же input. Ошибка возникает при version ниже 2, disable flag в transaction input, несовпадении height/time типа или недостаточном masked value. CSV не говорит «через N блоков от создания кошелька»: он относится к возрасту точного prevout, который этот input тратит.
| Проверка | Если проходит | Если нет |
|---|---|---|
| Outpoint и полный script известны | Выбрать реальную witness-ветку | Не подписывать по данным одного UI |
| CLTV branch исполняется | Сверить operand/type/nLockTime/non-final sequence | Не применять CLTV к другой ветке |
| CSV branch исполняется | Сверить version, flags, mask и prevout age | Пересобрать transaction или ждать |
| Абсолютная и относительная границы достигнуты | Проверить остальные script/signature/fee условия | Не broadcast: consensus/policy reject вероятен |
| Spend уже в mempool | Следить за exact txid и reject reason | Не считать отсутствие в одном explorer доказательством invalid |
- Проверка
- Outpoint и полный script известны
- Если проходит
- Выбрать реальную witness-ветку
- Если нет
- Не подписывать по данным одного UI
- Проверка
- CLTV branch исполняется
- Если проходит
- Сверить operand/type/nLockTime/non-final sequence
- Если нет
- Не применять CLTV к другой ветке
- Проверка
- CSV branch исполняется
- Если проходит
- Сверить version, flags, mask и prevout age
- Если нет
- Пересобрать transaction или ждать
- Проверка
- Абсолютная и относительная границы достигнуты
- Если проходит
- Проверить остальные script/signature/fee условия
- Если нет
- Не broadcast: consensus/policy reject вероятен
- Проверка
- Spend уже в mempool
- Если проходит
- Следить за exact txid и reject reason
- Если нет
- Не считать отсутствие в одном explorer доказательством invalid
Контрольный расчёт
- 1Зафиксируйте сеть и tip
Сохраните block hash/height и MTP независимого fully validating node.
- 2Получите prevout
Проверьте txid:vout, amount, confirmation block и exact locking script.
- 3Раскройте ветку
Сопоставьте redeem/witness script или Taproot leaf с witness, который планируется использовать.
- 4Разберите transaction
Запишите version, nLockTime и nSequence каждого input до любой подписи.
- 5Вычислите обе границы
Отдельно посчитайте absolute finality и BIP-68 age, затем выполните CLTV/CSV comparisons.
- 6Проверьте узлом
Используйте testmempoolaccept или эквивалентную локальную validation без broadcast; сохраните reject reason.
Stop-сигналы
- кошелёк показывает одну дату, но не раскрывает script, nLockTime и nSequence;
- MTP заменяют текущим Unix time или обещают точную минуту включения;
- CSV считают от создания адреса, а не confirmation height/time prevout;
- CLTV operand и tx.nLockTime имеют разные типы height/time;
- все sequences final, хотя предполагается активный absolute nLockTime;
- для проверки просят seed или private key вместо unsigned transaction и public script data.
Spendability подтверждена только когда exact script path, signatures и все lock constraints валидны в одном chain context; достаточный срок не гарантирует inclusion или разумную fee. Если transaction отклонена, сохраните raw hex и reject reason, исправьте поля без раскрытия ключей и только затем применяйте coin control или работу с мемпулом, RBF и CPFP — эти инструменты не обходят timelock.
Источники
Мы используем прямые ссылки и фиксируем дату проверки. Полный текст чужих материалов не перепечатывается.
- BIP-65 — OP_CHECKLOCKTIMEVERIFY Bitcoin BIPs · Проверено 23 августа 2026 г. в 19:59 GMT+5
- BIP-68 — Relative lock-time Bitcoin BIPs · Проверено 23 августа 2026 г. в 19:59 GMT+5
- BIP-112 — OP_CHECKSEQUENCEVERIFY Bitcoin BIPs · Проверено 23 августа 2026 г. в 19:59 GMT+5
- BIP-113 — Median Time Past Bitcoin BIPs · Проверено 23 августа 2026 г. в 19:59 GMT+5
- Bitcoin Core — consensus transaction verification Bitcoin Core · Проверено 23 августа 2026 г. в 19:59 GMT+5
