用語集 / トランザクションと手数料
シーケンス番号
別名はnSequenceです。
- シーケンス番号とは?
- シーケンス番号は、すべてのトランザクションのインプットにある4バイトのフィールドで、手数料の置き換えを示し、locktimeを有効にし、相対的なタイムロックを符号化できるものです。
BIP-68で規定されています。
無関係な3つの役割が1つのフィールドを共有しているのは、ビットコインには別のフィールドを追加する余裕がなかったからです。サトシによる当初の構想、すなわち新しいバージョンごとに数値を上げる原始的なペイメントチャネルは、より高い数値をマイナーが優先するよう強制するルールがなかったため、2010年ごろに放棄されました。生き残ったのは、ウォレットのトランザクションの挙動を決める一連のマジックバリューです。
仕組み
シーケンス番号を読むということは、それが古い順に並んだ3つの別々のルールに照らしてどうなのかを確認するということです。
最終値。 0xffffffff、10進数で4,294,967,295というシーケンスは、インプットを最終のものとして示します。トランザクション内のすべてのインプットが最終であれば、locktimeフィールドは完全に無視されます。これは初期のウォレットにおける既定値であり、このフィールドをまったく考慮したことのないソフトウェアが構築したトランザクションでも、今なお見られるものです。
置き換えのシグナル。 BIP125は範囲の下端に意味を割り当てました。0xfffffffd以下に設定されたインプットは、送信者がより高い手数料を払うバージョンでトランザクションを置き換える可能性があることを示します。0xfffffffeという値はその間を縫うもので、置き換えのシグナルを出さずにlocktimeを有効にします。この区別は効力の大半を失っています。Bitcoin Coreはバージョン28.0(2024年10月)以来、シグナルの有無にかかわらず置き換えをリレーするからです。
相対的なタイムロック。 BIP68はバージョン2以上を宣言するトランザクションについて下位ビットを再解釈し、そのルールは2016年7月のブロック419,328から強制可能になりました。ビット31がクリアな場合、下位16ビットは、そのインプットが使うコイン自身が承認されてからどれだけの時間が経過しなければならないかを示します。ビット22が単位を選び、クリアならブロック単位で最大65,535ブロックすなわちおよそ455日、セットなら512秒の期間で、上限は388日近くになります。時計は親の承認時点から進み、固定された日付からではありません。これはまさに2人の間の契約に必要なものです。
どこで見られるか
シーケンス番号は、生のトランザクションのダンプでは列として、ウォレットソフトウェアではチェックボックスとして現れ、この2つの表示が同じ言葉を使うことはほとんどありません。
インプットをデコードするブロックエクスプローラーは、各インプットの横に4294967293のような値を表示します。これは0xfffffffdであり、そのウォレットが置き換え可能なトランザクションを構築したことを示します。Bitcoin Coreのdecoderawtransactionも同じ数値を表示し、SparrowとElectrumは数値としてではなく「replace by fee」の切り替えの背後にこれを出します。
最も重い実際の利用者はライトニングネットワークです。チャネルの失効遅延、すなわち相手方が古い状態を公開した場合に罰せられるまでの期間は、コミットメントトランザクションのインプット上のこのフィールドを通じて強制される相対的なタイムロックです。同じ仕組みが、サブマリンスワップ、ボールトの設計、そして相手方に行動する公正な機会が与えられた後にのみ返金経路が利用可能にならなければならないあらゆる契約を支えています。
シーケンス番号vs locktime
シーケンス番号はインプットごとであり、locktimeはトランザクションごとです。これが両者を区別する最も手早い方法であり、両者が異なる目的に使われる理由を説明します。
locktimeはトランザクション全体に対して1つの絶対的な期限を設定し、ブロック高または実時間で表され、使われるコインが1日前のものでも5年前のものでも適用されます。シーケンス番号内の相対的なタイムロックは、そのインプットが使う特定のコインの承認時点から測るため、各インプットが独自の待機期間を持て、同じスクリプトがいつ資金が入れられても機能します。両者はまた厄介な形で互いに依存しています。locktimeは少なくとも1つのシーケンス番号が最終値未満である場合にのみ強制されるため、すべてを0xffffffffに設定するウォレットはもう一方のフィールドを静かに無効にします。