Develop with pleasure!

福岡でCloudとかBlockchainとか。

MultiChainにみるPrivate Blokchainを作る際のポイント

BitcoinのBlockchainは公開台帳なわけだけれど、PrivateなBlockchainってどうやって作るんだろう?
Bitcoin Coreをフォークして別のポート番号やnamespace変更して起動すればできるのか?と思ったけど、P2Pノードとして分散動作するとPrivateな要件は満たさない。
とモヤモヤしてたところ、MultiChainというPrivate Blockchainのホワイトペーパーが公開されてたのでざっと読んでみた。

http://www.multichain.com/download/MultiChain-White-Paper.pdf

Bitcoinの欠点

ホワイトペーパーで取り上げられてる欠点は↓のようなもの。

  • 容量不足
    BitcoinのBlockchainは1日あたり30万トランザクションでブロックサイズの上限は1MB。多くの金融プラットフォームにおいてこのキャパシティではお話にならない。、
  • トランザクションコスト
    トランザクションの手数料が低いとなかなかブロックに含まれにくい。将来的にトランザクション量が増えていくとトランザクションをブロック含めるための入札みたいになってきて手数料の増加になるんじゃ?
  • 無関係なデータ
    公開台帳なので自分と全く関係な取引のデータも確認、保存しなくちゃならない。
  • マイニングリスク
    ポアソン分布によって定義される平均10分というproof of workによるマイニングはブロックの作成とトランザクションの確認の時間が読めない。イデオロギーや経済的な理由によってトランザクションを拒否するといった可能性がある。あと可能性は低いけど51%攻撃。
  • プライバシーの欠如
    公開台帳なので全ての取引が参照できちゃう。
  • オープン性
    オープンなので誰でもノードに参加できるし、身元確認もされないので、違法性のある取引において魅力的なプラットフォームになる。

まぁこういった欠点がありながらも既にBitcoinは流通していて、Bitcoinを受け入れる個人・企業といった枠組みができあがっているので、オルトコインなどがなかなか浸透しにくい土壌になってるので、他のチェーンからよっぽど画期的な機能がリリースされない限りBitcoinのBlockchainの成長は続くと思われる。

MultiChainで実現してるPirvate Blockchainの仕組み

MultiChainでは、ユーザ権限を導入することで、ノードに参加可能かどうか、参加後に利用可能な機能等を制限するようにしてる。MultiChainのコアな目的は↓の3つ。

  • Blockchain上のアクティビティは許可されたユーザによってのみ行われることを保証する。
  • トランザクションのコントロール
  • proof of workに関するコストをかけずにマイングを行う
ノードとして接続できるか判定するハンドシェイクプロセス

MultiChainではBlockchainで2つのノードが接続する際に発生するハンドシェイクプロセスを以下のように拡張して、許可されたユーザ以外はBlockchainに接続できないようになってる。

  1. 各ノードは許可リストの公開アドレスとしてのアイデンティティを提示する。
  2. 各ノードは他のノードのアドレスが自身の許可リストのバージョンにあるか検証する。
  3. 各ノードは相手にチャレンジメッセージを送信する。
  4. 各ノードはチャレンジメッセージに署名をして送り返すことで、自身が提示した公開アドレスに対応する秘密鍵を所有していることを証明する。

各ノードは、結果に満足しない場合P2P接続を中止する。

権限を公開アドレスに紐付けるという原理は、ネットワークの他の多くの操作に拡張できる。
例えば、トランザクションには送信者、受信者両方のアドレスが含まれるので、与えられたアドレスのリストを参照して、トランザクションを送信もしくは受信していいかどうかを制限できる。
場合によってはBlockchainの内容は全て参照可能にして、取引のみ制限したいというケースも対応可能。
また、coinbaseトランザクションに署名フィールドを追加しマイナーの署名を含めることによって、MultiChainでのマイニングを同様に制限できる。

トランザクションメタデータを利用した権限管理

MultiChainでは、特殊なメタデータを含むネットワークトランザクションを使って全ての権限の付与・取消を行う。
最初の“genesis”ブロックのマイナーは自動的に他のユーザの権限管理も可能な管理者権限を含む全ての権限を手に入れる。この管理者は権限を付与するユーザのアドレスと一緒に権限を付与するメタデータトランザクションに入れて送信することで、ユーザに権限を付与する。
管理者権限や他のユーザのマイニング権限を変更する場合は、変更を許容するか既存の管理者による投票が行われる。これらの投票は管理者によって別のトランザクションで登録され、充分な合意に達したら変更が適用される。
“setup phase”と呼ばれるチェーンの最初のいくつかのブロックでは、単一の管理者がこの投票プロセスを回避することができる。
MultiChainの将来のバージョンでは、権限の付与・取消を自由にできる“super administrators”が導入されるみたい。

権限の変更がトランザクションメタデータに埋め込まれるため、ネットワーク内の全てのノードに迅速に伝搬し、合意を作成する。しかし、ネットワークは分散化しているため、別のノードが別の時間に権限のトランザクションを受信することもあれば、別のトランザクションと前後することもある。
そのため、例えば支払いのトランザクションの有効性が直前にブロードキャストされた権限変更のトランザクションに依存している場合、あるノードは受理しあるノードは拒否をするといった違いは致命的になる。

