BOLT #3 : Bitcoin Transaction and Script Formats

BOLT #3 : Bitcoin Transaction and Script Formats お知らせ
Table of Contents

ここでは、署名が有効であることを保証するために双方が合意する必要があるオンチェーントランザクションの正確なフォーマットを詳述している。これは、資産トランザクション出力スクリプト、コミットメントトランザクション、HTLC トランザクションで構成されている。

Transaction

Use of Segwit

ここで使われているほとんどのトランザクション出力は pay-to-witness-script-hash (P2WSH) 出力(P2SH の Segwit 版)である。このような出力を支出するために witness スタックでの最後のアイテムは、P2WSH を生成するために使用された実際のスクリプトでなければならない。

資産トランザクション出力スクリプトは P2WSH であり、以下のような構造をしている。(pubkey1 は圧縮形式での 2 つの funding_pubkey で辞書的に小さい方であり、pubkey2 は大きい方である)

2 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG

Commitment Transaction

コミットメントトランザクションの構造は以下のようになっている。

  • version : 2
  • locktime : 上位 8 ビットは 0x20 であり、下位 24 ビットは不明瞭なコミット番号の下位 24 ビットである
  • txin count : 1
    • txin[0] outpoint : funding_created メッセージの txidoutput_index
    • txin[0] sequence : 上位 8 ビットは 0x80 であり、下位 24 ビットは不明瞭なコミット番号の下位 24 ビットである
    • txin[0] script bytes : 0
    • txin[0] witness : 0 <signature_for_pubkey1> <signature_for_pubkey2>

Commitment Transaction Outputs

ペナルティトランザクションの機会を可能にするために、失効したトランザクションの場合、コミットメントトランザクションの所有者に資産を戻す全ての出力は to_self_delay ブロックのために遅らせる必要がある。この遅延は、第2段階の HTLCトランザクションで行われる。

各アウトプットの1 sat 未満の金額は切り捨てる。HTLC トランザクションの手数料を引いた料金がコミットメントトランザクションの所有者によって設定された dust_limit_satoshis よりも小さい場合、出力は生成してはいけない(その資産は手数料に追加する)。

to_local 出力

この出力はこのコミットメントトランザクションの所有者に資産を戻し、OP_CHECKSEQUENCEVERIFY を用いてタイムロックされる必要がある。もし取り消し可能秘密鍵を知っていれば、相手によって遅延なく獲得される。出力は version-0 P2WSH の witness スクリプトである。

to_remote 出力

option_anchor_outputs がコミットメントトランザクションに適用する場合、to_remote 出力は csv ロックした1つのブロックによって妨げられる。

提供した HTLC 出力

この出力は、HTLC タイムアウト後の HTLC タイムアウトトランザクション、または支払いプリイメージまたは失効キーを使用してリモートノードのいずれかに資金を送る。出力は、witness スクリプトで P2WSH である。

受け取った HTLC 出力

この出力は、HTLC-タイムアウト後、または失効キーを使用してリモートノードに資金を送るか、または支払いプリイメージが成功した HTLC-成功トランザクションに資金を送る。出力は P2WSH であり、witness スクリプト(option_anchor_outputs はない)を持つ。

トリミングされた出力

各ピアは生成するべきでない出力の下限値 dust_limit_satoshis を指定している。これらの出力を "トリミングされた" とする。トリムされた出力は生成するには小さすぎると見なされ、代わりにコミットメントトランザクション手数料に追加される。HTLC の場合、2 段目の HTLC 取引も制限値を下回る可能性があることを考慮する必要がある。

HTLC-timeout and HTLC-success Transactions

これらの HTLC トランザクションほ、HTLC-タイムアウトトランザクションはタイムロックされていることを除いて、ほとんど同一である。これらはペナルティトランザクションによって支出することができる。

  • version: 2
  • locktime: 0 -> HTLC-success, cltv_expiry -> HTLC-timeout
  • txin count: 1
    • txin[0] outpoint: コミットメントトランザクションの txid と and HTLC トランザクションにマッチする HTLC 出力の output_index
    • txin[0] sequence: 0 (option_anchor_outputs の場合は 1)
    • txin[0] script bytes: 0
    • txin[0] witness stack: 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> -> HTLC-success, 0 <remotehtlcsig> <localhtlcsig> <> -> HTLC-timeout
  • txout count: 1
    • txout[0] amount: HTLC 量 - 手数料
    • txout[0] script: version-0 P2WSH with witness script
  • option_anchor_outputs をこのコミットメントトランザクションに適応した場合、 SIGHASH_SINGLE|SIGHASH_ANYONECANPAY が使用される

Closing Transaction

各ノードに2つのバリエーションがあることに注意されたい。

  • version: 2
  • locktime: 0
  • txin count: 1
    • txin[0] outpoint: funding_created メッセージからの txidoutput_index
    • txin[0] sequence: 0xFFFFFFFF
    • txin[0] script bytes: 0
    • txin[0] witness: 0 <signature_for_pubkey1> <signature_for_pubkey2>
  • txout count: 0, 1 or 2
    • txout amount: 1つのノードに支払われるための最終残高
    • txout script: shutdown メッセージでノードの scriptpubkey に指定されているように

