Develop with pleasure!

福岡でCloudとかBlockchainとか。

Colored Coins Protocolのカラーリングの仕組み

Open Assets Protocol含め、通称カラードコインと呼ばれるプロダクトは何種類かあって、それぞれカラーリング(実際にはアセットIDとかで色ではないのでカラードコインという呼称は違和感ある)のプロトコルが決められている。基本的にプロトコルは異なるので相互運用とかはできない。

今回はそんなカラードコインの一種であるColored-Coinsのカラーリング方法について調べてみた。

github.com

Bitcoinトランザクションのカラーリング

Colored Coinsプロトコルはブロックチェーン上でアセットの発行や、転送を行うのに↓の2つのBitcoin OP_CODESを使ってる。

OP_RETURN

任意のデータをブロックチェーンに格納できるOP_RETURNを利用する方法で、Open Assets Protocol含め他のカラードコインの実装でもよく使われる手法。

OP_RETURN <最大40バイトのデータ(※現在は80バイト)>

アセットの操作に関するデータは全てOP_RETURNを使って保存される。ただColored CoinsのプロトコルではTorrents内に保存された任意のサイズのメタデータをサポートしており、アセット操作に関するデータ以外に、SHA1 torrent info_hashとオプションでTorrentで保存されたメタデータの検証をするためのメタデータのSHA-256ハッシュを保存するスペースが必要になる。これらのデータを格納するのにOP_RETURNで保存できるデータ量では足りないので、入りきらないデータ(SHA-256ハッシュとか)をエンコードして別にマルチシグの出力に格納する。

多重署名アドレス(マルチシグ)

Bitcoinでは一般的に、コインを使用するのにN個中m個の署名を必要とする m out of N マルチシグアドレスをサポートしている。(Bitcoinを利用するための秘密鍵複数あり、その内のm個の鍵があればBitcoinを利用できるといったもの)

マルチシグアドレスはブロックチェーン上のデータをエンコードするためのものではなく、その点でいくつかの欠点がある。Bitcoinネットワーク内のノードのメモリに負荷をかけたくないので、1 out of N形式のマルチシグアドレスを使っている。この方法だと速やかに単一のUTXOを使用でき(メモリ内に保持していたUTXOのリストからすぐ削除されメモリ負荷を下げる効果がある)、残りのN-1個の公開鍵が格納されるスロット(各32バイト)をエンコードしたデータを格納するのに利用できる。Colored Coinsではこの1 out of Nアドレスを↓の簡易表記で記述している。

(1|N) = 1 out of N mulitisig address

現在、Colored Coins プロトコルでは、(1|2)と(1|3)のマルチシグアドレスのみ使用している。理論的にはNを3より大きくすることで、多くのデータを追加することが可能だけど、もし圧縮したデータを利用したにも関らず、OP_RETURNと(1|3)マルチシグでもデータの保存スペースが足りなくない場合、余計な複雑さを避けるためNを増やすのではなく出力を追加する形での対応を考えている。

メタデータとTorrents

Colored Coinsプロトコルでは、カラードトランザクションへのメタデータの付加をサポートしている。メタデータは直接ブロックチェーン上に保存されることはなく、プレーンなJSONフォーマットでtorrentsを使って保存される。torrentsを使うことでデータの保存と共有の分散化が可能になる。

ブロックチェーンへのデータの保存ロジック
  • メタデータが無い場合
    メタデータが無い場合は、アセットの操作に関する情報はOP_RETURNで保存できるスペースで充分なので、全てOR_RETURNの後に記述される。
  • メタデータがある場合
    メタデータがあるとOP_RETURN内のスペースでは充分でないので、以下のロジックでブロックチェーンにデータを記録する。(SHA-1のサイズは20バイト、SHA-256のサイズは32バイト)
    • 検証用にメタデータのSHA-256ハッシュが必要無い場合は、OP_RETURN内にエンコードしたSHA1 torrent info_hashを格納する。
    • メタデータのSHA-256ハッシュが必要な場合は、OP_RETURNの40バイトの中にSHA-256ハッシュとSHA1 torrent info_hashを格納するスペースが足りないので、SHA-256ハッシュはマルチシグアドレス内に格納される。
      • OP_RETURNの40バイト内にSHA1 torrent info_hashを格納する充分なスペースが残っている場合は、メタデータのSHA-256ハッシュを格納するのに1-fo-2マルチシグアドレスを使用する。
      • それ以外にSHA1 torrent info_hashを格納するスペースもOP_RETURN内に残っていない場合は、メタデータのSHA-256ハッシュとSHA1 torrent info_hashの両方を1-of-3マルチシグアドレス内にエンコードして格納する。

