Avalancheでブロックチェーンを作ってみる ~Snowflakes, Snowmen, Avalanche Terrain~
AvalancheはDeFiのような金融サービスやエンタープライズアプリケーションをプラグプレイできる一元化したプラットフォームとして機能するブロックチェーンのプラットフォームです。高い相互運用性と拡張性を持ち、複雑なルールセットを持つアプリケーションやカスタムブロックチェーンネットワークを複雑なプロセスなく作成したり、既存のプライベート/パブリックサブネット上に構築することができるようになります。前稿ではプライマリチェーンの1つであるContract Chain(C-Chain)にスマートコントラクトをデプロイしてみました。Avalancheには複数のブロックチェーンを持つサブネットという概念が存在しています。サブネットの作成によって、アプリケーションを実装するブロックチェーン・VM(Virtual Machine)を生成することができるようになります。本稿ではサブネットなどの概念を俯瞰した上で、実際にAvalancheプラットフォーム上にサブネットやブロックチェーンを作ってみたいと思います。
AvalancheについてはAvalanche-Japaneseの公式Mediumが充実しています。基本的には公式サイトと公式のドキュメントをソースとしています。また手前みそですがAvalanche概略とC-Chainについては前回簡単にまとめてありますのでご覧ください。[1]
Avalancheは「ナカモトコンセンサス」(堅牢性、規模、分散化)と「クラシカルコンセンサス」(速度、迅速なファイナリティ、エネルギー効率)の利点を併合し、高い分散性とスループット、秒未満のファイナリティを可能としつつ、高いエネルギー消費や複雑なシャーディングを避けている点にその革新性があると思われます。
加えてサブネットによるブロックチェーン作成やトランザクションを検証するバリデータセットの分割、アプリケーションごとのVM(Virtual Machine)の選択など高スループットかつ、早いファイナリティでブロックチェーンのネットワークを構成することができるようになっている点が他のブロックチェーンとは異なっています。
これらの特性は同じL1(レイヤー1)のブロックチェーンであるEthereumやPolkadot、Cardanoなどに対して明らかな優位性があります。EthereumのアプリはEVM上でしか動作しませんが、Avalancheではアプリ固有のブロックチェーンを追加することが可能です。Polkadotのパラチェーンは参加上限数があるため、様々な制約や集権性が存在しています。
目次です。
- マルチチェーンデザイン(再掲)
- サブネットの作成
- バリデータの追加
- VM(Virtual Machine)
- ブロックチェーンの作成
マルチチェーンデザイン
Avalancheは、重要な機能の役割を分割し、異なるデータ構造を採用する3つのブロックチェーンを持つマルチチェーンフレームワークを採用しており、開発者はアプリケーションに対して最大限の柔軟性と制御を行うことが可能となります。プライマリーチェーンはExchange Chain(X-Chain)、Contract Chain(C-Chain)、Platform Chain(P-Chain)でC-Chainがデフォルトのスマートコントラクト用のチェーンです。C-ChainはEVM(Ethereum Virtual Machine)互換でSolidityによるスマートコントラクトやEthereumツールとの完全な互換性を持っています。
チェーンは個別のVM(Virtual Machine)のインスタンスで、VMやWASMなどの複数のカスタムVMがサポートされているためチェーンはユースケースに応じた機能を持つことができます。Avalancheは様々なサブネットで構成され、サブネットと呼ばれるカスタムブロックチェーンネットワーク上に配置され、「一連のブロックチェーンの状態に関するコンセンサスを達成するために協力して働くバリデータの動的なセット」で構成されます。バリデータは少なくともプライマリーチェーンの3つを含むサブネットのメンバーとなる必要があります。
各バリデータ―は少なくともプライマリーチェーンのメンバーですが、その他のチェーンについてはアプリケーションに応じて動的に参加することが可能です。プライベートサブネットの作成によって、アプリ開発者は実装のルール、経済性、参加者、セキュリティを柔軟かつ詳細に設定することができるようになります。Avalancheは様々なサブネットで構成され、1つの相互運用可能なネットワークを形成するブロックチェーンのプラットフォームとなることを前提としています。[2]
X-Chain — スマートデジタルアセットの作成と取引のための分散型プラットフォームとして機能するAvalanche Virtual Machine(AVM)のインスタンスです。トランザクションが時系列やブロックの高さによって編成される従来のブロックチェーンとは対照的に、AvalancheのX-Chainは有向非周期グラフ(DAG)です。アセットの作成にはAVAXによる手数料の支払いが必要ですが、この手数料はバーンされます。
C-Chain — EVMのインスタンスがあるチェーンです。EVM互換でMetaMask、Web3.js、Remix、Truffle Suite、Embark Platformなどの分散型金融(DeFi)の成長を支えたEthereumツールをそのまま使用できます。既存のEthereumアプリケーションはAvalancheから容易に移設可能で、毎秒数千件のトランザクションを処理し、低いガス料金で、Solidityの容易な動作などの利点を享受することができます。
P-Chain — Avalanche上のメタデータチェーンであり、ステーク、ネットワーク間のバリデータの調整、カスタムサブネットの作成を担当します。全てのAvalancheのバリデーターはP-Chainのステークに参加してコアネットワークのセキュリティを確保しますが、各バリデーターは、ダイナミックまたはプライベートなバリデーターセットを形成してサブネットを運用することができます。
各サブネットは、独自のトークンや手数料などの料金体系を設定できます。ステークキングや取引手数料をAVAX、ステーブルコイン、独自のトークンによる支払いに設定することもできます。Avalancheはコンセンサスプラットフォームであるため、プロジェクトは既存のトークンやアプリケーションを移植してAvalanche上で使用することができます。誰でもAVAXでサブスクリプションスタイルの料金を支払うことで独自のサブネットを作成することができます。新しいブロックチェーンを作成するために既存のサブネットを使用することも可能です。サブネットの作成とブロックチェーンの料金は両方ともAVAXで支払われ、トークンはバーンされます。バリデータは3つのプライマリーチェーンに加えて独自のサブネットなど複数のサブネットを検証可能となっています。
サブネットの作成
Exchange Chain(X-Chain)、Contract Chain(C-Chain)、Platform Chain(P-Chain)の3つがデフォルトのチェーンであることに言及しました。ここではサブネット、ブロックチェーンそしてバリデータの関係について見ていきたいと思います。ちなみにサブネットという呼称はIPネットワークにおけるサブネットと同じなので紛らわしいのですが、あえてこの名前を当てているような気がしています。
- プライマリーネットワーク
プライマリーネットワークは特別なサブネットです。カスタムブロックチェーンなどを動かすすべてのサブネットはこのプライマリーネットワークのメンバーである必要があります。ネットワークのハブをイメージすると分かりやすいかと思います。3つのデフォルトチェーンはすべてこのプライマリーネットワークのブロックチェーンです。
- サブネット
サブネットには動的なバリデータによってコンセンサスメカニズムが動作する複数のブロックチェーンセットが存在します。各チェーンは必ず1つのサブネットによって検証されます。サブネットには複数のブロックチェーンを適用可能で、ノードはさらに複数のサブネットのメンバーとなることが可能です。サブネットの分割によってどのような利点があるかを見てみましょう。
コンプライアンス — 特定の国にあるバリデータセットのみ使用したい、特定のKYC/AMLをパスしたノードのみ使用したいなど分散性とは別のレイヤーでバリデータの要件が必要な場合
プライベートチェーン — パーミッションチェーンのように指定したバリデータだけで検証されるチェーンが必要な場合、外部から実質非公開となるようなチェーンの作成
アプリ要件による制約 — アプリケーション固有の事情によって要件がある場合、例えばCPUやメモリに要件がある場合はサブネットで要件を指定することでバリデータが制限可能となる
バリデータはその性能や要件に応じて複数のサブネットへ参加することが可能となっています。ただしプライマリーネットワークのメンバーであることは必須となっているためデフォルトチェーンのバリデータとの兼業となります。前述のとおりカスタムサブネットでは、バリデーター、手数料などのエコノミーモデル、VM(Virtual Machine)などを完全にコントロールおよび設定することができます。バリデータセットは、他のブロックチェーンからVM(EVMなど)を移植して、コンセンサスメカニズムを置き換え、ネットワークのパフォーマンスとスマートコントラクトのロジックを最適化することができるようになります。
サブネットが作成されるとスレッショルドとキーセットが設定されます。バリデータを作成したサブネットへ追加するためにキーセットから得られるスレッショルドの署名が必要です。キーセットをコントルールキーと呼び、バリデータを追加する際に必要なコントロールキーの署名をコントロール署名と呼びます。本稿ではFuji Testnetでスレッショルド2、コントロールキー2つの設定でサブネットを作成してみます。まずはAvalancheGoをインストールしてローカルでブロックチェーンを走らせます。
ソースコードからのビルドがうまくできなかったのでバイナリを使用しました。最新のAvalancheGo-v1.4.2です。バイナリのインストールおよびノードの実行は以下の公式ページを参考にしました。[3]
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 61
Model name: Intel Core Processor (Broadwell)
Stepping: 2
CPU MHz: 2400.000
BogoMIPS: 4800.00
Hypervisor vendor: KVM
Virtualization type: full$ mkdir work && cd work
$ wget https://github.com/ava-labs/avalanchego/releases/download/v1.4.2/avalanchego-linux-arm64-v1.4.2.tar.gz
$ tar -xvf avalanchego-linux-amd64-v1.4.2.tar.gz
$ cd avalanchego-v1.4.2/
$ ./avalanchego --network-id=fuji --http-host <your node IP>
ブートストラップ開始と終了のログメッセージが出力されるので、ブートストラップ終了のメッセージが出力されるまでチェーンのシンクを待ちましょう。シンクはX-Chain、C-Chain、P-Chainそれぞれで実施されチェーンが同期されていきます(以下のログ表示のとおり)。
# Initialized a bootstrap
INFO [05-09|20:42:58] <P Chain> avalanchego/snow/engine/common/bootstrapper.go#300: Bootstrapping started syncing with 1 vertices in the accepted frontier# Bootstraping has ended
INFO [05-10|09:38:47] <C Chain> avalanchego/snow/engine/snowman/transitive.go#128: bootstrapping finished with 2HgyLw6F9zvinerdVCZzTMTPhM5eTvzUFxafrLhimnnpiKmuzt as the last accepted block
INFO [05-10|09:39:12] <P Chain> avalanchego/snow/engine/snowman/transitive.go#128: bootstrapping finished with 2r34TWjCvRd4aXd95yhVMUMaMw3W846nuKKUadRpHvFstuq6TX as the last accepted block
INFO [05-10|09:39:21] <X Chain> avalanchego/snow/engine/avalanche/transitive.go#105: bootstrapping finished with 1 vertices in the accepted frontier
APIコールにはPostmanを使うと便利ということですが、サブネット作成の公式ドキュメントは curl
で叩いているので本稿でも同様に curl
で行います。Avalanche用のPostmanのコレクションはここにあります。 curl
でちまちまやるのが面倒くさい人はPostman使ってみてください。[4]
コントロールキーを作成する前にブートストラップが完了していることを確認しましょう。 {"isBootstrapped":true}
が結果として返ってくるはずです。次にノード上のキーストアとキーストアに紐づくユーザを作成します。
キーストアの作成とユーザの作成を行います。これらキーストアとユーザはノードレベルで存在しています。もし他のノードへこのユーザを移設したい場合には KeyStore API
を使用してマイグレーションすることができます。まずFuji Testnet X-Chainのアドレスを作成しておきます。X-fujiから始まるアドレスがX-Chain上に作成されます。
2つのコントロールキーをP-Chain上で作成します。作成した2つのコントロールキーを指定してサブネットを作成できます。ここでは前述のとおりスレッショルド2のパラメータを付与してサブネットを作成しました。公式ページには記載されていませんがサブネットの作成にはコストがかかります。そのための原資をまずは調達しましょう。
作成したX-ChainのアドレスへAVAXを送金します。FaucetからX-ChainおよびC-Chainへテスト用のAVAXを送付できるのでX-fujiから始まるアドレスを指定して2 AVAXを送信、受領していることを確認します。X-Chainのアドレスで受領したAVAXを avm.exportAVAX
platform.importAVAX
のAPIを使用してP-Chainの2つのアドレスへ移動します。
※コントロールキーのアドレスに必要な資金がないとサブネット作成のためのトランザクションを作成できないないとして怒られます(以下)
{"jsonrpc":"2.0","error":{"code":-32000,"message":"couldn't create tx: couldn't generate tx inputs/outputs: provided keys have balance (unlocked, locked) (0, 0) but need (10000000, 0)","data":null},"id":5}
FaucetやWebウォレットから適当にAVAXを送付しました。以下のAPIを叩くと確認できます。この例では10.5 AVAXがノード上のX-Chainのアドレスに存在していることが分かります(念のため繰り返しですがすべてFuji Testnetで実施しています、メインネットのAVAXではないです)。
次に2つのP-Chainアドレスに対して1 AVAXずつエクスポートします。次にP-Chain側でインポートの処理を行う必要があります。ウォレットからは『Cross Chain』というメニューで比較的簡単に行えますが逐次的に実行するとかなり面倒くさいですね。
次にP-Chainでインポートします。この段階でP-Chain側にAVAXを取り込めているのでサブネットの作成は成功します。 txID
がそのままサブネットのIDになります。正常にサブネットが追加されているか確認しましょう。[5]
Fuji Testnetに作成されたサブネットIDです。
2bFRwRRTmvn64z7LuDq4bzLqfjTtFan8GDiMqk6eok85JG8gvK
バリデータの追加
バリデータは少なくともプライマリーネットワークのメンバーである必要があることを思い出しましょう。バリデータをプライマリーネットワークのバリデータとして追加した後に作成した個別のサブネットへバリデータをバリデータセットとして追加します。最初に公式の手順に沿ってバリデータをプライマリーネットワークへ追加しました。[6]
繰り返しとなりますがPostmanのコレクションが提供されているのでPostman使った方が効率的に作業はできると思います。プライマリーネットワークへの追加は、以下gistのパラメータの NodeID
rewardAddress
をご自身のパラメータへ変更する必要があります。
2つのコントロールキーから作成したサブネットIDを指定して、対象ユーザで同様にバリデータをサブネットへ追加します。これでバリデータのプライマリーネットワークへの追加および作成したサブネットへのバリデータの追加が完了しました。
ノードのホワイトリストへサブネットを追加する必要があります。この操作はノードが検証するサブネットを指定するためのもので意図せずノードが他のサブネットをバリデートすることを防ぐことができます。AvalancheGoの起動オプションで --whitelisted-subnets
でサブネットIDを指定するだけです。ここでは自身の作成したサブネットIDを指定。明記されていませんがプライマリーネットワークは最初からホワイトリストされているものと想定されます。
$./avalanchego --network-id=fuji --http-host 127.0.0.1 --whitelisted-subnets=2bFRwRRTmvn64z7LuDq4bzLqfjTtFan8GDiMqk6eok85JG8gvK
VM(Virtual Machine)
VM(Virtual Machine)という言葉はサーバ仮想化の用語と同じで紛らわしいのですが、ブロックチェーンにおけるVMとはブロックチェーンでバイトコードが実行される基盤のことです。単一の機能を持つVMではアプリケーション実装に制限が発生するために、カスタムの分散型アプリケーションが必要なケースでは、独自のブロックチェーンをスクラッチで作成する必要がありました。
Ethereumはブロックチェーンにスマートコントラクトを導入することでこの問題を解決しました。EthereumのEVM(Ethereum Virtual Machine)がVMとしては有名ですが、パフォーマンスの低さやSolidityという新規プログラミング言語の習得などがアドプションの障壁となっていました。AvalancheではブロックチェーンはVMのインスタンスとして扱われます。
AvalancheではGo言語がサポートされ、AVM(Avalanche Virtual Machine)を現在追加することが可能となっています。同じAVMを使用して複数のブロックチェーンを追加したり、独自のアプリ専用のVMを開発してブロックチェーンを追加し、要件に基づいたバリデータで構成されたサブネットへ展開する、といった設定を行うことができます。
将来的にはGo言語でブロックチェーンを開発してVMインスタンスとしてAvalancheのネットワークへ追加することができるようになるようです。Go言語によるVMの開発については以下に掲載されています。[7]
ブロックチェーンの作成
さて前述のとおりカスタムのブロックチェーンの作成は現在行えないため、AVMを作成してサブネットへ追加してみたいと思います(よく読むと現在はAVMとタイムスタンプVMのインスタンスを新規作成できると書いてある、タイムスタンプVMは試していません)。
ブロックチェーンの作成はまずジェネシスの作成を行い、そのジェネシスデータを利用してAVMのインスタンスを追加、という風に進みます。作成されたブロックチェーンがサブネットに紐づくことで対象のバリデータによって検証されるようになるはずです。[8]
avm.buildGenesis
を使用してジェネシスデータを作成しました。ジェネシスデータのバイト表現が返ってくるのでメモしておきます。ハマりポイントですが encoding
をcb58に指定する必要があります。ジェネシスデータを指定する次のパラメータではhexを渡すとエラーになってしまいます。
次にブロックチェーンを作成します。 subnetID
genesisData
などのパラメータをご自身の値へ変えて頂く必要があります。指定するユーザはサブネットを作成した、2つのコントロールキーをを持つユーザです。返却される txID
がそのままブロックチェーンのIDになります。
ブロックチェーンを確認するとリストの最後にいま作成したブロックチェーンのIDが追加されているはずです。JSONで返ってくるのでjqコマンドあたりを使用してあげるとうまく整形できると思います。
{
"id": "dNHknFVgmxc3snHtDmvhXwanDTderFRMPYjRv5kSyNRqej4hR",
"name": "New test AVM",
"subnetID": "2bFRwRRTmvn64z7LuDq4bzLqfjTtFan8GDiMqk6eok85JG8gvK",
"vmID": "jvYyfQTxGMJLuGWa55kdP2p2zSUYsQ5Raupu4TW34ZAUBAbtq"
}
というわけでAvalancheでサブネットを作成し、AVMを新しくブロックチェーンとして追加できました。Avalancheのプラットフォーム(高スループット、分散性、早いファイナリティ)の利点を生かしつつEVMや独自のブロックチェーン実装と追加を行えるところにAvalancheの真価があるのではないでしょうか。カスタムブロックチェーン作成の動向についてはDiscordで追ってみたいと思います。
まとめ
- Avalancheはコンセンサスプロトコルの名称で、「ナカモトコンセンサス」(堅牢性、規模、分散化)と「クラシカルコンセンサス」(速度、迅速なファイナリティ、エネルギー効率)の利点を組み合わせた新たなコンセンサスメカニズムである
- Avalancheは3つのプライマリーチェーンを含むマルチチェーンフレームワークを採用しており、開発者はアプリケーションに対して最大限の柔軟性と制御を行うことが可能となる(Exchange Chain、Contract Chain、Platform Chain)
- Ethereumの開発ツールであるTruffleなどEthereumの開発資源を流用しデプロイできるためEVM互換であるBSCなどのブロックチェーンの採用やアプリの移行が多くなっている、Avalanche C-ChainもEVM互換のチェーンとなっている
- サブネットを構成するバリデータセットによって複数のブロックチェーンの検証が行われる、バリデータセットは任意に採用可能なためサブネットごとにコンプライアンスなどの要件を満たすことができる
- Go言語によるVM(Virtual Machine)の開発がサポートされている、現在追加できるVMはAVMとタイムスタンプVMの2つだけである