Fees

手数料計算

両者のコミットメントトランザクションや HTLC トランザクションの手数料計算は現在の feerate_per_kw と予想されるトランザクションの重さをベースとしている。実際と予想の重さはいくつかの理由により異なる。

Fee Payment

基本コミットメントトランザクション手数料と to_localto_remote_anchor 出力量は出資量から取り除かれる。手数料は出資者への出力から引かれていることに注意されたい。

ノードは:

  • 最終手数料が低すぎる場合:
    • チャネル開設を失敗する可能性がある

コミットメントトランザクション構造

この章では、あるピアのコミットメントトランザクションを構築するための アルゴリズムを詳細に説明する。 ピアの dust_limit_satoshis、現在の feerate_per_kw、各ピア(to_localto_remote)への金額、およびすべてのコミットされた HTLC など。

  1. コミットメントトランザクションの入力とロックタイムを初期化する
  2. どのコミットされた HTLC がトリミングに必要なのか計算する
  3. 基本コミットメントトランザクション手数料を計算する
  4. 出資者(to_local もしくは to_remote)からこの基本手数料を引く
  5. 提供した HTLC ごとに、トリミングされていない場合は提供した HTLC 出力を追加する
    6.受け取った HTLC ごとに、トリミングされていない場合は受け取った HTLC 出力を追加する
  6. to_local 量が dust_limit_satoshis 以上の場合、to_local 出力を追加する
  7. to_remote 量が dust_limit_satoshis 以上の場合、to_remote 出力を追加する
  8. option_anchor_outputs がコミットメントトランザクションに適用される場合:
    • to_local が存在する、もしくはトリミングされていない HTLC がある場合、to_local_anchor 出力を追加する
    • to_remote が存在する、もしくはトリミングされていない HTLC がある場合、to_remote_anchor 出力を追加する
  9. BIP 69+CTLV order に沿ってソートする

Keys

Key Derivation

各コミットメントトランザクションは一意の localpubkeyremotepubkey を使用している。HTLC-成功と HTLC-タイムアウトトランザクションは local_delayedpubkeyrevocationpubkey を使用している。per_commitment_point に基づいたトランザクションごとに変更がある。option_static_remotekeyoption_anchor_outputs の場合、remotepubkey への鍵ローテーションは適用されない。

鍵交換の理由は、失効されたトランザクションのトラストレスな監視を外部委託できるためである。そのような監視者は、たとえどのトランザクション ID を監視すべきかを知っていて、どの HTLC と残高が含まれているかを合理的に推測できたとしても、コミットメントトランザクションの内容を明らかにすることができるべきではない。しかし、コミットメントトランザクションごとのストレージを避けるために、監視者はペナルティトランザクションに必要なスクリプトを再作成するために使われる per_commitment_secret, revocation_basepoint, delayed_payment_basepoint を受け取ることができる。従って、監視者は各ペナルティ入力に対する署名を与えられさえすればよい。

localpubkey, local_htlcpubkey, remote_htlcpubkey, local_delayedpubkey, and remote_delayedpubkey Derivation

これらの鍵はかれらのベースポイントから足すことで生成される。

pubkey = basepoint + SHA256(per_commitment_point || basepoint) * G

対応する秘密鍵は同様に生成される。

privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)

remotepubkey Derivation

option_static_remotekey もしくは option_anchor_outputs が交渉されている場合、remotepubkey は単にリモートノードの payment_basepoint であり、そうでない場合、リモートノードの payment_basepoint を使用して計算される。

シンプルな派生は、たとえデータを失い、対応する per_commitment_pointを知らなくても、ノードがコミットメントトランザクションを支出することが可能ということを意味する。ウォッチタワーは、それらのうちの1つをオンチェーンで見た場合にのみ to_remote 出力を持っているそれに与えられたトランザクションを相関させることができたが、そのようなトランザクションは強制力を必要とせず、ウォッチタワーに渡されるべきではない。

revocationpubkey Derivation

revocationpubkey は見えない鍵である。ローカルノードがリモートノードに対して新しいコミットメントを作りたいと思った時、コミットメントのために新しい per_commitment_secret を生成するために自身の revocation_basepoint とリモートノードの per_commitment_point を使用する。リモートノードがその per_commitment_secret を明らかにした後、ローカルノードは revocationprivkey を生成することができる。

per_commitment_point は楕円曲線の掛け算で生成される。

per_commitment_point = per_commitment_secret * G

これはリモートノードの revocation_basepoint から失効公開鍵を生成するために使用される:

revocationpubkey = revocation_basepoint * SHA256(revocation_basepoint || per_commitment_point) + per_commitment_point * SHA256(per_commitment_point || revocation_basepoint)

この構造は basepoint を提供するノードも、per_commitment_point を提供するノードも、どちらも他ノードの秘密なしで秘密鍵を知ることはできないことを保証する。

per_commitment_secret がわかれば、対応する秘密鍵を導出することができる。

revocationprivkey = revocation_basepoint_secret * SHA256(revocation_basepoint || per_commitment_point) + per_commitment_secret * SHA256(per_commitment_point || revocation_basepoint)

タイトルとURLをコピーしました