先月Russell O’ConnorがBitcoin-Devメーリングリストに投稿した、Bitcoinの次のソフトフォークの内容として検討されている、CTV
(OP_CHECKTEMPLATEVERIFY
)opcodeと、eltooスタイルのLightningチャネルを構成可能にするANYPREVOUT
を、新しいopcode TXHASH
とCSFS
(CHECKSIGFROMSTACKVERIFY
)で代替する提案がされていたので見てみる↓
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019813.html
CTVとは?
CTV
はBitcoinでCovenantsを可能にするための提案でBIP-119として現在提案されている。
簡単に言うと、CTV
opcodeは、スタックからPOPしたハッシュ値と、トランザクションのハッシュが一致するか検証するopcode。これを利用すると、UTXOのコインの支払い先や額を指定することができる。具体的には、scriptPubkeyでこのUTXOを使用する際の、支払いトランザクションのハッシュ値を指定する。この時、ハッシュの計算に用いられるのは、トランザクションデータの内↓
- バージョン
- ロックタイム
- 全インプットのscriptSig(nullでなければ)
- インプットの数
- シーケンス番号
- アウトプットの数
- 全アウトプット
- 現在実行中のインプットのインデックス
要は、コインを支払う時に、特定のトランザクションデータでしかそのコインをアンロックできないようにしておく仕組み。
ANYPREVOUTとは?
ANYPREVOUT
は、SIGHASHタイプの新しいモードの提案。SIGHASHタイプ自体は、署名がトランザクションのどの部分にコミットするかを指定するもの。
これまでのSIGHASHモードとは異なり、ANYPREVOUT
を指定すると、署名がインプットが参照するUTXOのOutPointにコミットしなくなる。つまり、インプットの参照先を変更することができる(参照先が同じロック条件である場合)。これにより現在のLNチャネルとは異なるeltooスタイルのLNチャネルを構成できるようになる。
CTVとANYPREVOUTの重複するポイント
CTV
とANYPREVOUT
は、提供する機能は異なるものの、重複するポイントがある。それはインプットの参照先のOutPoint(TXID)の扱い。
ANYPREVOUT
は、↑に書いたようにそもそもインプットの参照先のTXIDにコミットしないが、CTVの場合も、そのUTXO自体のTXIDを計算することは循環参照になるので不可能なため、↑に書いたようにCTVで計算されるハッシュ値にはインプットが参照するOutPoint(TXID)は含まれていない。
つまり、CTV
とANYPREVOUT
はいずれもインプットが参照するTXIDにコミットしない。
CTVをANYPREVOUTで代替
ANYPREVOUT
が署名検証の際のインプットが参照するTXIDを除外するという特徴を利用すると、ANYPREVOUT
でCTVを代替することもできる。
これは予め公開鍵と署名をUTXOのscriptPubkey内に設定することで実現できる。本来、署名はインプットのscriptSig/witnessScript内に配置されるのが一般的だが、これをscriptPubkeyに入れる。そうすることで、このUTXOを使用するためには、支払いトランザクションのハッシュが、scriptPubkey内の署名のメッセージダイジェストと一致する必要があり、scriptPubkeyを作成した時点で支払いトランザクションの構成を制御できる。
これは署名がANYPREVOUT
で署名されている=参照先のTXIDにコミットしていないから実現できる機能になる。
もちろんデータサイズやコミットするデータの対象範囲の差など、CTVをそのまま使用した方が良い点もある。
TXHASHとCSFSによるCTVとANYPREVOUTの代替
さて、提案の主題は、↑のCTVやANYPREVOUTの機能を、TXHASH
とCSFS
(CHECKSIGFROMSTACKVERIFY
)という2つの新しいopcodeをTapscriptに導入して別の形で実現しようというもの。
CSFS
BitcoinのOP_CHECKSIG
などの署名検証opcodeは基本的に署名対象のメッセージダイジェストはトランザクションデータから生成されるが、CSFS
というのはスタック上から公開鍵とメッセージと署名を取得して署名検証を行うopcodeになる。つまり任意のメッセージに対する署名検証を可能にするopcodeだ。これはElementsで既に導入されており、Bitcoin Cashなど他のブロックチェーンでも導入されていることが多い。これが利用可能になると、オラクルを用いたコントラクトなどが作りやすくなる。
TXHASH
TXHASH
というのは今回新たに提案されたopcodeで、スタックからtxhash
フラグをポップし、そのフラグに従ってトランザクションハッシュを計算し、その結果をスタックにプッシュするopcode。
CTVの代替
TXHASH
はCTV
とほぼ同様の機能を持つので、<ctv style flag> TXHASH EQUALVERIFY
でCTV
と同様のことが可能になる。ctv style flag
はCTVのハッシュ計算ルールを示すフラグで、TXHASH
によりそのルールでトランザクションのハッシュを計算し、EQUALVERIFY
でスタックに予めあるハッシュと一致するかを検証する。
ANYPREVOUTの代替
<anyprevout-pubkey> CHECKSIGVERIFY
は、<apo_style_flag> TXHASH <pubkey> CHECKSIGFROMSTACKVERIFY
によって代替される。この場合、<apo_style_flag> TXHASH
でインプットのTXIDにコミットしないトランザクションハッシュを計算し、スタックにプッシュし、その後、公開鍵をスタックにプッシュし、CHECKSIGFROMSTACKVERIFY
でスタックから署名とメッセージと公開鍵を取得して署名検証を行う。
CTV
もANYPREVOUT
も、用途は異なるものの、署名検証に用いるトランザクションハッシュをどう構成するか制御する機能であることをは共通。今回の提案は、この機能をCTV
もANYPREVOUT
というそれぞれ特化した機能として導入するのではなく、もう少しプリミティブなopcodeを導入することで代替可能にするというもの。
もちろん専用の機能として作られるCTV``ANYPREVOUT
よりも数バイトコスト高にはなるが、CHECKSIGFROMSTACKVERIFY
単体ではオラクルのサポートが可能になったり、CAT
opcodeなど将来導入される可能性のあるopcodeと組み合わせた場合の拡張性などは、このようなプリミティブな機能の方が有利になるというもの。