Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoin Cash上でネイティブにカラードコインをサポートするOP_GROUP

Bitcoin CashブロックチェーンでBCH以外にネイティブにカラードコインをサポートするためにOP_GROUPという新しいopcodeが提案されている↓

https://github.com/BitcoinUnlimited/BUIP/blob/master/077.mediawiki

OP_GROUPとは?

OP_GROUPBitcoinスクリプト言語に追加する単一のopcodeで、ブロックチェーン上でトークン(カラードコイン)を効果的に表現する。OP_GROUPは既存のカラードコインの提案および実装とは異なり、通常のトランザクションの検証の一環でマイナーがカラードコインを検証する。これはビットコイン(BCH)と同様、無効なカラードコインのトランザクションブロックチェーンに現れないことを意味する(他のほとんどのカラードコインの提案はカラードコインのプロトコルとして無効なトランザクションブロックチェーン上に現れるため全てのクライアントがカラードコインのtxを検証する)。さらにこのOP_GROUPの提案では、全てのUTXOにカラーを明示する。これらの機能を一緒に追加することで以下が可能になる。

  1. ユーザーが誤ってカラードコインを通常のビットコインとして使用することがなくなる。
  2. SPVウォレットはビットコインと同じ容易さとセキュリティモデルでカラーリングされたコインを処理できる。

OP_GROUPの初期バージョンでは、他のカラードコインがサポートしている高度な機能の一部は含まれていないが、(SPVウォレットで有効など)カラードコインに必要な主要な機能を含んでいると思われる。この機能は他のカラードコインの提案にはない。

というのがBUIPに書かれてる内容だが、これだけだとどうやって実現するのか全く分からないので、リンクされている↓の記事を見てみる。(本筋とは関係ないけど、プロトコルの内容はちゃんとBUIP内に書こうよ。。)

medium.com https://www.yours.org/content/colored-coins-in-bitcoin-cash-b26804e05964/

OP_GROUPの挙動

スクリプト内にOP_GROUPが現れると、スタックの一番上のデータがグループ識別子として使われ、インプット/アウトプットの値がそのグループに関連付けられた整数に加算/減算される。この整数はgroup balanceと呼ばれる。OP_GROUPが無い場合、そのインプット/アウトプットはデフォルトのbitcoin cashグループとして扱われる。トランザクションの処理の最後に、bitcoin cashグループを除く各グループのバランスは0にならなければならない(bitcoin cashグループのインプットは手数料分アウトプットより多いためバランスは0にはならない)。言い換えると、全カラードコイングループ内で、satoshiのインプットとアウトプットのバランスは一致する。

通常のP2PKHのスクリプトは以下のような形式だが

OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

カラーリングされたアウトプットの公開鍵ハッシュへの支払スクリプトは以下のような形式になる。

<グループ識別子> OP_GROUP OP_DROP OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

OP_DUP以降はP2PKHと同じで、先頭にグループ識別子とOP_GROUPOP_DROPが付加されている。グループ識別子がscriptPubkey内にあるため、SPVウォレットでもUTXOがどのグループなのかを識別できるという仕組みだ。OP_GROUP命令はスタックの頂上からグループ識別子をポップしないので、その後のOP_DROPが必要になる。これは不便だが、アップグレードされていないクライアントはOP_GROUPをno-opとして解釈するため、OP_GROUPを理解しないクライアントでもトランザクションを有効と判断するようになる。このためこのスクリプトの変更でハードフォークは必要ない。

また今のところグループ識別子のデータフォーマットはまだ定義されてないみたい。

カラードコイントークンの作成と破壊

カラーリングされたコインを持つトランザクションのインプットとアウトプットのバランスは0になるということだったが、2つだけ例外がある。カラードコインのトークンを発行するmintと破壊するburnの場合だ。

mint トランザクション

以下のようなscriptPubkeyを持つインプットと

OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

以下のscriptPubkeyを持つアウトプット

<グループ識別子> OP_GROUP OP_DROP OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

が含まれるトランザクションを考える。インプットにはOP_GROUPがないため、通常ではグループのバランスが取れておらずトランザクションの検証に失敗するが、mintトランザクションであれば例外となる。アウトプット内のOP_GROUPのグループ識別子がインプットのデータ要素と一致する場合、mintトランザクションであると認識され、このインプットの値はアウトプット内のグループ識別子のグループの値として扱われる。

