Bitcoin CashのブロックチェーンでBCH以外にネイティブにカラードコインをサポートするためにOP_GROUP
という新しいopcodeが提案されている↓
https://github.com/BitcoinUnlimited/BUIP/blob/master/077.mediawiki
OP_GROUPとは?
OP_GROUP
はBitcoinのスクリプト言語に追加する単一のopcodeで、ブロックチェーン上でトークン(カラードコイン)を効果的に表現する。OP_GROUP
は既存のカラードコインの提案および実装とは異なり、通常のトランザクションの検証の一環でマイナーがカラードコインを検証する。これはビットコイン(BCH)と同様、無効なカラードコインのトランザクションはブロックチェーンに現れないことを意味する(他のほとんどのカラードコインの提案はカラードコインのプロトコルとして無効なトランザクションがブロックチェーン上に現れるため全てのクライアントがカラードコインのtxを検証する)。さらにこのOP_GROUP
の提案では、全てのUTXOにカラーを明示する。これらの機能を一緒に追加することで以下が可能になる。
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_GROUP
、OP_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