そんな問題を解決するために一度Blockchain上でトランザクションの確認が行われると、その最終的な順序は固定化される。全てのノードはBlockcina上の順序に‘replayed’されるというルールに従い、ブロック内の各トランザクションは、直前のユーザ権限の状態に応じて有効となる。ブロック内のトランザクションがこのルールに従わない場合、そのブロックは無効なブロックとして扱われる。有効なブロックのマイナーはそのブロック内の全ての権限の変更が適用された後に許可リストに含まれている必要がある。

MultiChainにおけるマイニング

MultiChainでは、与えられた時間内に同じマイナーによって作成できるブロック数を制限することによって、Private Blockchainにおいて1人の参加者がマイニングプロセスを専有するというジレンマを解決する。
MultiChainは”mining diversity”と呼ばれるパラメータを使ってこれを実装している。(0 ≤ mining diversity ≤ 1)以下のプロセスで判断する。

  1. ブロック内のトランザクションの順番に全ての権限変更の適用を実施する。
  2. 権限変更の適用が終わった後で、マイニング可能なマイナーをカウントする。
  3. マイナーにmining diversityを掛け、切り上げる。
  4. このブロックのマイナーがもし1つ前のブロックをマイニングしていたら、このブロックは無効となる。

ラウンドロビンのスケジュールをを強制することで、許可されたマイナーが有効なブロックを作成するにはローテーションしなけばならなくなる。mining diversityパラメータはネットワークを害そうとするマイナー達の割合によって決める。
0を設定すると全て制限が無い状態になり、1を設定すると全てのマイナーがローテーション中となる。一般的にはより高い値の方が安全だが1に非常に近い値を設定するといく人かのマイナーが非アクティブな状態になるとBlockchainがフリーズすることがある。
合理的な値として0.75が推奨されてる。
こういう制約があるので、ノード側もリソースを節約するため、1つ前のブロックを既に自身がマイニングしていた場合、ブロックをマイニングしようとはしない。

あと面白いのがこのmining diversityはネットワーク遮断時にも有効な仕組みになる。ネットワークが不通の状態だと他のトランザクションやブロックを参照することはできないのでチェーン内のフォークに繋がる。ネットワークが繋がるようになると、より長いフォークを持つチェーンが全体的な合意として採用される。diversityの閾値によって、より長いBlockchainをもつ孤立したグループに許可されたマイナーの大部分がいることが保証される。(他のグループのBlockchainはすぐにフリーズしてしまうため)

マイニングコスト

MultiChainのBlockchainではデフォルトで取引手数料やブロック報酬はデフォルトで0。ブロックをマイニングするコストがわずかなら、マイナーはBlockchainの運用がスムーズに進むよう利害関係を越えて補償を必要とせずにマイニングを行う。あるいは、マイナーは、伝統的なオフブロックチェーンで支払われていたように、ネットワークの参加者に年間で固定額のサービス料金を請求することになるかもしれない。
Blockchainの目的がトークン化された資産の取引である場合は、“native”の通貨は成果物の展開として無視されるだろう。しかしトランザクションが不足するようであれば、MultiChainはブロック報酬と最小取引手数料にネイティブの通貨を使用することができる。この場合参加者は、トークン化された資産と引き換えにマイナーからネイティブの通貨を購入する必要がある。

MiltiChainの設定項目

MultiChainではユーザが以下の内容を含む全てのBlockchainのパラメータを設定ファイルに定義できる。

  • チェーンのプロトコル。(Private Blockchainなのか純粋なBlockchainなのか)
  • ブロックの目標時間。(1分とか)
  • アクティブな権限のタイプ(誰でも接続可能とか、特定のユーザしか送信/受信ができないとか)
  • 上述したMining diversity(Private Blockchainの場合のみ)
  • 管理者とマイナーを追加/削除するのに必要な合意レベルと、セットアップフェーズで合意を必要としない期間。(Private Blockchainの場合のみ)
  • マイニング報酬(ブロックあたり50ネイティブ通貨とか)
  • P2P接続する際のポートと、JSONRPC APIのポート(8571, 8570)
  • 許可するトランザクションタイプ(pay­to­address, pay­to­multisig, pay­to­script­hashとか)
  • 最大ブロックサイズ(1 megabyte)
  • トランザクションあたりの最大メタデータサイズ=OP_RETURNのサイズ(4096 bytes)

1つのサーバ上に複数のBlockchainが利用できるので、それぞれ設定ファイルは別の名前を付ける必要がある。新しいBlockchainを作るには2つの簡単なステップが必要になる。

  1. 最初にユーザはチェーンの名前を選ぶ。そうするとMultiChainはその名前でデフォルト設定を含む設定ファイルを作成する。デフォルト値はユーザによって変更可能。
  2. 続いて、Blockchainを起動するとgenesis blockがMultiChainによってマイニングされ、作成者に全てのユーザ権限が付与される。この時点で、その後の偶発的な変更を防ぐためにMultiChainにgenesis blockと一緒に設定ファイルに記載されてる全てのBlockchainパラメータのハッシュを埋め込む。

