見出し画像

【完全保存版】Astar におけるSubstrateとEVMのアカウントの関係について

当記事は、こちらの記事翻訳・編集したものです。

0 はじめに

本日は、Substrate内で使用できる様々な種類のアカウントと、Substrate内でEVMを使用する方法をご紹介します。

Substrateの概念は非常に拡張性があり複雑です。

そのため、Substrate内の異なるレイヤー(ネイティブブロックチェーンレイヤーやEVMレイヤーなど)の鍵を管理するユーザーとして焦点を絞ります。

TL;DR:(要約)

  • Substrate複数の署名者タイプをサポートしています。

  • Substrate内でEVMを使用するためにEVMパレットを追加できます。

  • SubstrateのネイティブアカウントSS58形式ですが、EVMアカウントH160形式です。

  • SubstrateはEVMの状態にアクセスできますが、EVMはSubstrateの状態にアクセスできません。

  • SS58アカウントH160にマッピングすることで、2つのアカウント間を移行することができます。

1 SubstrateとSS58

Substrateレイヤー1ブロックチェーンフレームワークで、カスタム機能を持つ様々なブロックチェーンを作成するために使用されます。

フレームワークとは、再利用可能なソフトウェア部品設計パターンを組み合わせて、特定の問題解決を効率的に行うためのツール箱のようなものです。

https://web3-technology-stack.readthedocs.io/en/latest/layer_1/protocols/substrate/

デフォルトでは、Substrateブロックチェーンはトランザクションの送受信SS58アドレスフォーマットを使用します。

SS58BitcoinBase-58-checkに若干の変更を加えたものです。

https://ismailakkila.medium.com/my-notes-on-bitcoin-addresses-f9689fd3057f

Payloadは一般的にデータ通信やデータパケットにおいて、実際の役に立つデータやメッセージを指します。

特に、このフォーマットには、アドレス特定のネットワークに属していることを識別するアドレスタイプのプレフィックスが含まれています。

SS58アドレスの例aLoNHLwqd75cniRoF2k2DrXgsbUWacuCxqc6d6BBmvG3NVQ

2 EVMとH160

EVMはイーサリアム内のトランザクションで任意のコード実行を可能にする仮想マシンである。

https://ethereum.org/ja/developers/docs/evm/

EVMはイーサリアムから始まりましたが、現代のブロックチェーンでは、EVMはむしろブロックチェーンが「イーサリアム互換」であることを可能にしています。

「EVM」は他のブロックチェーン内で広大なイーサリアムのエコシステムを共有するための標準です。

翻訳者 注
元々はEVMイーサリアムの機能を実現するためにイーサリアムいうブロックチェーンから生まれましたが、現在では、さまざまなブロックチェーンがイーサリアムのエコシステムを共有するための標準となっています。

SubstrateにはFrontier framework と呼ばれるパレットがあり、Substrateネイティブ環境とともにイーサリアム互換性アカウントを追加しています。

イーサリアム160ビット16進文字列パブリックアドレスとして使用しており、ユーザーはこのアドレスでトランザクションを送受信することができる。

Substrateでは、この形式を160ビットハッシュを意味するH160と呼んでいます。

ブロックチェーンがイーサリアムと互換性を持つためには、H160アカウントを使用する必要があります。

これはEVMとイーサリアムエコシステム内のすべてのツールが認識できる唯一のアカウント形式だからです。

このルールはEVMパレットを使用したサブストレートチェーンにも適用されます。

H160アドレスの例
0x4C40D74739A7C95D8358191D68E6d5C77a867E12

1 アカウント

1 Substrate 公開鍵の種類


Substrate3種類のアカウント(ソース)をネイティブにサポートしています。

  • ECDSAsecp256k1曲線を使った署名スキーム。これはBitcoinEthereumのセキュリティに使われている暗号アルゴリズムと同じ。

  • Ed25519:Ed25519は、Curve25519を使用したEdDSA署名スキームです。セキュリティを損なうことなく超高速を実現するために、設計と実装のいくつかのレベルで慎重に設計されている。

  • SR25519: SR25519はEd25519と同じ曲線に基づいている。しかし、EdDSAスキームの代わりにSchnorr署名を使用しています。SR25519は公開鍵を公開しません。

ユーザーは、Polkadot-jsウォレット同じフレームワークに基づくウォレットから、これらの鍵のいずれかを使ってトランザクションに署名したり、外部コールを呼び出したりできます。

