🌟

Astar NetworkのEVMとSubstrateの互換性について

2023/06/28に公開

この記事は株式会社Gincoのテックブログとして書いています。

この記事では、Astar NetworkのEVM (Ethereum Virtual Machine) とSubstrateとの互換性について紹介します。弊社プロダクトのGinco Enterprise WalletでもAstarを取り扱っています。

Astar Networkの概要

Astar Network(旧名Plasm Network)は、Polkadotエコシステムの一部であり、スケーラブルなマルチチェーンDApps(分散型アプリケーション)を開発・実行するためのプラットフォームです。AstarはSubstrateというブロックチェーンを作成するフレームワークを利用して構築されており、そのため、Polkadotと簡単に統合することが可能です。

また、EVMおよびWebAssembly(Wasm)の両環境をサポートしています。(公式サイト)

つまり、Astar Network上ではSolidityで書かれたスマートコントラクトの実行や、Rustなどの言語からコンパイルされたWebAssemblyで書かれたコントラクトが実行出来ます。

EVMとSubstrateの互換性について

Substrateではpalletという、言わばプラグインのようなものを入れる事により、機能を追加出来る仕様があります。

AstarではParity Technologies社が開発しているpallet-evmというpalletによりEVMとSubstrate間で資金を移動させることが出来ます。(ソースコード)

イメージとしては、Substrateの中に独立したEVMサンドボックスが存在しているような感じです。

Astar Architecture Image
アーキテクチャ図

英語ですが下記のAstar CTOの記事がとても分かりやすかったので紹介します。

https://medium.com/astar-network/using-astar-network-account-between-substrate-and-evm-656643df22a0

画像を見ると、Astarのアカウントは3種類あります。

  1. Nativeアカウント: Substrateベースのアカウント(ウォレット例: Polkadot.js)
  2. EVMデポジット: Substrateベースのアカウントから作成した受け取り用のEVMアカウント
  3. EVMアカウント: EVMベースのアカウント(ウォレット例: MetaMask)

(アカウントが3種類というと語弊がありますがここでは便宜上EVM Depositもアカウントとして扱います。)

ユースケースとしては下記の2パターンを想定して解説します。

  1. 資金をSubstrate → EVMで移動させる場合
  2. 資金をEVM → Substrateで移動させる場合

まずは、SubstrateベースのNativeアカウントとEVMベースのEVMアカウントをそれぞれPolkadot.jsとMetaMaskで作成します。

Nativeアカウントアドレス EVMアカウントアドレス
Substrateベース WSEDrP14YB15dDt8QcMqnA1KwoHwfvGpFbsFCVQxdwXTocW
EVMベース 0xC374C947C506E051EA81d3DD572862fE7F49B358

1. 資金をSubstrate → EVMで移動させる場合

まずは資金をSubstrate → EVMで移動させる場合について考えます。

NativeアカウントアドレスからEVMアカウントアドレスへ送金するには下記の手順を踏む必要があります。

  1. 受け取り側のEVMアカウントアドレスからNativeアカウントアドレスを導出する。

    Nativeアカウントアドレス EVMアカウントアドレス
    Substrateベース WSEDrP14YB15dDt8QcMqnA1KwoHwfvGpFbsFCVQxdwXTocW
    EVMベース YqPg3Y5yVnDsZmPsaFDzZp8tjvNh5gHrza6ETijUyA1nQkd 0xC374C947C506E051EA81d3DD572862fE7F49B358
  2. 導出したNativeアカウントアドレスに対し送金する。

ここで、Go言語実装を見ながらEVM → Substrateの導出方法について触れます。

// EVMAddressToSubstrateAddress
func EVMAddressToSubstrateAddress(address string) (string, error) {
 if strings.HasPrefix(address, "0x") {
  address = strings.ToLower(fmt.Sprintf("%s", address[2:])) // ① "0x"を取り除く
 }
 addressByte, err := hex.DecodeString(address) // ② byte形式にする
 if err != nil {
  return "", err
 }
 var raw []byte
 prefix := []byte("evm:") // ③ "evm:" prefixを付けaddressに連結する
 raw = append(prefix, addressByte...)
 if len(raw) != 24 {
  xerrors.Errorf("Invalid length: %d", raw)
 }
 h := blake2b.Sum256(raw) // ④ ハッシュ化する
 return EncodeAstarAddress(h[:], false), nil
}
  1. "0x"を取り除く
  2. byte形式にする
  3. "evm:" prefixを付けaddressに連結する
  4. ハッシュ化する

