Contact

【CTO Tech blog】OP_CHECKSIGFROMSTACKの導入を提案するBIP-348

  • CTO Tech blog

先日OP_CHECKSIGFROMSTACK opcodeの導入を提案するBIP-348がBIPとして登録された↓

https://github.com/bitcoin/bips/blob/master/bip-0348.md

OP_CHECKSIGFROMSTACK

OP_CHECKSIGFROMSTACK(OP_CSFS)自体は、昔からElementsに導入されているopcodeで、スタック内の任意のメッセージに対する署名検証を可能にする。既存のOP_CHECKSIGなどの署名検証用のopcodeは、メッセージがそのopcodeの実行中のトランザクションデータに限定されている。

動作

OP_CSFSは、スタックに以下の3つの要素がある前提で動作する。3つ未満の場合は、スクリプトの実行は失敗し終了する。

OP_CSFSを実行すると、↑の3つの要素がスタックからPOPされ以下の検証を行う。

  1. 公開鍵のサイズをチェック。サイズがゼロの場合、スクリプトは失敗、終了。
  2. 公開鍵のサイズが32 byteの場合、BIP-340で定義されている公開鍵として扱われる。
    •  署名が空でない場合、署名とこの公開鍵とスタックから取得したメッセージに対してBIP-340に従いSchnorr署名の検証が行われる。検証に失敗した場合は、スクリプトは失敗、終了。
  3. 公開鍵のサイズがゼロでも32 byteでもない場合、未知の公開鍵タイプとして扱われ*1、実際の署名検証は行われず、署名検証が成功したものとして扱われる。
  4. この段階まで処理が続くと、
    •  署名が空の場合は、空のベクトルスタックにプッシュされる
    •  署名が空でない場合は、sigopsのカウントがインクリメントされスタックに0x01がプッシュされる

Elementsとの挙動の違い

Elementsには、OP_CHECKSIGFROMSTACKとOP_CHECKSIGFROMSTACKVERIFYの2つのopcodeが用意されている。VERIFYが付く方は署名検証に失敗するとそこで終了し、付かない方は検証結果をスタックのプッシュする(OP_TRUE or OP_FALSE)。

BIP-348の挙動は、これらを組み合わせたような挙動になっていて、署名検証に失敗した場合はそこでエラーとなりスクリプトの実行が終了する。スタックに結果がプッシュされるのは、

  • 署名検証に成功した場合:OP_TRUE
  • 署名が空だった場合:空のベクトル=OP_FALSE

の2パターンのみ。

用途

OP_CSFSがあると以下のようなことが可能になる。

コベナンツ

Elementsでは結構初期の頃から言われてたもので、OP_CATと組み合わせてコベナンツを実現できる。まだOP_CATとSchnorrトリックが提案される前で、スタック上でトランザクションを組み立ててその署名の検証をOP_CSFSで行い、そこで使用した公開鍵と署名をOP_CHECKSIGでも利用することでコベナンツを実現するというもの

委任

コインの使用条件を第三者に委任することができる。例えば、以下のようなロックスクリプトを構成すると

<公開鍵A> SWAP IF 2 PICK SWAP CSFS VERIFY ENDIF CHECKSIG

これをアンロックするには二通りの方法がある。

  • Aの秘密鍵を知る所有者がアンロックする方法で、その場合のwitnessは↓

<Aの秘密鍵で生成したTx署名> 0

  • Aの秘密鍵を知る所有者が第三者(公開鍵Bとする)にコインの使用を委任する場合のwitnessは↓

<Bの秘密鍵で生成したTx署名> <公開鍵B> <Aの秘密鍵で生成した公開鍵Bをメッセージとした署名> 1

Aの秘密鍵の所有者は、公開鍵Bをメッセージとして、公開鍵Aに対して有効な署名を生成しそれを渡せば、Bの秘密鍵の所有者はいつでも↑のアンロックができる。

オラクルの署名検証

任意のメッセージに対する署名検証が可能になるので、オラクルの署名をトリガーとした(DLCのような)コントラクトが可能になる。

LN Symmetry

あとBIPに書かれてるのは、OP_CHECKTEMPLATEVERIFY(BIP-119)と組み合わせることで、LN Symmetry(eltoo)が可能になるという点。もともとLN Symmetryは、BIP-118のANYPREVOUT(APO:旧SIGHASH_NOINPUT)の導入が必要なプロトコルだけど、OP_CHECKTEMPLATEVERIFY <公開鍵> OP_CHECKSIGFROMSTACKで、ANYPREVOUTがシミュレートできるっぽい。これもう少し詳細知りたいな。

*1:この振る舞いは、BIP-342で定義されているTapscriptにおける未知の公開鍵タイプの取り扱いと同じ

本記事の元ページ

https://techmedia-think.hatenablog.com/entry/2024/12/12/184358

話題のキーワード