一般的に、SR25519スキームは、Auraを使用してブロックを生成できる鍵を生成するために使用されます。

Auraオーソリティ(認証されたバリデーター)が順番にブロックを生成するラウンドロビン方式コンセンサスアルゴリズムです。
各バリデーターは自分の番が来るとブロックを生成し、そのブロックをネットワークにブロードキャストします。
ブロックはそれぞれのバリデーターによって検証され、合意が得られたらブロックチェーンに追加されます。

chatGPT-4

SR25519と同じシードフレーズを持つEd25519スキームは、Grandpa を使ってブロックを確定するための鍵を生成するのに使われます。

"GRANDPA"は、"GHOST-based Recursive Ancestor Deriving Prefix Agreement"の略語で、Substrateブロックチェーンフレームワークに組み込まれたブロックのファイナライズ(確定)アルゴリズムの一つです。

chatGPT-4

ECDSAは、2019年にGavin Woodによって初めてSubstrateに追加された、Substrateトランザクションに署名できる鍵の代替スキームです。

翻訳者注
他の鍵署名方式(前述のEd25519やSR25519)とは異なる、代替的な署名方式であることを指しています。

ECDSAスキームは、BitcoinEthereumで使用されるアカウントの公開鍵の互換性を追加するために使用されます。

Substrateは複数の暗号アルゴリズムに対応していますが、ユーザーがトランザクションを受け取ったり行ったりする際には、3つとも全く同じ挙動を示すため、アルゴリズムは全く問題になりません。

翻訳者注
暗号アルゴリズムは、ブロックの生成と確定のためのKeyを生成する際に使われるからだと思いました。
認識が違っていましたら、後から修正します。

例えば、「chimney manage ritual space armed kick angle cram indoor valid pipe margin」 というシードフレーズを考えてみましょう。

このフレーズを使用すると、以下のようなアカウントになります。

SR25519: XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK
Ed25519: bBfbreU46m2NMLcvDsPMUVkfRNZm7fcXbJ4drZXParAYaY
ECDSA: Y7hpF7NCiSbG15xvVHj4ktntqFCgBurutKaCBPnhVUV5ecn

1つのシードフレーズで3つの異なるパブリックアドレスを作成し、暗号スキームを変更することで、ユーザーはこれら3つのアカウントすべてを制御することができます。

2 イーサリアム鍵

イーサリアムは、すべてのイーサリアム互換ネットワークを通じて同じであるECDSA署名スキームのみをサポートしています。

Substrate ECDSAEthereum ECDSAの大きな違いは、生成されるアドレス形式です。

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

プロセスを簡略化すると、SubstrateEthereum ECDSAの両アカウントは公開鍵を共有しますが、最終的なハッシュアルゴリズムは異なるため、異なる結果が得られます。

SubstrateアカウントはBlake2でハッシュ化された公開鍵をSS58にエンコードします。

一方、Ethereumアドレスは異なるハッシュ化アルゴリズムを使用します。

これは非常に一般的な説明であるため、いくつかの技術的な詳細は無視されていることに注意してください。

エンドユーザーにとって、Substrate取引Ethereum取引署名に使用するアカウントの違いは、使用するウォレットの種類によって異なります。

例えば、MetaMaskで署名するユーザーはイーサリアム互換のネットワークトランザクションにのみ署名でき、Polkadot-jsウォレットを使用するユーザーはSubstrateベースのトランザクションにのみ署名できます。

2 Substrate上のEVM

1 アーキテクチャ

EVMパレットを実装するSubstrateブロックチェーンアーキテクチャは一見複雑に見えるかもしれません。

しかし、EVM独自のアカウント残高を持つ独立したサンドボックスであり、ホストであるSubstrateブロックチェーンブロック状態を共有するだけであることを理解すれば、分離して理解することがはるかに容易になります。

全体的なアーキテクチャは上図のように表現できます。
注意すべき重要な点がいくつかあります。

① EVM環境はSubstrateの上で動作します。

つまり、EVMサンドボックスブロック高はホストSubstrateネットワークに依存します。

ホストSubstrateネットワークEVMの状態にアクセスできます

一方、EVMサンドボックス通常の手段でホストSubstrateネットワークの状態にアクセスしたり、状態を変更したりすることはできません。

