Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoinベースの新しいデジタルアセットプロトコル「RGB」

Lightining Networkとの連携も含めた、「RGB」というBitcoinベースの新しいデジタルアセットプロトコルが発表された↓

github.com

RGBのプロトコル仕様は、現状以下の5つのモジュールに分かれている。

  1. RGB
    プロトコルのコアおよび低レベルのアセットロジックを定義。
  2. Kaleidoscope
    他のモジュールを包括しプロトコルとして相互作用するための高レベルの機能を定義。
  3. Bifröst
    クライアントサイド検証の枠組みのプルーフの保存と公開について定義。
  4. Lighting Network Integration
    RGBをLighting Networkに適用する(アセットに対応したルーティング、チャネルの更新、クローズなど)ために必要なBOLTの拡張などを定義。
  5. Proofmarshal
    アセットに特化した形で、スケーラビリティとプライバシーを向上させる、Lightning Networkを補完・代替するレイヤー2ソリューションの定義。

まだ完成という訳ではないっぽく、現時点で使用が少しでも記載されてるのはRGBと、Bifröst、Lighting Network Integration。いずれもまだ作成途中っぽい。Lighting Networkで任意のアセットをオフチェーンで取引するための拡張仕様が定義されてたり、LNとは別のスケーラビリティソリューションの提案とか特徴的。

まずは、RGBモジュールみながらコア機能についてまとめた。

アセットの検証

一般的に、カラードコインはOP_RETURNを利用してBitcoinのトランザクションレイヤーを拡張しているが、Bitconのプロトコル上、OP_RETURNにあるデータは何の意味ももたず、その上に構成されるアセットの取引もコンセンサスレベルで関与することはない。そのため、こういった拡張プロトコルでは、そのプロトコルに対応したウォレットやノードなどのクライアントが、アセットの振る舞いの検証をするClient Side Validationモデルを採用する。RGBも他のカラードコインのプロトコルと同様このClient Side Validationを採用している。

コントラクト

アセットがどのようなもので、アセットの発行方法、転送のルールなどを定義したものをコントラクトと呼んでいる。このコントラクトのデータは以下の2つのデータで構成される。

  • header
    コントラクトの全種類共通のヘッダ項目
  • body
    コントラクトの種類毎に定義される項目

headerのデータ項目は以下の通り。

フィールド 内容
title アセットコントラクトのタイトル
description アセットコントラクトの定義
contract_url コントラクトとlight-anchorの発行に関する一意のURL
issuance_utxo このコントラクトをデプロイするためのコミットメントを持つトランザクションで使用されるUTXO
network 使用中のネットワーク(mainnet, testnet)
total_supply 総供給量(単位はsatoshi)
min_amount dust limitのように転送する際のトークンの最小量
max_hops 再発行前の最大ホップ数(この機能を無効にする場合は0xFFFFFFFFを設定する)
reissuance_enabled 再発行機能を有効にするかどうか
reissuance_utxo (オプション)トークンを再発行する際に使用するUTXO
burn_address トークンを償却する際の送信先アドレス
commitment_scheme このコントラクトで使用するコミットメント方式
version 使用されたブループリントのバージョンを表す16 bitの数値

Open Assets ProtocolなんかだとAsset Definition Fileに近いけどあれはメタデータ的な位置付けで、↑ではアセットの種類による振る舞いやルールも定義するようになっている。

アセット識別子:asste_id

各アセットはasset_idで識別される。このasset_idコントラクトのいくつかのデータ項目のハッシュから計算されるようだが、現時点では算出方法については書かれてない。

Proof-of-burn

アセットを焼却する際は、コントラクトのheader内のburn_addressで指定されたアドレスにアセットを送る。

ブループリント

コントラクトには種類があって、この種類によってアセットがどのように管理されるかであったりその振る舞いが決まる。これをブループリントと呼んでいる。

現状定義されているブループリントは以下の3つ。

Simple issuance: 0x01, version: 0x0008

シンプルなアセット発行のコントラクトで、headerのtotal_supplyで指定された量のアセットを発行し、owner_utxo宛に送る。

このタイプのコントラクトのbodyのデータ項目は、以下の通り。

フィールド 内容
owner_utxo 全てのトークンを受け取るUTXO

この場合コントラクトは以下のようになる。

