Bitcoinのタイムロック
安土さんの動画をみるのが早いかも
https://www.youtube.com/watch?v=MuaHIjKXC9E&t=898s
タイムロックの基本的な仕組み
UTXOが特定の時点(ブロック高 or タイムスタンプ)まで使えないようにする制御方法。
送金トランザクションに「いつから使えるか」という条件を付与し、ブロックチェーン上でそれを enforce(強制)する。
従来はnLockTimeやnSequenceをつかったコンセンサスアルゴリズムの強制力のないタイムロックを使っていた
segwitからCLTVやCSVをつかった強制力のあるタイムロックが登場(UTXOにタイムロックができる)
絶対タイムロックと相対タイムロック
絶対タイムロック (CLTV: CheckLockTimeVerify)
「ブロック高がX以上」もしくは「UNIXタイムがY秒以降」というように絶対的な時間やブロック番号を指定する手法。
相対タイムロック (CSV: CheckSequenceVerify)
「このトランザクションがチェーンに取り込まれてからZブロック経過後でないと spend できない」というように相対的な経過ブロック数で管理する手法。
nLockTime
Bitcoinのトランザクションヘッダにあるパラメータ。ある程度古くから存在する仕組みで、トランザクションが有効化される最小ブロック高 or 時刻を指定できる。
サイズ: 32ビット(4バイト)整数
意味: 「トランザクションが有効となる最も早いブロック高さまたは時刻(UNIXエポックタイム)」
区切り: 値が 500,000,000(約1970年-1985年のUnix Time相当) を基準に区別される
nLockTime < 500,000,000 の場合 → ブロック高(Block Height) として解釈
nLockTime がブロック番号として解釈される場合、マイニングされるブロックの高さが nLockTime 以上であればトランザクションは有効。
例: nLockTime = 800,000 の場合、実際のブロック高が 800,000 に達するまではトランザクションは承認されない(取り込まれない)。
nLockTime >= 500,000,000 の場合 → UNIXタイムスタンプ(単位は秒)として解釈
nLockTime がUNIXタイムとして解釈される場合、ブロックのタイムスタンプ(正確にはネットワークルールに基づく「平均/中央値」)が指定時刻を超えたら有効になる。
例: nLockTime = 1,700,000,000(約2023年半ば)の場合、そのUNIX時刻を過ぎるブロックが生成されるまで有効にならない。
nLockTime を指定しても、トランザクション内の全入力(Vin)の nSequence が 0xFFFFFFFF(最大値) だと、nLockTime は無視されます。
OP_CHECKLOCKTIMEVERIFY (CLTV) との違い
nLockTime は “トランザクションレベル” でのロック指定(ヘッダ情報)。
CLTV は Bitcoin Script 内の OP_CHECKLOCKTIMEVERIFY を使うもので、“UTXOの支払いスクリプトレベル” でロックをかける。
nSequence
Bitcoinがローンチされた当初は「トランザクションを未承認のまま更新(置き換え)する」マルチパーティーのユースケースを想定していました。
nLockTime を有効にするだけの用途
単にトランザクションの nLockTime(絶対タイムロック)を効かせたい場合、nSequence を最大値より1つ減らす(例: 0xFFFFFFFE)などに設定する。
BIP68 では相対ロック(CSV)に使う際の nSequence ビットフィールドについて定義
Bit 31(最上位ビット): “Time-based vs. Block-based” フラグ。
0 → ブロック数による相対ロック
1 → 時間(UNIX timestamp単位)による相対ロック
Bits 0..15(下位16ビット): 実際のロック値 (ブロック数や秒数)
Bits 16..30 は現在は予約領域(将来用途または必ず0にするのが推奨)。
例:
nSequence = 0x00000064 (10進数で100) の場合
Bit 31 = 0(ブロックベース)
下位16ビットは100 → 100ブロックの相対ロック
nSequence = 0x40000064(16進数で0x40000064)
Bit 31 = 1(時間ベース)
下位16ビット = 100 → 100 * 512秒 (大体 51200秒 = 約14.2時間) の相対ロック
BIP68 では1ブロック ≈ 10分 という前提で、時間モードの時は1ユニット=512秒と定義されています。
OP_CLTV
OP_CHECKLOCKTIMEVERIFY (CLTV) は、Bitcoin Script で実装された絶対タイムロックを行うためのOPコードです。
主に BIP65(2015年)で導入されました。
CLTV と nLockTime の違い
nLockTime
トランザクション全体の「いつから有効になるか」を設定する機能。ヘッダーにある 4バイトの値で、トランザクションが承認される(マイニングされる)最も早いブロック高 or 時刻を指定。
しかし nLockTime は全入力に対して一律で、かつ Script 内で柔軟な条件分岐を付けることはできない。
nSequence との組み合わせが必要という制約もある(入力がすべて 0xFFFFFFFF だったら nLockTime は無効化など)。
OP_CHECKLOCKTIMEVERIFY (CLTV)
Script(UTXOレベル) に直接「このスクリプトは指定したロックタイムを経過していなければアンロック不可」と書ける。
マルチシグや条件分岐と組み合わせてUTXOごとに独自ロック条件を付与できる。
Scriptの中で部分的に CLTV 条件を適用するなど、柔軟かつセキュアなタイムロックが可能。
OP_CSV
OP_CHECKSEQUENCEVERIFY (CSV) は、Bitcoin Script における「相対タイムロック」を実現するOPコードで、BIP68・BIP112 で導入。
全入力の nSequence が 0xFFFFFFFF だったりすると CSV が無効化されてしまう。
スクリプト内でロック期間を指定
ScriptPubKey(RedeemScript)の一部に OP_CHECKSEQUENCEVERIFY を書いておき、スタック上に必要なロック値をpushして実行すると、そのロック条件を満たさない場合は検証が失敗する。
nSequence を利用
CSV が機能するには、トランザクション入力の nSequence フィールドに「相対ロック期間」を示す値を設定する必要がある。
BIP68 で定義されたビットフォーマットに基づき、ブロック単位 or 時刻単位(512秒刻み)のロック指定が可能。
用途
「チャネルを一度開設した後、一定期間経たないと資金を引き出せないようにする」など、アップデート後に猶予期間を設けたいケースが多い。
OP_CHECKLOCKTIMEVERIFY (CLTV) は絶対タイムロック(ある固定時刻やブロック高を指定)なので、ユースケースによっては運用が難しい。
CSV なら、「UTXOが生成されてから何ブロック後」という相対指定ができるため、トランザクションの依存関係や順序性を扱いやすい。