EVMからのSubstrate状態遷移は、EVMのプリコンパイルされたカスタムコントラクトによってのみ実現できます。

② EVM環境は独自のRPCエンドポイントを公開します。

このエンドポイントはFrontier RPCクライアントを実装することで公開することができ、EIP-1474と互換性があります。

EIP-1474は、EIPの一つで、EthereumのJSON-RPC仕様を定義したものです。
JSON-RPCリモートプロシージャコール(RPC)の一つで、データ形式にJSONを利用し、HTTPなどを通じてデータを送受信します。これにより、ネットワークを介して機能を呼び出すことが可能になります。

chatGPT-4

MetaMaskを使用してネットワークに接続し、他のイーサリアム互換チェーンと同様にトークンを表示または送信することができます。

③ EVM環境はEVMデポジットを持ちます。

EVM環境にはEVMデポジットと呼ばれる独自の残高があり、Substrateネイティブアカウントから引き出すことができます。

SubstrateネイティブSS58アドレスは、EVMデポジットにマッピングされたH160アドレスに変換でき、EVM H160アドレスSS58アドレスに変換できる。

これにより、アカウントネイティブ残高からEVM残高へトークンを転送することができます。

しかし、これは非可逆的な変換であるため、SS58H160に変換して同じSS58アドレスに戻すことはできません。

翻訳者注
変換自体は可能ですが、一部の情報(この場合はアドレスの一部)が変換プロセス中に失われているためです。

さらに、アカウントが作成された環境内でのみトランザクションに署名することができます。

例えば、通常の方法では、ネイティブ・アカウントでEVMトランザクションに署名することはできませんし、その逆もできません。

④ まとめ

EVMネイティブSubstrateの残高間のアドレス変換とトランザクションを無視すれば、EVMを備えたSubstrateの全体的なアーキテクチャは、単一のノードで動作する2つの別々のブロックチェーンを持っていると見なすことができます。

ユーザーは、Substrateに触れたり理解したりすることなくMetaMaskEVMを使用したり、EVMにまったく触れることなくPolkadot-jsウォレットSubstrateを使用したりすることができます。

2 EVMレイヤーの視点

EVMパレットSubstrate上で機能することを説明するために、次の例を考えてみましょう。

https://astar.subscan.io/block/539982

Astarメインネットブロック539982では、6つの外部呼び出し(Extrinsic call)がありました。

3つのイントリンシックコール(ブロックチェーンによって実行されたコール)を除くと、2つのSubstrate残高移動1つのイーサリアム取引があります。

https://astar.subscan.io/block/539982

EVMエクスプローラーで同じブロック番号を見ると、トランザクションが1つしかないことがわかります。

Substrate RPCでは、ネイティブトランザクションEVMサンドボックス内のトランザクションを表示できます。

一方、EVM RPCでチェーンにアクセスすると、EVMパレット内で発生したトランザクションしか表示できません。

Ethereumの外部呼び出しは、呼び出し元H160アドレスターゲットH160アドレスEVMトランザクションハッシュ(Substrateトランザクションハッシュとは異なる)を含むethereum.Executedイベントを発行します。

EVMコールSubstrateトランザクションハッシュを持たないことに注意。)

このイベントは、サブストレートネットワークEVMサンドボックス内の状態遷移を受動的に読み取るためのフォーマットです。

EVM RPCからトランザクションハッシュを見ると、詳細なトランザクションが返されます。

https://blockscout.com/astar/tx/0x49d6f414f196442dfcd726cb2c5c61f9861d81e9074ca2e5a21ecf62c1b3aa9f/token-transfers

EVM RPCはトランザクションの詳細データを返しますが、fromtoのアドレスはSubstrateブロックイベントのものと同じであることがわかります。

https://astar.subscan.io/extrinsic/539982-5?event=539982-34

これはブリッジ取引で、ユーザーは別のブロックチェーンから610 WASTRトークンスワップしています。

ブロック・イベントを見ると、トークンのミントとトークンのバーンが行われていることがわかります。

https://blockscout.com/astar/tx/0x49d6f414f196442dfcd726cb2c5c61f9861d81e9074ca2e5a21ecf62c1b3aa9f/token-transfers
https://blockscout.com/astar/tx/0x49d6f414f196442dfcd726cb2c5c61f9861d81e9074ca2e5a21ecf62c1b3aa9f