{
  "kind": 0x01 // 作成するコントラクトの種類で、これは一般的な発行
  "version": 0x0008 // このコントラクトの種類で使われるバージョン
  "title": <String>, // アセットコントラクトのタイトル
  "description": <String>, // 償還可能なアクションと非スクリプトによる条件の定義
  "issuance_utxo": <String>, // このコントラクトへのコミットメントに使われるUTXO
  "contract_url": <String>, // コントラクトおよびlight-anchorを公開するための一意のURL
  "total_supply": <Integer>, // 総供給量(satoshi)
  "max_hops": <Integer>, // 再発行前にアセットに対して実行可能なオンチェーン転送の最大量
  "min_amount": <Integer>, //一緒に転送可能なカラーリングされたsatoshiの最小量
  "network": "BITCOIN", // 使用するネットワーク
  "reissuance_enabled": 0, // 再発行の無効化
  "burn_address": <Address>, // トークンを焼却するのに使用するアドレス
  "commitment_scheme": "OP_RETURN", // このアセットで使用するコミットメント方式
  "owner_utxo": <String>, // 全ての発行トークンを受信するUTXOで、コントラクト指定のフィールド。
}
Crowdsale: 0x02, version: 0x0008

クラウドセール用のブループリント。total_supplyまで指定した価格でトークンを販売する。コントラクトには異なるasset_idをもつ2つのアセットが作られる。1つは通常のトークン用のアセットでもう1つは払い戻し用のトークン。払い戻し用のトークンはクラウドセールの期間前や後に送金してセールを逃したユーザー向けのもの。

このタイプのコントラクトのbodyのデータ項目は、以下の通り。

フィールド 内容
deposit_address トークンを購入する際のBitcoinの送金先アドレス
price_sat 1トークンあたりの価格(satoshi)
from_block クラウドセールを開始するブロック
to_block クラウドセール終了のブロック
Re-issuance: 0x03, version: 0x0008

アセットの発行者が、供給量を増やすことでアセットの再発行を可能にするブループリント。このコントラクトを使用する際は、オリジナルのコントラクトのreissuance_enabledが0でないこと。またオリジナルコントラクトのreissuance_utxoで指定されているUTXOを使ってデプロイする必要がある。

このコントラクトの場合、header内のtitle,description,network,min_amount,max_hops,burn_address,commitment_schemeはオリジナルから変わらないので全て0をセットする。

またbodyのデータ項目はない。

プルーフ

コントラクトは上記のように種類によってルールが異なるが、各コントラクトに設定された全ての条件を満たすことでアセットの所有権を証明し、そのアセットの送付が可能になる。このコントラクトに設定された全ての条件を満たしたことを証明するのがプルーフになる。

プルーフコントラクトと同様headerbodyを持つとされているが、具体的な項目についてはまだ定義されていないっぽい。

アセット送付時のプルーフ

アセットを送付する際は、以下のデータがプルーフになる。

  • アセットの発行から今までの全てのプルーフのチェーン
  • 以下3つの項目からなるリスト
    • 取引するトークンのカラー
    • 取引する量
    • 送信するトークンのアウトプットに関する情報で、UTXOベースのトランザクションを送信する場合はSHA256D(TX_HASH || OUTPUT_INDEX_AS_U32)で、アドレスベースのトランザクションを送信する場合は受信者に送信するアウトプットインデックス。
  • (オプション)meta-dataに関連するmeta-script

これらのプルーフは以下のdark-tagを使ってAES256で暗号化され、Publisher Serverに送られる。

dark-tag

アセットの受取人が生成する30バイトのエントロピーを持つ共通鍵で、アセットを送ってもらう際に、アドレスおよびPublisher Serverの情報と一緒に、アセットの送信元に送る。

受取人がdark-tagを生成する際は、受信用のアドレスを生成するのに使用しているBIP32ベースの導出鍵を使って導出する。

プルーフの情報はこのdark-tagで暗号化されているため、取引されているカラーや量に関してはこのdark-tagを知っているユーザーのみが把握でき、第三者ブロックチェーン上のトランザクションを確認してもこれらの情報は確認できないと思われる。

dark-tagが漏洩すると、発行トランザクションからそのトランザクションまでのアセットの流通経路は分かるが、途中で分岐していた場合などはそっちのアセットの流通経路までは分からない。

Publisher Server

Publisher Serverは、各アセットの取引で生成された暗号化されたプルーフを保存し、そのクエリに対応するサーバー。アセットの発行者によってメンテナンスされる場合もあるし、個々の受信者がメンテナンスしたり、第三者によって提供されることも考えられる。

BitTorrentやIPFSなどの分散ストレージの利用も挙げられているが、RGB自体はPublisher Serverについてシンプルさのため集中型の管理もありとしてる。

コミットメント方式