インプットのデータ要素というのはまだプロトコルで正式に定められている訳ではないようだが、アドレスやアドレスの元となる公開鍵などを利用する模様。公開鍵やそこから派生したアドレスを利用することで、その公開鍵に対応する秘密鍵を持つユーザーのみが同じ識別子のコインを作り出すことができる。これは既存のカラードコインのプロトコルでもよく採用されているアプローチだ。

最初のmintトランザクションはオプションでOP_RETURNを含めることができ、これには人間が識別できるグループの短い名前やグループの詳細について説明したドキュメント/コントラクトのハッシュが記録されている。

ちなみに↑のインプット1つカラーリングされたアウトプット1つのmintトランザクションだと手数料が設定できないので、実際には手数料分のインプットが追加されることになる。

↑のルールの場合、発行者は同じ公開鍵を使えば同じグループ識別子のコインを何度でも追加発行できる。そのため追加発行を許可しないようなコインの発行をどう制御するかは検討が必要。

burn トランザクション

burnトランザクションはカラーリングされたコインを通常のBitcoin Cashに戻す際に使用するトランザクション

トランザクションのインプットは↓のようなカラーリングされたscriptPubkeyのUTXOを参照していて

<グループ識別子> OP_GROUP OP_DROP OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

アウトプットは以下のようにカラーリングされていないscriptPubkey

OP_DUP OP_HASH160 <公開鍵のハッシュ> OP_EQUALVERIFY OP_CHECKSIG

全アウトプットにOP_GROUPが含まれていない場合、burnトランザクションとみなされる。

グループを識別しやすくするためのルール

このアプローチでは、OP_GROUPが複雑なスクリプト内にある場合、トランザクションの検証時にどのグループのコインに属するか決定することができないかもしれないという問題があり、このためスクリプトのスタンダードルールとして以下の制約が設けようとしているみたい。

  • スクリプト内にOP_GROUPは1つのみ
  • OP_GROUPは条件付きのロジック(OP_IF、OP_ELSEとか)の外側であること
  • OP_GROUPの直前にグループ識別子がプッシュされていること

カラードコインの量

↑のルールでグループ識別子によってカラードコインを識別する仕組みが提供される。識別は可能だがカラーリングされたコインの量はそのままアウトプットのコインの量(satoshiの量)を使ってる。2ndレイヤーで実装するカラードコインの場合、カラーリングされたコインには専用の量があり、UTXOとして認識するために各アウトプットに少額のBitcoinが乗っているが、OP_GROUPの場合はBitcoinの量とカラードコインの量を分離してはいないのが特徴的でもある。ただいずれもカラーリングされている間はBitcoinとしては使えないという点は同じだ。

所感

  • インプットとアウトプットの各グループのコイン量のバランスのチェックは、各スクリプト単体の評価時には結果が分からないので、全インプット/アウトプットを考慮して計算しないといけない。つまりスクリプトインタプリタ単位では検証できないわけで、そういった評価の類をスクリプトのopcodeとして導入していいものか?本来スクリプトのランタイムはscriptSig + scriptPubkeyを組み合わせて実行して結果が出るもの。Covenantsの仕組みとかでその中でトランザクションデータをスタックに入れて評価するような拡張の提案もあるけど、OP_GROUPトランザクションの他のインプットも含めた上で評価する必要があり、検証のスコープが複数のインプットのスクリプトにまたがることになるけど、いいのか?。
  • 最初のmintトランザクションにはOP_RETURNメタデータを付与できると記載されているけど、これは最初のmintトランザクションかどうかをチェックしないといけないという意味になると考えると、どのトランザクションが最初の発行トランザクションであるか管理しておかなければならないということになる?
  • インプット/アウトプットでグループのコインのバランスがゼロになる必要があることから、おそらくP2SHは使えないと思われる。P2SHの場合、そのredeem scriptが明かされるのは、そのスクリプトを使用するトランザクションのscriptSigなので、アウトプットがP2SHだとそのredeem script内にOP_GROUPがあることをトランザクションの検証時に確認する術がない。
  • Bitcoinではネイティブにこういったトークンをサポートしてなくて、やる場合は2ndレイヤーで実装してたのもあり1stレイヤーのコンセンサスで保護されるわけではない。そのためトークンプラットフォームとしてはEthereumが人気な訳だけど、Cashが対応するとスクリプトの堅牢性という意味も含めてBitcoinベースのトークンプラットフォームも進化していくかもね。
  • ちなみにBTCでは、コア開発者の1人であるJohnson Lauがソフトフォークでカラードコインをネイティブに対応する提案を書いているが↓、実際に導入されることは無いだろうな。 btcnews.jp