しかし、Substrate内でこのアカウントの状態遷移を調べると、興味深いことが起こります。

イーサリアムの取引イベントを詳細に見ると、トークンのミントバーン金額は正しいことは確認できる。

https://astar.subscan.io/extrinsic/539982-5

しかし、興味深いのはアカウントです。

EVM RPCH160アドレスを返しますが、Substrate RPCEVMサンドボックス内のすべてのアカウントに対してSS58アドレスを返します。

これは、Substrateではデフォルトのアドレス形式常にSS58だからです。

では、Substrateどのようにアドレス形式を変換し、どのように残高を処理するのでしょうか?

3 EVMへの入金とアドレス変換


polkadot-js/util-cryptoパッケージは関数evmToAddressをエクスポートします。

この関数はH160アドレスを受け取り、その前にevm:を付け、文字列をバイト配列に変換し、バイトをBlake2でハッシュし、公開鍵をSS58にエンコードします。

提供されたH160アドレス有効なEVM署名者のものである場合(アカウントがMetaMaskのようなウォレットから作成された場合)、SS58アドレスマッピングされます。

SS58アカウントからこのマッピングされたSS58アドレスにトークンを送信すると、元のH160アカウントEVMサンドボックス内の資金にアクセスできるようになります。

同じパッケージのaddressToEvm関数を使用して、SS58アドレスH160アドレスに変換することも可能です。

SubstrateはまずSS58文字列デコードしてハッシュ化された公開鍵(180ビットのハッシュ、つまりH180)を取得し、末尾の20ビットを削除して160ビットのハッシュになるようにアドレスを変換します。

提供されたSS58アドレス有効なサブストレート署名者のものである場合、結果の文字列は マップされたH160アドレスとなります。

EVM署名者がこのアドレスにトークンを送付すると、トークンは元のSS58アカウントEVMデポジットに保管されます。

このアカウントは、evm.withdraw外部呼び出しによってトークンを取り戻すことができます。

EVMパレットH160アカウントSS58アカウントハッシュマップを保持しており、SubstrateはマッピングされたH160アドレスとマッピングされたSS58アドレスを関連付けることができます。

また、アドレス変換は非可逆処理であり、変換処理を元に戻すことはできないことにお気づきかもしれません。

一度SS58アドレスH160アドレスに変換すると、それを元に戻すことはできません。

そのため、アドレスを有効なマップ済みアドレスに変換する際には、元の署名者に注意する必要があります。

翻訳者注
非可逆のため、元のアドレスに復元できなくなるためです。

Substrateの署名者はSS58アドレスからH160アドレスに変換でき、EVM署名者SS58アドレスに変換できます。

他の方法では、有効なマッピングされたアドレスは作成されません。

さて、外部呼び出しの539982-5とEVMトランザクションハッシュの話に戻ります。

https://astar.subscan.io/extrinsic/539982-5

SubstrateのRPCから表示されたSS58アドレスはどこから来たのでしょう?

EVMトランザクションは、アドレス「0x3c..e0」が610 ASTRトークンをアドレス「0x7c..bc」に送信したことを示しています。

https://astar.subscan.io/extrinsic/539982-5

しかし、Substrateイベントは、アドレス「Z3..7i」が610 ASTRトークンをアドレス「bV..BK」に送信したことを示しています。

ひとつ確かなことは、EVM RPCのH160アドレスの両方がオリジナルの署名者であるということです。

これは、EVMトランザクションに署名できたからです。

マップされたH160アドレスは、元の署名者がサブストレートアカウントであるため、EVMトランザクションに署名できません。

そこで、アドレスSS58に変換してみましょう。

擬似コードを使用すると、変換プロセスを以下のように表現できます(オンラインツールを使用して、自分でアドレスを変換することもできます。)

let astarAddressPrefix = 5
let step1 = toByteArray(["evm:", "0x3c0561dd616cb7cc25ef728869f93c01b6225ee0"])
let step2 = blake2Hash(step1)
let step3 = ss58Encode(step2, astarAddressPrefix)
let mappedSs58Address = step3mappedSs58Address == "Z3oCmw6ndSgoWvFUU1vsvC7KK1hQNBRUKQXjJs9iLY7Pp7i"

「Z3..7i」は、「0x3c..e0」アドレスがマッピングされていることがわかります。(これは、「bV..BK」と「0x7c..bc」も同様にわかります。)