初回起動時はBlockchainは単一ノードで起動される。新しいノードを追加するには、次の3つのパラメータを使って別のコンピュータでMultiChainを起動する。

  • Blockchain名
  • IPとポート番号
  • 既存のノードのIPアドレス

利便性のためこの情報はお馴染みの形の“node address”になる。( chain1@12.34.56.78:8571 のような)
最初に新しいノードは、ネットワークがprivateで接続権限を持っていないので接続が許可されることは無い。MultiChainは新しいノードで自動生成された公開アドレスを含むメッセージを管理者に送る。管理者は簡単なコマンドを使って、接続権限を付与するトランザクションを作成する。その後新しいノードは再接続の成功し、自動的にBlockchainの属性が定義された設定ファイルをダウンロードできる。その後の同じBlockchainへの接続はチェーン名を指定するだけで、ノード間のハンドシェイクプロセスでは同一のパラーメータを使用するのを保証する。

アセットの発行と制限

Bitcoinでは、各トランザクションはその出力に含まれるBitcoinの量をエンコードする。トランザクションの入力のBitcoinの総量より多くの量のBitcoinがその出力にセットされている場合、そのトランザクションはネットワークによって無効とみなされる。全てのネットワークノードは未使用のトランザクションの出力(UTXO)でBitcoinの量を把握するため、この検証が可能となる。結果、ネットワーク、Blockchainに含まれるトランザクションに含まれるエンコードされたBitcoinの量は充分信頼できる。そのためSPVのような軽量ウォレットでもBlockchainの全データを保存することなく安全な取引が可能になる。

Bitcoin越しのアセットのトークン化では、非ネイティブなアセットの存在を定義するメタデータが同じネットワークの検証対象ではないということが問題になる。
例えばABC銀行がドルを表すトークンを発行したとして、不正なユーザは、トランザクションの入力にABCのドルが一つもない状態でも、出力に100ABCドルを含んでいるというメタデータトランザクションを作成することができる。BitcoinのBlockchainではメタデータは参照されず、ABCドルのトラッキングも行われないので、このトランザクションは有効とみなされる。

そのため、トークン化したアセットはBitcoinのBlockchain上では、そこで流通するBitcoinに比べてセカンドクラスの位置付けとなる。トークン化したアセットの存在は、トークンが作られたトランザクションを起点とした全てのトランザクションを調べることで確認できる。

MultiChainではこの問題をBitcoinスクリプト言語が提供する拡張機能を使って各トランザクションの出力にあるアセットのIDと量をエンコードすることで解決している。トランザクションの出力に含まれている全てのアセットの合計とトランザクションの入力に含まれているアセットの合計がマッチするようトランザクションの検証ルールを拡張している。この等価チェックはBitcoin量のチェックより厳格である(Bitcoinの場合、入力の合計より出力の合計が少なくても、差分はマイナーの手数料になるため)。

MultiChainの拡張アプローチ

MultiChainの設計の大部分は、BitcoinのBlockchainとPrivateなBlockchain間のスムーズな移動を目的としていて、以下のような設計になってる。

  • Bitcoinネットワークの公式クライアントであるBitcore Coreをフォークしている。コードは将来Bitcoinの強化のためマージできるよう変更、ローカライズしている。
  • MultiChainはBitconiのプロトコルトランザクション、Blockchainアーキテクチャを使用しており、ノード間の初期接続の際のハンドシェイクプロセスのみ変更している。その他の機能はメタデータトランザクションやブロックの検証ルールを変更して実装している。
  • CLIやRPC等のAPIについては新しく追加されたネットワークコマンド等もあるが、Bitcoin Coreと完全互換がある。
  • MultiChainのBlockchainの設定ファイル内のプロトコルの設定によって、通常のBitcoinのネットワークノードして動作させることもできる。
  • Bitcoinトランザクションを強化する、CoinSparkのような多通貨とメッセージング機能機能をサポート。

所感

  • ユーザ権限の認可の設定もトランザクションメタデータ使って実現してるのは面白い。せっかくのP2P環境なのに権限管理する中央サーバなんかがいると意味なくなるので。
  • Open Assets ProtocolとかもOP_RETURNに記載するメタデータを使ってアセットの数を管理しているので、そういった意味ではノードレベルで入力と出力の量の等価性は判断できないので、こういったところはMultiChainが行ってるようなスクリプト言語を拡張して等価性をチェックできるようなBIPがあっても良いと思う。
  • Private Chainだけあってトラザクションサイズ(メタデータのサイズ)自由に増やせるのは便利。
  • BitcoinのBlockchainのマイニングパワーを利用しないチェーンを作る場合は、BitcoinのBlockchainのように成熟期を迎えてないチェーンにおいては、マイノリティによるマイニングの専有を防ぐための仕組みは大事。