アセットを新規発行する際は↑のコントラクトのデータを、アセットを送付する際はその条件を満たしていることを証明する↑のプルーフをそれぞれブロックチェーンにコミットする必要がある。Open Assets Protocolでは、これらは基本的にOP_RETURNのアウトプットにMakerOutputと呼ばれるOA用のペイロードをプッシュする形態をとっていたけど、RGBの場合は以下の2種類の方法が用意されている。

OP_RETURN

他のカラードコイン同様OP_RETURNを使う方法で、OP_RETURNの後に↑のコントラクトやプルーフのエンティティ情報をプッシュする。OP_RETURNを使ったRGBの有効なコミットメントを含むトランザクションのルールは以下の通り。

pay-to-contract

pay-to-contractは直訳するとコントラクトへの支払い。コントラクトの内容を元に鍵およびアドレスを生成するプロトコルで、昔Blockstreamが発表したSidechainのホワイトペーパーなどで紹介されている。

RGBのエンティティにコミットするpay-to-contractアドレスは以下のように計算する。

  1. ランダムに128 bitのnonceを生成する。
  2. weak = hmac_sha256(key=original_pubkey, data=(nonce||double_sha256(RGBのエンティティ)))を計算する。
  3. new_pubkey = original_pubkey + G * tweakを計算する。
  4. 計算したnew_pubkeyを公開鍵として、P2WPKH or P2PKHアドレスを生成する。

この公開鍵に対応する秘密鍵は、元の秘密鍵に対して同じ計算を適用することで計算できる。

後は計算したアドレス宛に送金するトランザクションを作るだけで、トランザクションの構成は通常の支払いと何ら変わらない。

アセットの送付方法

RGBで実際にアセットを送付する際、送信者は以下の2つの方法でアセットの所有権を移転できる。

アドレスベース

アセットの受信者がアセットのUTXO自体を受け取りたい場合に使用する。この場合、プルーフには、トランザクション内の受信者の送信先アドレス宛のアウトプットのインデックスをセットする。

※ アセットを受信者のアドレスに送るという直観的に分かりやすい方法で、他のカラードコインなどでも一般的によく使われている方法。

UTXOベース

受信者が既に持っているUTXOに、トークンをバインドしたい場合に使用する。このためこの送付トランザクションには受信者向けのアウトプットは含まれず、プルーフには、送信先のUTXOのハッシュをセットする。

※ この場合ブロックチェーントランザクションを見ただけでは、誰から誰にアセットが送付されているのか推測できない。

この場合、複数のアセットが同じUTXOを指定していた場合、そのUTXOは両方のアセットを持つということになるのかな?

RgbOutPoint

上記のようにアドレスベースの場合は送信トランザクションのアウトプットインデックスを、UTXOベースの場合は受信者の既存のUTXOのOutPointを指定することになるが、それぞれをエンコードしたオブジェクトをRgbOutPointと呼んでいる。

RgbOutPointシリアライズする際は、どちらか分かるようUTXOベースの場合は0x01、アドレスベースの場合は0x02がプレフィックスとして付与される。(長さで分かりそうな気がするけど)

所感

Open Assets Protocolとかだと、取引するアセットの量や宛先は全てトランザクション内のMarkerOutput(OP_RETURNにOpen Assets Payloadをプッシュしたもの)で管理されていて、OAのトランザクションを解釈できれば、ブロックチェーン上でどのアドレスからどのアドレスにいくつのアセットが送られているか確認できるプロトコルだったけど、RGBの場合取引するアセットやその量は全てプルーフに記載され、受信者が生成した共通鍵dark-tagで暗号化されPublisher Serverと呼ばれる外部ストレージに保存されるようになっている。ブロックチェーン単体ではアセットの動きは追えず、外部にあるプルーフが必要になる。UTXOベースのトランザクションであれば、プルーフのみがブロックチェーンアンカリングされているといっても良い。

ノードはトランザクション内のコミットメントとプルーフから受信したアセットの情報を判断するので、フルノードでなくSPVノードのような軽量ウォレットでもアセットの管理ができるだろう。

まだ不明点も多いので具体的な実装を含めてプロトコルの完成までまだ時間かかりそうだけど、他にもLNとの連携や、LNとは別のスケーラビリティソリューションなど面白そうな機能はあるので、今後が楽しみ。

不明点

↓のようにドキュメントの中に出てくるけど、内容や仕組みについてまだ書かれてないことが多い。

  • asset_idの計算方法
  • プルーフの具体的な構成と、検証の仕組み
  • プルーフチェーンの構成方法とその正しさの証明
  • meta-dataやmeta-scriptの内容と振る舞い
  • dark-tagの導出方式
  • Publish Serverと通信する際の具体的なプロトコル