※ この仕様が作成された時点ではOP_RETURNに格納なデータサイズは40バイトだったため上記仕様のようで、OP_RETURNのサイズが80バイトに拡張されるとSHA1 torrent info_hashとSHA-256のメタデータハッシュ両方ともOP_RETURN内に格納するみたい。この際、SHA-256のハッシュをRIPEMD-160で圧縮することでブロックチェーンに記録するデータサイズを20バイトに制限する。

アセット操作を行うトランザクション

Colored Coinsプロトコルではアセットを操作するのに2つのタイプのトランザクションを使用する。

発行と転送用のトランザクション

発行用のトランザクションによって新しいアセットが作成され、資産の多くの属性が決められる。必要に応じて発行用のトランザクションでアセットの転送を行うことも可能。

転送用のトランザクション

アセットの転送のみを行うトランザクションで、アセットの発行は行わない。

発行用トランザクションエンコーディング

バイト数 定義 コメント 保存場所
2 プロトコルの識別子 "Colored Coins"のCCを表すASCII表現で”0x4343”を設定。 OP_RETURN
1 バージョン番号 現在は”0x01”を設定。 OP_RETURN
1 発行用のOP_CODEs OP_RETURN
20 SHA1 Torrent Hash (オプション)メタデータが含まれる場合のみ OP_RETURN or (1|3) マルチシグ
32 メタデータのSHA256ハッシュ (オプション)メタデータが含まれ、メタデータの検証を行う場合のみ (1|2) or (1|3) マルチシグ
1-7 発行するアセットの単位数 Encoding Schemeによってエンコードした値 OP_RETURN
2-9 (per instruction) アセット転送用の命令 アセットの入力から出力のフローをエンコーディングしたもの。 OP_RETURN
1 発行フラグ 現時点では4bitのみ使用 OP_RETURN

転送用トランザクションエンコーディング

バイト数 定義 コメント 保存場所
2 プロトコルの識別子 "Colored Coins"のCCを表すASCII表現で”0x4343”を設定。 OP_RETURN
1 バージョン番号 現在は”0x01”を設定。 OP_RETURN
1 転送用のOP_CODEs OP_RETURN
20 SHA1 Torrent Hash (オプション)メタデータが含まれる場合のみ OP_RETURN or (1|3) マルチシグ
32 メタデータのSHA256ハッシュ (オプション)メタデータが含まれ、メタデータの検証を行う場合のみ (1|2) or (1|3) マルチシグ
2-9 (per instruction) アセット転送用の命令 アセットの入力から出力のフローをエンコーディングしたもの。 OP_RETURN
アセットの量

アセット発行時の単位数で、Encoding Schemeによってエンコードされた、1〜10,000,000,000,000,000 (10^16)までの範囲の値。(関連するのは発行用のトランザクションのみ)

発行フラグ

このフラグは、新たに発行されたアセットに関する追加情報を指定する。現時点では4bitのみ使っており残りの4bitは将来の拡張のために予約されている。(関連するのは発行用のトランザクションのみ)

  • 最初の3bitでアセットのdivisibilityを指定する。
    (divisibilityはOAのようにメタデータで定義せずにトランザクション内に含められてる)
  • 最後の1bitはアセットがロック中かアンロック中か指定する。
アセットのDivisibility

アセットには、アセットの量のスケールを指定するDivisibilityを割り当てることができる。例えば

  • divisibility:0は整数に対応しており、アセットの量は1,2,3, etc...といった単位になる。
  • divisibility:1はスケールが小数点1位となり、値は0.1, 0.9, 1.5, etc...といった単位になる。
  • divisibility:3はスケールが小数点3位となり、値は0.001, 0.999, 123.456, etc...といった単位になる。

従ってdivisibility:0のアセットを100発行した場合、整数値の量を送付でき、divisibility:2でアセットを100発行すると0.01〜0.99までのアセットを送付するようになる。

OP_CODE

発行と転送のOP_CODEsはトランザクションの処理中に実行される。

トランザクションあたりのアセット処理キャパシティ

1つのトランザクションで送付できるアセットの量はパラメータの数によって変わる。例えば、なんのメタデータもなく全ての転送に最小の2バイトを使うだけであれば、18個の転送命令を1つの転送用トランザクションに入れることができ、発行用トランザクションでは17個まで処理できる。

実際の理論的な限界はもっと高いけど、これは最後の出力に行方不明なアセットの転送命令を加える必要があるため(おつりとか手数料)↑の個数になる。

所感

  • 現状はOP_RETURNが80バイトに拡張されたので基本的に全てのデータをOP_RETURN内に格納することができるかもしれないけど、マルチシグのアドレスをデータの保存に使うというアイディアはおもしろい。
    (必要な秘密鍵は1つなので本来のマルチシグの意味は無いけど)
  • メタデータをTorrentsで共有して、メタデータのハッシュを使った改竄検知が仕組みがあるのは良いなー。

具体的なメタデータのハンドリング方法やアセットを転々流通させた際のasset IDの計算や、攻撃に対する対策とかはまた調査していきたい。