この4ステップでEVMアドレスからSubstrateアドレスを導出することが出来ます。

ここで注目して欲しい点としては、アドレスの導出には秘密鍵を使用していないということです。

導出したSubstrateアドレスと元のEVMアドレスの残高は共有されるので、Substrateアドレスに対し、入金が起こると即時にEVMアドレスの残高にも反映されます。

また、前項で Substrateの中に独立したEVMサンドボックスが存在していると記載しましたが、下記の仕様があります。

  • 親であるSubstrate側のExplorerでは子であるEVMの取引履歴が確認できる(※)
  • 子であるEVM側のExplorerでは親であるSubstrate側の取引履歴が確認出来ない

※ EVMの取引履歴は導出したSubstrateアドレス同士の取引履歴として記録されている

2. 資金をEVM → Substrateで移動させる場合 (こっちが複雑)

次に資金をEVM → Substrateで移動させる場合です。

EVMアカウントアドレスからNativeアカウントアドレスへ送金するには下記の手順を踏む必要があります。

  1. 受け取り側のNativeアカウントアドレスからEVMデポジットアドレスを導出する。
Nativeアカウントアドレス EVMデポジットアドレス EVMアカウントアドレス
Substrateベース WSEDrP14YB15dDt8QcMqnA1KwoHwfvGpFbsFCVQxdwXTocW 0x161069bcb00759baaca58188c84ccf5f55cd787c -
EVMベース YqPg3Y5yVnDsZmPsaFDzZp8tjvNh5gHrza6ETijUyA1nQkd 0xC374C947C506E051EA81d3DD572862fE7F49B358
  1. 導出したEVMデポジットアドレスに対し送金する。
  2. NativeアカウントアドレスからEVMデポジットアドレスの残高を引き出すメソッドを呼び出す(pallet-evmのEvm.withdrawメソッド)

再びGo言語実装を確認します。

// EVMデポジットアドレスの生成
// SubstrateAddressToEVMDepositAddress
func SubstrateAddressToEVMDepositAddress(address string) (string, error) {
 pubKey, _, err := DecodeAddress(address)
 if err != nil {
  return "", err
 }
 return fmt.Sprintf("0x%x", pubKey[0:20]), nil // ① pubkeyの前半20byteを抽出
}
  1. pubkeyの前半20byteを抽出

こちらはシンプルです。公開鍵の前半部分を抽出しているのみになります。

また、EVM → Substrateの場合と同様で秘密鍵は使用していないので出金はできません。

EVM → Substrateの場合と異なる点としては、導出したEVMデポジットアドレスと元のSubstrateアドレスは残高を共有していないという点です。

EVMデポジットアドレスに入金が発生した後、Evm.withdrawする必要があります。

なので、取引所でEvm.withdrawの対応がされていない場合、外部のEVMウォレットから取引所のNativeアカウントアドレスに入庫すると残高が引き出せない可能性があります。

Evm.withdrawの対応がされているかの確認をするか、EVMアカウントはEVMアカウントに入庫するようにしましょう。

まとめ

今回は、Astar NetworkのEVMとSubstrateの互換性について紹介しました。

Astar NetworkではEVMとSubstrateを利用出来るので便利な反面、きちんと仕様を理解をしないと、残高が引き出せないことがあります。当記事で少しでも理解の助けになれたら幸いです。

株式会社 Ginco ではブロックチェーンを学びたい方、ウォレットについて詳しくなりたい方を募集していますので下記リンクから是非ご応募ください。

株式会社Ginco の求人一覧

参考文献

https://github.com/paritytech/frontier

https://medium.com/astar-network/using-astar-network-account-between-substrate-and-evm-656643df22a0

https://docs.astar.network/

Discussion