これは前節で示したアドレスと一致します。

では、SS58からH160への変換はどうでしょう。

SS58のアカウントXdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkKをマッピングされたH160アドレスに変換したいとします。

このプロセスは次のように表現できます。

let step1 = ss58Decode(XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK)
let mappedH160Address = dropTrailingBytes(step1, 20)mappedH160Address == "0x4aa7df162dc5543a3c1a5e216d16d260f9ead5ed"

また、Substrate keyユーティリティを使えば、SS58アドレスのデコードされた公開鍵を見ることもできます。

hoonkim@Hoons-MacBook-Pro Astar % ./target/release/astar-collator key inspect XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK
Public Key URI `XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK` is account:
Network ID/version: astar
Public key (hex): 0x4aa7df162dc5543a3c1a5e216d16d260f9ead5ed6204baeceb461cd568a7cf56
Account ID: 0x4aa7df162dc5543a3c1a5e216d16d260f9ead5ed6204baeceb461cd568a7cf56
Public key (SS58): XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK
SS58 Address: XdBhqfbg5Jsqp5YgNJVNLzMMBrzGsmBkZypS5Z7nr214fkK

「Xd…kK」の公開鍵は「0x4a..ed6204baeceb461cd568a7cf56」です。

一方、マップされたH160アドレスは「0x4a..ed」です。

マップされたH160を作成する際、公開鍵から末尾の6204baeceb461cd568a7cf56が消えていることに注意してください。

これで、アドレス変換の仕組みとSubstrate RPCEVMアカウントを表示する仕組みがわかりました。

マップされたアドレストークンを送付してEVMアカウントからアクセスし、SubstrateアカウントからEVM預金を引き出してみましょう。

この例では、2つの異なるウォレットから2つのアカウントを作成しました。

MetaMask: 0xA843c5d2B2dFc45e6799EAE9b8dbEE0189e6CcAa
Polkadot-js: ZyakNoVJnDXcKFLYfnsTY9EZLYd6PHifzXG5jFyTbSM9dvd

では、Substrateアカウントから、EVMサンドボックスにしかアクセスできないMetaMaskアカウントに、10ASTRを送ってみましょう。

全体像としては、次のことをやろうとしています。

これを行うには、まずMetaMaskアドレスマップされたSS58アドレスに変換する必要があります。

0xA843c5d2B2dFc45e6799EA9b8dbEE0189e6CcAaを変換すると、ZaZgWyUczTxo8Zi8V4frbdHtnjbPr8RE24b3qCjCaMsKUfMになります。

このSS58アドレスpolkadot-jsから10トークンを送ります。

すると、残高がMetaMaskに表示されます。

残高の変化EVMエクスプローラにも反映されています。

しかし、ブロックイベントを見ると、Substrateレイヤー内でSubstrate署名者からトークンを送信したため、この転送のブロックイベントは表示されません。

そのため、このイベントは、Substrate RPC内では表示されていても、EVM内ではアクセスできません。

では、トークンをSS58アカウントに戻してみましょう。ZyakNoVJnDXcKFLYfnsTY9EZLYd6PHifzXG5jFyTbSM9dvdを変換すると、0xb2aed18d6495133a43dd6ecd9a5abd1fcae57150になります。

マップされたH160アカウント9.99トークン(ガス代を差し引いた額)を送金しました。

しかし、このトークンは、アカウントZyakNoVJnDXcKFLYfnsTY9EZLYd6PHifzXG5jFyTbSM9dvdSubstrate残高には直接送られません。

このトークンはEVMサンドボックス内のマッピングされたH160アカウントの残高であるEVMデポジットに保管されます。

EVMデポジットのトークンを引き出すには、元のSS58アカウントevm.withdraw関数を呼び出す必要があります。

この関数は、マップされた H160 アドレスと、引き出したいトークン数をパラメータとして要求します。

この例では、polkadot-js ポータルを使って 9.9 トークンを引き出しています。

関数を呼び出した後、ZyakNoVJnDXcKFLYfnsTY9EZLYd6PHifzXG5jFyTbSM9dvdの残高が9.9 ASTRトークン増えているのがわかります。

これで、EVMアカウントとSubstrateアカウントの間を行き来できるようになりました。

以上で、Substrate内でEVMを使用する方法について知る必要があることは全てです!

サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