【完全保存版】AstarのXVM(Cross-Virtual Machine)について
当記事は、こちらの記事を翻訳・編集したものです。
0 はじめに
2022年、多くのことが起こりました。
Web3業界全体が、技術的な成果、現実的な問題の解決、今までに見たことのない産業の温床となるなど、新たな境地を切り開きました。
もちろん、業界が学び、改善すべき事件や出来事もたくさんありました。
2022年は、Web3の世界では「大盛況のうちに幕を閉じた」と言っても過言ではないでしょう。
しかし、テクノロジーは成長するものであり、このような出来事を経験することは、何がうまくいき、何がうまくいかないかを知ることにつながります。
Astar Foundationでは、今起きている外部からの影響に関係なく、未来の基盤を作るために努力してきました。
そして今日、Astar Visionを達成するための最も重要な機能の1つ、クロス仮想マシン(XVM)を紹介できることを誇りに思います。
この記事では、Web3におけるスマートコントラクトの役割、dApp開発を進める上で見えている問題点、XVMを作った理由、XVMの仕組み、そして最後に、未来が提示するものについて説明します。
1 WASM仮想マシンについて
1 WASMとは
WebAssembly(WASM)は、WebAssembly仮想マシンがWASMバイトコードを解釈するために読むことができるメッセージフォーマットです。
厳密に言えば、WASMは、仮想環境でシステムと通信するために上位言語からコンパイルされるメッセージフォーマットを指します。
しかし簡略化のため、この記事でWASMと言う場合は、バイナリとしてのWASMとブロックチェーン内の仮想マシンの両方を指すことにします。
WASMはもともと、システムレベル言語からコンパイルされたバイナリをブラウザに使用し、ウェブアプリケーションにネイティブに近いパフォーマンスを生み出すために使われていました。
しかし、WASMの移植性のおかげで、これはブラウザ以外でも実行できます。
2 スタックベースのVM
WASMのVMはEthereum Virtual Machine(EVM)のようなスタックベースのVMであるため、WASMのバイナリにコンパイルされている限り、スマートコントラクトの実行環境を作成することが可能です。
3 型安全性と適切なエラー処理
EVMとは異なり、これはWASMを通じて、Rust、Go、C++など、WASMをターゲットにできる言語で書かれたスマートコントラクトを実行するブロックチェーンを作成できることを意味します。
これらはすべて型安全性と適切なエラー処理をサポートしています。
4 非同期性
さらに、WASMネイティブにコンパイルできる主要な言語のほとんどが、その構文で非同期関数をサポートしているため、WASMスマートコントラクトに非同期性を導入することが可能です。
5 相互運用性
相互運用性については、これは、応答が何であるかを知らずにやみくもにメッセージを送信する代わりに、スマートコントラクト内でクロスチェーン関数を扱えるようになったことを意味します。
EVMとSolidityがこの部門で欠けていることを考えると、これはDeFi以外で業界標準のクロスチェーンネイティブアプリケーションを作成する上で大きな意味を持ちます。
このため、WASMのような、非同期性をサポートする新しい技術が導入されると、それはDeFi以外の業界でのクロスチェーンネイティブアプリケーションの作成、そしてブロックチェーン技術全体のさらなる発展に大きな影響を及ぼす可能性があります。
6 スマートコントラクトの未来
これら多くの要因から、WASMはスマートコントラクトの未来です。
しかし、EVMとの互換性の問題があるため、ブロックチェーン技術の大量導入は困難になりつつあります。
2 XVMの動機
1 WASMベースのスマート・コントラクトの現状
技術的に言えば、WASMベースのスマート・コントラクトが進むべき道であることは誰もが知っています。
しかし、EVMが支配する世界でWASMスマートコントラクトを採用する場合、大きな課題があります。
ほとんどのチームは、リッチなEVMエコシステムに慣れすぎています。
ほとんどのWASM VMエコシステムは小規模で、あまりにも異質であるため、多くの既存プロジェクトはWASMスマートコントラクトをゼロから学ぶメリットを見いだせず、EVMエコシステムへのアクセスを犠牲にしています。
2 AstarにとってのXVM
私たちは、まさにこの問題を解決するためにXVMを作りました。
私たちをPlasmの頃から知っている人は、私たちが常に非常にWASMスマートコントラクトにフォーカスしたネットワークだったことを思い出すかもしれません。
しかし、Astarを立ち上げたとき、コントラクトパレットの代わりにEVMで立ち上げました。
これはエコシステムを立ち上げ、より幅広くプラットフォームを提供するためでした。
しかし、我々は常にWASMスマートコントラクトをより広範なエコシステムに組み込むことを計画していました。
3 XVMの概要
XVMのアイデアはそこから始まりました。
XVMはカスタムパレットとインターフェースのセットで、ある仮想マシンのスマートコントラクトが別の仮想マシンとあたかも同じ環境にあるかのように通信できるようにするものです。
言い換えれば、XVMを使えば、ink!スマートコントラクトを作成し、EVM側で利用可能なあらゆるアセットやコントラクトにアクセスできます。
4 XVMと別のレイヤー0との接続
さらに、AstarのEVMがAxelarやCelerのような別のレイヤー0に接続されている場合、AxelarやCelerに接続されているすべてのEVMチェーンにアクセスできるinkスマートコントラクトを作成できます!
XVMは、ビルダーが大規模なEVMエコシステムと相互作用しないという犠牲を払うことなく、革新的なdAppsを開発することを奨励することを願っています。
3 XVMのメカニズム
では、XVMはどのように機能するのでしょうか?
実際の仕組みは非常にシンプルで、エンコードされた呼び出しを配列として受け取り(SCALEコーデックにインスパイアされています)、XVMパレットへの引数として渡します。
4 アーキテクチャ
以下は、XVMの背後にあるアーキテクチャと、他のVMとの接続方法です
1 XVMモジュールの公開について
各スマートコントラクトVMは、他の環境のスマートコントラクトが使用できるように、XVMモジュールを公開する方法を持ちます。
2 各VMの関数について
XVMパレット関数を公開する各VMの関数を作成します。
例えば、コントラクト・パレットにはチェーン拡張機能(Chain Extension)があり、EVM側にはコンパイル済みのコントラクト(Precompiled Contract)があります。
3 エンコード済みの呼び出しについて
一方のVMにデプロイされたスマートコントラクトは、チェーン拡張機能またはプリコンパイルされたコントラクトにエンコードされた呼び出しを送信することで、もう一方のVMとやり取りすることができます。
4 アダプターについて
XVM関数が呼び出されると、パレットはターゲットVMのアダプターを呼び出し、関数コールをターゲットのスマート・コントラクトに渡します。
ブロックチェーンの観点からは、このトランザクションの行は単一のブロックの一部となり、完全にトランザクション的なものとなリマす。
これがXVM呼び出しの方法です。
5 XVMの使用
1 概要
XVMコールがその中核でどのように機能するかが分かったところで、スマート・コントラクト開発者の観点からどのように機能するかについて説明しましょう。
最初のユースケースは、インク開発者がEVM空間のアセットにアクセスすることなので、このセクションでは主にink!コントラクトからXVMを使用することに焦点を当てます。
しかし、同じ原則がEVM上のSolidityコントラクトにも適用されることに注意してください。
2 XVMコールに必要なもの
SolidityコントラクトにXVMコールを行うために必要なのは、スマートコントラクトのH160 EVMアドレス、関数セレクタ、関数に渡すエンコードされた引数だけです。
3 全コードについて
話はもう十分なので、実際のコードを見てみましょう。
//! ERC721 EVM contract interoperability using XVM interface.
#![cfg_attr(not(feature = "std"), no_std)]
pub use self::erc721::{
Erc721,
Erc721Ref,
};
use ink_lang as ink;
/// EVM ID (from astar runtime)
const EVM_ID: u8 = 0x0F;
/// The EVM ERC721 delegation contract.
#[ink::contract(env = xvm_environment::XvmDefaultEnvironment)]
mod erc721 {
const APPROVE_SELECTOR: [u8; 4] = hex!["095ea7b3"];
const TRANSFER_FROM_SELECTOR: [u8; 4] = hex!["23b872dd"];
const MINT_SELECTOR: [u8; 4] = hex!["40c10f19"];
use ethabi::{
ethereum_types::{
H160,
U256,
},
Token,
};
use hex_literal::hex;
use ink_prelude::vec::Vec;
#[ink(storage)]
pub struct Erc721 {
evm_address: [u8; 20],
}
impl Erc721 {
/// Create new ERC721 abstraction from given contract address.
#[ink(constructor)]
pub fn new(evm_address: [u8; 20]) -> Self {
Self { evm_address }
}
#[ink(message)]
pub fn transfer_from(&mut self, from: [u8; 20], to: [u8; 20], token_id: u128) -> bool {
let encoded_input = Self::transfer_from_encode(from.into(), to.into(), token_id.into());
self.env()
.extension()
.xvm_call(
super::EVM_ID,
Vec::from(self.evm_address.as_ref()),
encoded_input,
)
.is_ok()
}
#[ink(message)]
pub fn approve(&mut self, to: [u8; 20], token_id: u128) -> bool {
let encoded_input = Self::approve_encode(to.into(), token_id.into());
self.env()
.extension()
.xvm_call(
super::EVM_ID,
Vec::from(self.evm_address.as_ref()),
encoded_input,
)
.is_ok()
}
#[ink(message)]
pub fn mint(&mut self, to: [u8; 20], token_id: u128) -> bool {
let encoded_input = Self::mint_encode(to.into(), token_id.into());
self.env()
.extension()
.xvm_call(
super::EVM_ID,
Vec::from(self.evm_address.as_ref()),
encoded_input,
)
.is_ok()
}
fn transfer_from_encode(from: H160, to: H160, token_id: U256) -> Vec<u8> {
let mut encoded = TRANSFER_FROM_SELECTOR.to_vec();
let input = [
Token::Address(from),
Token::Address(to),
Token::Uint(token_id),
];
encoded.extend(ðabi::encode(&input));
encoded
}
fn approve_encode(to: H160, token_id: U256) -> Vec<u8> {
let mut encoded = APPROVE_SELECTOR.to_vec();
let input = [Token::Address(to), Token::Uint(token_id)];
encoded.extend(ðabi::encode(&input));
encoded
}
fn mint_encode(to: H160, token_id: U256) -> Vec<u8> {
let mut encoded = MINT_SELECTOR.to_vec();
let input = [Token::Address(to), Token::Uint(token_id)];
encoded.extend(ðabi::encode(&input));
encoded
}
}
}
これは、XVMを使用してEVM環境でERC721 Solidityコントラクトを制御できるink!スマートコントラクトです。
これは、XVM SDKコントラクトリポジトリから直接取り出したものです。
コントラクト自体は大したものではないことがわかりますが、少し解剖してみましょう。
4 VM_IDについて
EVM_IDはVMのIDを指し、XVMがこのコントラクトがどのVMをターゲットにするかを理解するために必要です。
これはIDなので、XVMを拡張していくつものスマート・コントラクトVMをサポートし、相互に通信できるようにすることができます。
5 XVMのデフォルト環境について
6 関数セレクタの定義について
スニペットの後半では、このコントラクトが使用する関数セレクタを定数として定義しています。
7 EVMアドレスについて
コードの次の部分では、メッセージを送信するH160アドレス([u8; 20]は20バイト長の配列を意味し、160ビットであることに注意)を定義します。
8 コンストラクタについて
この例では、コンストラクタとしてデプロイ時にユーザーにアドレスを定義させていますが、有効なEVMアドレスである限り、この動作は完全にカスタマイズ可能です。
9 コントラクト関数について
次のセクションでは、クライアントが相互作用する呼び出し可能なパブリックなコントラクト関数を宣言します。
こちらの「transfer_from」関数を見てみましょう。
まず、「from」「to」「token_id」の3つの引数を取り、「bool」(trueかfalse)を返すということがわかります。
次に、こちらの「transfer_from_encode」関数で符号化(エンコード)してそうです。(後で見てみましょう。)
into関数では型推論で別の型に変換し、所有権を移動させています。
(細かい部分は省略します。ご不明の場合は「型を変えている」のニュアンスで良いと思います。)
10 エンコード用関数について
では、「transfer_from_encode」関数を見てみましょう。
「TRANSFER_FROM_SELECTOR」というバイト配列をベクター型に変換しています。
これによって、新たな要素を追加できるようになりました。
こちらは、Rustのenum型であるTokenのバリアント(具体的な形を持つenumの値)Addressを使用して、fromという値などをラップしています。
このTokenというenumは、Ethereumの関数呼び出しに使用される各種のパラメータタイプを表現するためのものです。
例えば、AddressバリアントはEthereumのアドレスを表現し、UintバリアントはEthereumのuint型を表現します。
次に、こちらを見てみましょう。
「ethabi」ライブラリを用いています。
まずは、各値をバイト配列に変換します。
アドレスは20バイトです。
そして、32バイトになるように、0で埋めています。
なお、この2つの処理は同時に行われますが、わかりやすさのために、分けて書いています。
これを「extend」でくっつけています。
11 XVM Callについて
ここで、自身の実行環境の拡張機能である、「xvm_call」を使用しています。
これにより、EVMの関数を呼び出します。
そして、具体的に、次の引数を渡しています。
このようにして、XVM Callが行われています。
6 今すぐ試す
XVMは現在、私たちのパブリック・テストネット「shibuya」で公開されています!
この最新機能をすぐに試すことができます。
また、XVMを使いたい開発者が開始できるように、いくつかのリポジトリを用意しました。
7 ink! XVM SDK
前のセクションをご覧になったかもしれませんが、スマート・コントラクトからXVMを使うのは簡単です。
しかし、開発プロセスをさらに簡単にするために、EVMやWASM VMの世界で一般的に使用されるインターフェースのためのXVM SDKを用意しました。
ぜひInk!XVM SDKリポジトリをチェックして、ERC20やERC721などを制御できるインク!コントラクトを作成してください。
コミュニティからの支援により、SDKを拡張してより多くのインターフェースをサポートし、SolidityとAsk!のSDKを作成し、XVMを活用できるサンプルdAppを作成できます。
8 Sub0 XVMワークショップ dApp
フルスタックのdAppで動くXVMについてもっと知りたいのであれば、Sub0 XVM Workshopリポジトリを見てください。
これは、Sub0で初めてXVMの機能を一般公開するために使用したプロジェクトです。
このシンプルなdAppは、EVMとSubstrateの両方のネイティブの署名者からERC20トークンを制御する方法を示しています。
XVMに関するAstar Tech Talkもご覧ください。
9 アプリケーション
1 ユニバーサルなアセットコントローラーについて
XVMのシンプルさにもかかわらず、EVMからWASM VMへの流動性の橋渡し以上の多くの潜在的なアプリケーションを作成できます。
XVMを使用すると、異なるアカウントスキームから異なる環境に存在する資産の所有権を証明することができます(例:Polkadot-jsウォレットを使用するだけで、EVM ERC20トークンの所有権移行)
つまり、すべてのアセットを管理するために環境ごとに新しいウォレットを作成する必要はありません。
つまり、単一の署名者でユニバーサルなアセットコントローラーを作成できるのです。
2 NFTマーケットプレイスでの応用例
例えば、多くのNFTマーケットプレイスでは現在、MetaMaskのようなEVM署名者のみが利用可能です。(なお例外はKusamaのSingularです。)
そのため、Polkadot-jsを使用したERC721 NFTやMetaMaskを使用したRMRK NFTの取引やオークションはできません。
XVMを使えば、2人の署名者がEVMとWASM VMの両方であらゆるNFT規格の所有権を扱い、移転できるようにすることで、この問題を解決できます。
これにより、UXの機会が広がります。
言い換えれば、ユーザーはお気に入りのウォレットインターフェースを離れることなく、複数のマーケットプレイスで様々なタイプのNFTを検討することができます。
3 クロスチェーンでの応用例
その他のアプリケーションとしては、XVMと同じエンコーディング方式を採用したクロスチェーンのdAppsがあります。
Astarネットワークを通じて、XCMPのようなセキュアなクロスコンセンサスメッセージパッシングプロトコルがPolkadot上にあれば、SolanaやNearのような完全に異質な環境でスマートコントラクトと対話することができます。
XVMに関して言えば、空は無限であり、私たちはこれによって、将来のスマートコントラクトが、どの言語で書かれ、どの環境/RPCを使用しているかに関係なく、シームレスに動作することを願っています。
10 将来
1 XVM v3について
現在、XVMはv2であり、我々はv3の作成に励んでいます。
v2の制限の一つは、XVMストレージのクエリーとエラー・メッセージがないことです。
スマート・コントラクトとやり取りするとき、開発者はアプリケーション・ロジックの一部として、アカウントが保持しているERC20トークンの量のような特定の値をクエリすることを期待しています。
v3では、スマート・コントラクトが別の環境からスマート・コントラクトのストレージ値を読み取れるようにします。
エラーメッセージと同様に、開発者はトランザクションが成功したかどうかしかわかりません。
しかし、エラーメッセージを改善することで、プロジェクトがdAppのコーナーケースを適切に処理できるようになります。
2 XCMPとの融合について
XVMの将来的には、これをXCMPと統合し、Astar上のスマートコントラクトが、どのVMを使用しているかに関係なく、他のパラチェーン上のスマートコントラクトを呼び出せるようにしたい。
これにより、開発者は真にクロスチェーンなネイティブdAppを作成できるようになり、スマートコントラクトの機能をこれまでできなかったようなものまで拡張できるようになります。
3 新しいVMについて
最後に、EVMとコントラクト・パレットだけではマルチVMチェーンとは呼べません。
将来的には、スマート・コントラクトの非同期性をネイティブに処理し、クロスチェーンの呼び出しを非同期関数として抽象化できる別のVMを追加する予定です。
このVMはXVMと互換性があり、Astar Network上のすべてのdAppが、ユーザーに別のチェーンで別のアカウントを作成させたり、別のdAppをデプロイさせたりすることなく、クロスチェーン機能の機能を完全に利用できるようになります。
11 最後に
XVMを使用することで、EVMが支配する従来のブロックチェーンエコシステムを融合する際に発生する問題を排除し、EVMが提供する広大なエコシステムへのアクセスを犠牲にすることなく、新しいパラダイムのdAppプロジェクトがエコシステムに参入できるようになることがお分かりいただけたと思います。
WASMスマートコントラクトによって、プロジェクトがシンプルな非同期関数で他のブロックチェーンにアクセスして使用できるようになります。
そして、プロジェクトがスマートコントラクトを開発する際にSolidityに欠けている型安全性を恐れる必要がなくなり、WASMの拡張言語機能によって人材のプールとプロジェクトの多様性が向上する未来が見えます。
また、XVMを通じて、プロジェクトはWASMで構築することで何が失われるかを心配することなく、エンドユーザーに価値をもたらすものの構築に集中することができます。
Astar Networkは、あなたのイノベーションが始まる場所です。
12 Astarについて
Astar Network はマルチチェーンのためのスマートコントラクトの未来です。
Astar Networkは、EVMとWASMスマートコントラクトによるdAppsの構築をサポートし、クロスコンセンサスメッセージング(XCM)による真の相互運用性を開発者に提供します。
Astar独自のBuild2Earnモデルは、開発者が自分のコードと構築したdAppに対して、dAppステーキングメカニズムを通じて報酬を得ることを可能にします。
Astarの活気あるエコシステムは、世界的にPolkadotの主要なParachainとなり、すべての主要取引所とTier 1 VCによってサポートされています。
Astarは、開発者がdAppsの構築を開始するために、すべてのイーサリアムとWASMツールの柔軟性を提供します。
PolkadotとKusama Networks上での成長を加速させるために、Astar SpaceLabsはトップTVL dAppsのためのインキュベーションハブを提供しています。
サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