PolkaWorld コミュニティに参加して、一緒に Web 3.0 を構築しましょう!
最終的な Polkadot 1.0 リリースとパラチェーンが近づく中、Cross Consensus Message Format (略して XCM) は、最初の実稼働対応バージョンをリリースしようとしています。これは、フォーマット、その目標、仕組みについての紹介であり、一般的なクロスチェーン タスクの実装に使用できます。
最終的な Polkadot 1.0 リリースとパラチェーンが近づく中、Cross Consensus Message Format (略して XCM) は、最初の実稼働対応バージョンをリリースしようとしています。これは、フォーマット、その目標、仕組みについての紹介であり、一般的なクロスチェーン タスクの実装に使用できます。
興味深い事実から始めましょう。 XCM は、単なる「クロスチェーン」ではなく、「クロスコンセンサス」メッセージ形式です。この違いは、この形式が最終的に何を達成するかを示しています。この形式は、チェーン間だけでなく、スマート コントラクトとモジュール間でも、またブリッジやシャード (Polkadot の Spree など) を介してさまざまなアイデアを送信するために通信します。
MDNICEエディター
🤟 プロトコルではなくフォーマット
ブリッジ モジュールとコントラクト モジュールを除くと、Polkadot には、構成チェーン間で XCM メッセージを実際に通信するための 3 つの異なるシステム (UMP、DMP、XCMP) が付属しています。 UMP (Up Message Passing) を使用すると、パラチェーンがリレー チェーンにメッセージを送信できるようになります。 DMP (Downward Messaging) により、リレー チェーンがメッセージをそのパラチェーンに渡すことができます。これらの中でおそらく最も有名なのは XCMP で、パラチェーン間でメッセージを送信できるようになります。 XCM を使用すると、これら 3 つの通信チャネルのいずれかを介してメッセージの意味を表現できます。
XCM は、チェーン間でメッセージを送信するだけでなく、他のコンテキストでも役立ちます。たとえば、これまでよく知らなかったトランザクション形式のチェーン上でトランザクションを実行するために使用できます。ビジネス ロジックがほとんど変更されないチェーン (ビットコインなど) では、トランザクション形式、またはウォレットがチェーンに指示を送信するために使用する形式は、無期限にまったく同じか、少なくとも互換性を維持する傾向があります。 Polkadot やその構成パラチェーンなど、高度に進化可能なメタプロトコルベースのチェーンを使用すると、単一のトランザクションでネットワーク全体のビジネス ロジックをアップグレードできます。これにより、トランザクション形式を含むあらゆるものが変更される可能性があり、ウォレット管理者、特にオフラインにしておく必要があるウォレット (パリティ署名者など) に潜在的な問題を引き起こす可能性があります。 XCM は適切にバージョン管理され、抽象的で汎用的なため、多くの一般的なトランザクションを作成するための永続的なトランザクション形式をウォレットに提供する手段として使用できます。
MDNICEエディター
🥅目標
すべての言語と同様に、特定の要素を他の言語よりも使用する傾向がある人もいます。 XCM は、XCM をサポートするすべてのシステムが考えられるすべての XCM メッセージを解釈できるように設計されているわけではありません。一部のシステムでは、一部のメッセージは合理的に解釈されません。他のものは合理的かもしれませんが、リソースの制約のため、または同じコンテンツをより明確で標準的な方法で表現できるため、インタプリタによって意図的にサポートされていません。システムは必然的に、考えられるメッセージのサブセットのみをサポートします。リソースに著しく制約のあるシステム (スマート コントラクトなど) は、非常に限られた「方言」しかサポートしない場合があります。
この浸透度は、XCM メッセージの実行に対する支払いなどの概念にまで広がります。 XCM は、ガスメーター制のスマートコントラクトプラットフォームやコミュニティパラチェーンから、システムパラチェーンとそのリレーチェーン間の信頼できる相互作用に至るまで、さまざまなシステムで使用できることがわかっているため、料金支払いなどの要素を焼き付けたくはありません。深すぎると合意が取り消せなくなります。
MDNICEエディター
😬 ネイティブのメッセージ形式を使用しないのはなぜでしょうか
第 2 に、オンチェーンの一般的なユースケースは、単一のトランザクションに簡単に適合するわけではありません。資金の引き出し、資金の交換、結果の入金をすべて 1 つのトランザクションで行うには、特別なトリックが必要になる場合があります。一貫した準備資産フレームワークに必要な後続の移転通知は、他の人に知られていないチェーンには存在しません。
第三に、料金の支払いなどの操作は、料金の支払いがスマート コントラクト メッセージのように交渉されていると仮定するモデルに簡単には適合しません。対照的に、トランザクション エンベロープは支払い処理のための何らかのシステムを提供しますが、一般に署名を含めるように設計されており、コンセンサス システム間で通信する場合には署名は無意味です。
MDNICEエディター
🎬 いくつかの初期ユースケース
XCM は汎用性、柔軟性、将来性を目指していますが、もちろん実際のニーズ、特にチェーン間のトークン転送のニーズを満たす必要があります。オプションの料金支払い(おそらくこれらのトークンを使用)は、DeFi の世界全体で一般的な交換サービスの共通インターフェイスのような別の方法です。最後に、XCM 言語を使用していくつかのプラットフォーム固有の操作を実行できる必要があります。たとえば、Substrate チェーンでは、特殊な機能にアクセスするために、そのモジュールの 1 つにリモート呼び出しをディスパッチする必要がある場合があります。
それに加えて、私たちがサポートしたいトークン転送モデルはたくさんあります。単純にリモート チェーン上のアカウントを制御し、ローカル チェーンが資金を受け取り、最終的に資金を転送するためにリモート チェーン上にアドレスを持つことを許可したい場合もあります。リモート チェーン上の他のアカウントへの制御。
2 つのコンセンサス システムがあり、どちらも特定のトークンの「ネイティブ ホーム」である可能性があります。いくつかの異なるチェーン上にインスタンスがあり、完全に交換可能な USDT や USDC のようなトークンを想像してください。このようなトークンを 1 つのチェーンで書き込み、対応するトークンを別のサポートされているチェーンで生成することが可能である必要があります。 XCM の専門用語では、これをテレポートと呼びます。資産の転送は、実際には、一方の側で資産を破壊し、もう一方の側でクローンを作成することによって行われるためです。
最後に、3 番目のチェーンを指名したい 2 つのチェーンがあり、それらのチェーンの 1 つの資産が、その資産の予備として使用されるネイティブ資産とみなされる場合があります。各オンチェーン資産のデリバティブ形式は完全にサポートされ、デリバティブ資産をそれを裏付けるリザーブチェーン上の原資産と交換できるようになります。これは、2 つのチェーンが必ずしも相互に信頼しているわけではないが、(少なくとも問題の資産に関する限り) 資産のローカル チェーンを信頼するつもりである場合が考えられます。ここでの例は、相互間で DOT を送信したいいくつかのコミュニティ パラチェーンがあることです。それぞれには、Statement チェーン (DOT のローカル ハブ) 上のパラチェーン制御の DOT によって完全にサポートされたネイティブ形式の DOT があります。ネイティブ形式の DOT はチェーン間で送信されますが、舞台裏では「本物の」DOT が Statemint 上のパラチェーン アカウント間を移動します。
この一見控えめなレベルの機能であっても、比較的多数の構成があり、それらの使用が望ましい場合があり、過剰適合を避けるためにいくつかの興味深い設計が必要です。
XCM の構造
XCM フォーマットの中心となるのは XCVM です。信じている人もいるかもしれませんが、これは (有効な) ローマ数字ではありません (ただし、ローマ数字である場合は 905 を意味する可能性があります)。実際、これは Cross Consensus Virtual Machine の略です。これは、トランザクションとほぼ同じレベルになるように設計された命令を備えた、非常に高度な非チューリング完全コンピューターです。
XCM の「メッセージ」は、実際には XCVM 上で実行される単なるプログラムです。これは 1 つ以上の XCM ディレクティブです。プログラムは最後まで実行されるか、エラーが発生するまで実行され、エラーが発生した時点で (意図的に今は説明しませんが) 終了して停止します。
enum Instruction {
TransferAsset {
assets: MultiAssets,
beneficiary: MultiLocation,
}
/* snip */
}
XCVM には、多数のレジスタと、それをホストするコンセンサス システムの全体的な状態へのアクセスが含まれています。命令はレジスタを変更することも、コンセンサス システムの状態を変更することも、あるいはその両方を変更することもできます。
おそらくご想像のとおり、資産はどの資産が譲渡されるのかを示すパラメータであり、受益者はそれらの資産が誰に、どこに与えられるかを指定します。もちろん、資産を誰からどこから入手するかという別の情報が欠落しています。これは、元のレジスタから自動的に推測されます。プログラムの開始時に、このレジスタは通常、メッセージの実際の送信元を反映する送信システム (ネットワーク、XCMP など) に従って設定され、受益者も同じ種類の情報になります。 Origin Register は保護された Register として動作します。何らかの方法で変更するために使用できる命令が 2 つありますが、プログラムが任意に設定することはできません。
使用されるタイプは、XCM の非常に基本的な考え方です。つまり、MultiAsset で表されるアセット、MultiLocation で表されるコンセンサス内のロケーションです。 Origin Register はオプションの MultiLocation です (必要に応じて完全にクリアできるためオプションです)。
MDNICEエディター
📍 XCMの場所にて
MultiLocation タイプは、コンセンサス世界に存在する単一の場所を識別します。これは、スケーラブルなマルチシャード ブロックチェーン (Polkadot など) から、コンセンサスのもとに存在するパラチェーン上の低レベルの ERC-20 アセット アカウントに至るまで、あらゆるものを表現できるかなり抽象的なアイデアです。コンピューター サイエンスの用語では、サイズや複雑さに関係なく、実際には単なるグローバル シングルトン データ構造です。
MultiLocation は常に、現在の場所を基準とした相対的な場所を表します。ファイルシステムのパスのように考えることができますが、ファイルシステム ツリーの「ルート」を直接表現する方法はありません。これには単純な理由があります。Polkadot の世界では、ブロックチェーンを他のブロックチェーンにマージしたり、他のブロックチェーンからフォークしたりすることができます。ブロックチェーンは非常に独立して誕生し、最終的にはより大きなコンセンサスの中でパラチェーンとして推進される可能性があります。そうすると、「ルート」の意味が一夜にして変わり、XCM メッセージや MultiLocation を使用するその他のメッセージが混乱する可能性があります。簡単にするために、この可能性は完全に除外しました。
XCM のポジションは階層的であり、コンセンサスの一部の場所はコンセンサスの他の場所に完全にカプセル化されています。 Polkadot のパラチェーンは、Polkadot 全体のコンセンサス内に完全に存在しており、これを内部ポジションと呼びます。より厳密には、あるコンセンサス システムの変更が別のコンセンサス システムの変更を意味するときは常に、前者のシステムは後者の内部にあると言えます。たとえば、Canvas スマート コントラクトは、それをホストするコントラクト モジュール内に存在します。ビットコインの UTXO はビットコイン ブロックチェーンの内部にあります。
これは、XCM が「誰が」と「どこで」という質問を区別しないことを意味します。 XCM のようなかなり抽象的なものの観点からは、区別は重要ではありません。2 つは曖昧になり、本質的に同じものになります。
MultiLocation は、XCM メッセージが送信される場所、アセットを受信できる場所を識別するために使用され、さらに、後で説明するように、アセット自体のタイプを記述するのにも役立ちます。とても便利なものです。
このようにテキストに書き出すと、それらはいくつかの .. (またはコンセンサス システムをカプセル化する「親」) コンポーネントとして表され、その後にいくつかの結合ポイントが続き、すべて / で区切られます。 (これは通常、Rust のような言語で表現する場合には起こりませんが、広く使用されているよく知られたディレクトリ パスに似ているため、理論上は理にかなっています。) カプセル化されたコンセンサス内の接続 内部ロケーション システムを識別します。親ノード/接続点がまったくない場合は、その位置がここにあると言うだけです。
例えば:
../Parachain(1000): パラチェーンで評価します。これにより、インデックス 1000 の兄弟パラチェーンが識別されます。 (Rust では、ParentThen(Parachain(1000)).into() と書きます。
Parachain(42)/AccountKey20(0x1234...abcd): リレーチェーンで評価され、パラチェーン番号 42 上の 20 バイトのアカウント 0x1234...abcd が識別されます (おそらく、Ethereum 互換アカウントをホストしている Moonbeam と同様です)。
キー、インデックス、バイナリ BLOB、複数の説明など、さまざまな方法でチェーン上のどこにあるかを識別するために使用されるさまざまなタイプの結合ポイントがあります。
MDNICEエディター
💰 XCM のアセット
XCM で作業する場合、多くの場合、ある種のアセットを参照する必要があります。これは、ほとんどすべての既存のパブリック ブロックチェーンが、内部の経済およびセキュリティ メカニズムのバックボーンを提供するために何らかのネイティブ デジタル資産に依存しているためです。ビットコインのようなプルーフ・オブ・ワーク・ブロックチェーンの場合、ネイティブ資産(BTC)は、ブロックチェーンを開発したマイナーに報酬を与え、二重支出を防ぐために使用されます。 Polkadot などのプルーフ オブ ステーク ブロックチェーンの場合、ネイティブ アセット (DOT) は、有効なブロックを生成して物理的な報酬を受け取るためにネットワーク管理者 (ステーカーと呼ばれる) が負担しなければならない担保の形式として使用されます。
struct MultiAsset {
id: AssetId,
fun: Fungibility,
}
一部のブロックチェーンは複数の資産を管理します。たとえば、イーサリアムの ERC-20 フレームワークでは、多くの異なる資産をオンチェーンで管理できます。イーサリアムの ETH など、非代替性を管理する一部の資産は非代替性、つまり固有のインスタンスであり、クリプトキティはそのような非代替性トークン (NFT) の初期の例です。
plain
enum AssetId {
Concrete(MultiLocation),
Abstract(BinaryBlob),
}
XCM は、そのようなすべての資産を簡単に処理できるように設計されています。この目的のために、データ型 MultiAsset とそれに関連する型 MultiAssets、WildMultiAsset、および MultiAssetFilter があります。 Rust の MultiAsset を見てみましょう。
enum Fungibility {
Fungible(NonZeroAmount),
NonFungible(AssetInstance),
}
したがって、アセットを定義するフィールドは 2 つあります。id と fun です。これは、XCM がアセットをどのように処理するかを示す良い指標です。まず、全体的な資産のアイデンティティを提供する必要があります。代替資産の場合、これは単に資産を識別するだけです。 NFT の場合、これは資産の「クラス」全体を識別します。このクラス内にはさまざまな資産インスタンスが存在する可能性があります。
アセットのアイデンティティは、具体または抽象の 2 つの方法のいずれかで表現されます。 Abstract は実際には使用されませんが、アセット ID を名前で指定できます。これは便利ですが、送信者が期待する方法で名前を解釈するのは受信者に依存するため、必ずしも簡単であるとは限りません。 Concrete では、資産を明確に識別するために、一般的に場所を使用します。ネイティブ アセット (例: DOT) の場合、アセットは多くの場合、アセットが鋳造されたチェーン (この場合は、パラチェーンが存在する Polkadot リレー チェーン) として識別されます。主にチェーン モジュール内で管理される資産は、そのモジュール内のインデックス位置を含めることで識別できます。たとえば、Karura パラチェーンは、 ../Parachain(1000)/PalletInstance(50)/GeneralIndex(42) にある Statemine パラチェーン上のアセットを参照する場合があります。
第二に、それらは代替可能であるか代替不可能である必要があります。代替可能であれば、関連するゼロ以外の数量が存在するはずです。交換できない場合は、数量ではなく、どのインスタンスであるかを示す必要があります。 (これは通常、インデックスによって表されますが、XCM では、配列やバイナリ BLOB など、他のさまざまなデータ型も使用できます。) これは MultiAsset を対象としていますが、他の 3 つの関連する型を使用する場合もあります。 MultiAssets もその 1 つで、実際には MultiAsset アイテムのセットを意味します。次に、WildMultiAsset があります。これは、1 つ以上の MultiAsset アイテムと一致するために使用できるワイルドカードです。実際には、All (すべてのアセットに一致) と AllOf は、特定の ID (AssetId) と代替性を持つすべてのアセットに一致する 2 つのワイルドカードのみをサポートします。特に、後者の場合、数量 (代替可能な場合) またはインスタンス (代替不可能な場合) を指定する必要はなく、すべてが一致します。
👉 Holding Register
最後に、MultiAssetFilter があります。これは最も一般的に使用されており、実際には MultiAssets と WildMultiAsset を組み合わせたもので、ワイルドカードまたは明示的な (つまり、非ワイルドカード) アセットのリストを指定できます。
WithdrawAsset(MultiAssets),
Rust XCM API では、これらのデータ型の操作をできるだけ簡単にするために、いくつかの変換が提供されています。たとえば、Polkadot リレー チェーン上にいる場合、100 個の分割不可能な DOT アセット ユニットに等しい代替可能な MultiAsset (詳しい人にとっては Planck) を指定するには、(ここでは 100).into () を使用します。
別の XCM 命令である WithdrawAsset を見てみましょう。表面的には、これは TransferAsset の前半と少し似ています。元のアカウントから一部の資産を引き出します。しかし、彼らにとってそれは何でしょうか?もし彼らがそれをどこにも預けないとしたら、それはかなり無駄な操作に違いありません。 Rust 宣言を見ると、その使用法に関するさらなる手がかりが見つかります。
enum Instruction {
DepositAsset {
assets: MultiAssetFilter,
max_assets: u32,
beneficiary: MultiLocation,
},
/* snip */
}
したがって、今回はパラメータが 1 つだけです (MultiAssets タイプ。どの資産を原点登録簿の所有権から取り下げる必要があるかを指定します)。ただし、アセットをどこに配置するかは指定されていません。
これらの一時的に保持される未使用の資産は、保持レジスターと呼ばれます。 (永久に持続しない一時的な場所にあるため「保持」、作業データを保存する場所である CPU レジスタに似ているため「レジスタ」です。) 保持レジスタ上で動作する命令は数多くあります。非常に単純なディレクティブは DepositAsset ディレクティブです。見てみましょう:
ああ!賢明な読者は、これが TransferAsset ディレクティブの欠けている半分によく似ていることに気づくでしょう。オンチェーンにデポジットされる保持レジスターからどの資産を削除するかを指定する、assets パラメーターがあります。 max_assets を使用すると、XCM 作成者は受信者に、デポジットする予定の固有のアセットの数を通知できます。 (資産の預け入れは高価な操作となる可能性があるため、これは、保有登録簿の内容を知る前に料金を計算する場合に役立ちます。) 最後に受益者があります。これは、TransferAsset 操作で以前に遭遇したのと同じパラメーターです。 Holding Register で実行されるアクションを表すディレクティブは数多くありますが、DepositAsset は最も単純なディレクティブの 1 つです。他はもっと複雑です。
🤑 XCMでの料金支払い
XCM での料金支払いは、非常に重要なユースケースです。 Polkadot コミュニティのほとんどのパラチェーンは、「トランザクション スパム」やサービス拒否攻撃への扉を開かないように、対話者が希望する操作に対して料金を支払うことを要求します。例外は、チェーンが対話者が適切に行動すると信じる十分な理由がある場合にも存在します。これは、Polkadot リレー チェーンが Polkadot Statemint 公益チェーンと通信する場合です。ただし、一般的なケースでは、XCM メッセージとそのトランスポート プロトコルが過剰に使用されないようにするには、料金を支払うのが良い方法です。 XCM メッセージが Polkadot に到達したときに料金がどのように支払われるかを見てみましょう。
前述したように、XCM には第一級市民としての手数料や手数料の支払いが含まれていません。イーサリアムのトランザクション モデルとは異なり、プロトコルで手数料の支払いが必須ではないためには、それを回避する必要があります。 Rust のゼロコスト抽象化と同様に、XCM では料金の支払いに大きな設計オーバーヘッドがありません。
支払いが必要なシステムの場合、XCM は資産を使用して実行リソースを購入する機能を提供します。大まかに言うと、これには次の 3 つの部分が含まれます。
まず、いくつかのアセットを提供する必要があります。
2 番目に、資産は計算時間 (サブストレート用語での重み) と交換する必要があります。
最後に、XCM 操作が指示に従って実行されます。
WithdrawAsset((Here, 10_000_000_000).into()),
最初の部分は、アセットを提供するいくつかの XCM ディレクティブの 1 つによって管理されます。これらのディレクティブの 1 つ ( WithdrawAsset ) はすでに知っていますが、他にもいくつかあります。これについては後ほど説明します。結果として生じる保有登録簿内の資産は、当然のことながら、XCM の実行に関連するコストの支払いに使用されます。料金の支払いに使用されなかった資産は、宛先口座に入金されます。この例では、XCM が Polkadot リレー チェーンで行われ、1 DOT (つまり、10,000,000,000 不可分単位) が取引されると仮定します。
enum Instruction {
/* snip */
BuyExecution {
fees: MultiAsset,
weight: u64,
},
}
現在、XCM ディレクティブは次のようになります。
これで 2 番目の部分に進み、XCM で支払う計算時間と引き換えにこれらの資産 (の一部) を交換します。このために、XCM 命令 BuyExecution があります。どのようなものかを見てみましょう:
最初の商品手数料は、保有登録簿から引き出されて手数料の支払いに使用される金額です。技術的には、これは上限にすぎず、未使用の残高はすぐに返金されます。
WithdrawAsset((Here, 10_000_000_000).into()),
BuyExecution {
fees: (Here, 10_000_000_000).into(),
weight: 3_000_000,
},
最終的な支出額は通訳システム次第です。料金は上限に過ぎず、通訳システムが希望の実行に対して追加料金を支払う必要がある場合、BuyExecution 命令によりエラーが発生します。 2 番目の項目は、購入する実行時間の量を指定します。これは通常、XCM プログラムの総重量を下回ってはなりません。
この例では、すべての XCM 命令の重みを 100 万と想定しているため、これまでのところ 200 万の 2 つのプロジェクト (WithdrawAsset と BuyExecution) があり、さらに 1 つが今後追加されます。これらの料金を支払うために必要な DOT をすべて使用するだけです (これは、宛先チェーンに法外な料金がかからないと信頼できる場合にのみ意味を成します - それが事実であると仮定します)。この時点で、XCM を見てみましょう。
WithdrawAsset((Here, 10_000_000_000).into()),
BuyExecution {
fees: (Here, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(1000).into(),
},XCM の 3 番目の部分は、残りの資金を保有登録簿に預けることです。このためには、DepositAsset ディレクティブを使用します。実際に保有登録簿にどれだけ残っているかはわかりませんが、預けるべき資産に対してワイルドカードを指定できるため、それは問題ではありません。これらを Statemint のソブリンアカウント (Parachain(1000) として識別) に入れました。
最終的な XCM ディレクティブは次のようになります。
アセットを別のチェーンに送信することは、おそらくチェーン間メッセージングの最も一般的な使用例です。あるチェーンが別のチェーンのネイティブ資産を管理できるようにすると、さまざまなデリバティブなユースケース(しゃれではありません)が可能になります。最も単純なものは分散型取引所ですが、多くの場合、分散型金融またはDe-Fiとしてまとめられます。
一般に、チェーン間でアセットを移動するには、チェーンが互いのセキュリティとロジックを信頼しているかどうかに応じて 2 つの方法があります。
MDNICEエディター
✨テレポート
WithdrawAsset((Here, 10_000_000_000).into()),
InitiateTeleport {
assets: All.into(),
dest: Parachain(1000).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parent.into(),
},
]),
}
相互に信頼しているチェーン (たとえば、同じ全体的なコンセンサスとセキュリティの傘の下にある同種のシャード) の場合、テレポーテーションと呼ばれる Polkadot のフレームワークを使用できます。これは基本的に、送信側で資産を破棄し、受信側でそれを鋳造することを意味します。この防御方法はシンプルかつ効率的です。必要なのは 2 つのチェーンの調整のみで、各側でのアクションは 1 つだけです。残念ながら、受信側チェーンが、送信側チェーンが実際に鋳造している資産を破棄することを 100% 信頼できない場合 (実際に、資産の合意されたルールを超えて資産を鋳造しない場合)、送信側チェーンには、実際には、メッセージ。
XCM が (主に) 1 DOT を Polkadot リレー チェーンから Statemint のソブリン アカウントに転送する様子を見てみましょう。 Polkadot がすでに料金を支払っているものとします。
ご覧のとおり、これは前回見た直接引き出し購入入金モデルと非常によく似ています。違いは、最後の 2 つのディレクティブ (BuyExecution と DepositAsset) の前後に挿入される InitiateTeleport ディレクティブです。バックグラウンドでは、送信チェーン (Polkadot リレー チェーン) は、InitiateTeleport 命令を実行するときに新しいメッセージを作成します。xcm フィールドを取得して新しい XCMReceiveTeleportedAsset に入れ、この XCM を受信チェーン (Statemint) に送信します。 Statemint は、Polkadot リレー チェーンがメッセージを送信する前に側の 1 つの DOT を破壊したと考えています。 (そして、そうです!)
ReceiveTeleportedAsset((Parent, 10_000_000_000).into()),
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parent.into(),
},
受益者は Parent.into() として宣言されていますが、賢明な読者は、これが Polkadot リレー チェーンのコンテキストで何を指すのか疑問に思うかもしれません。答えは「何もありません」ですが、何も問題はありません。 xcm パラメータ内のすべては受信者の観点から書かれているため、これは Polkadot リレー チェーンに供給される XCM 全体の一部ですが、実際には Statemint 上でのみ実行されるため、そのコンテキストは Statemint の後に続きます。
お気づきかと思いますが、これは以前の WithdrawAsset XCM と非常によく似ています。唯一の大きな違いは、ローカル アカウントから引き出して手数料や預金を調達するのではなく、送信者 (Polkadot リレー チェーン) で DOT が実際に書き込まれていることを信頼して、ReceiveTeleportedAsset メッセージを尊重することです。 Polkadot リレー チェーン (ここで、リレー チェーン自体を指すのは DOT のネイティブ環境です) 上で送信した 1 つの DOT のアセット識別子が、Statement: Parent. into() での表現に自動的に変更されたことは注目に値します。 Statemint コンテキストにおけるリレー チェーンの位置。
受益者は Polkadot リレーチェーンとしても指定されているため、そのソブリン口座 (Statement 上) には、新たに鋳造された 1 DOT から手数料を差し引いた金額が入金されます。 XCM は、受益者の口座またはその他のものを簡単に指定することができます。実際、この 1 DOT は、リレー チェーンから送信される後続の TransferAsset を使用して移動できます。
MDNICEエディター
🏦 リザーブ
チェーン間で資産を転送する別の方法は、少し複雑です。リザーブと呼ばれる第三者が使用されます。この名前は、公表された特定の価値の約束に信頼性を与えるために資産が「留保」される銀行の準備金システムに由来しています。たとえば、独立したパラチェーン上で発行された各「派生」DOT が 1 つの「真の」DOT (リレー チェーン上の Statemint や DOT など) と交換できると信じる理由がある場合、パラチェーンの DOT を次のようにすることができます。経済的には実際の DOT と同等であると考えられます。 (ほとんどの銀行は端数準備銀行業務を行っており、額面よりも少ない額の準備金を保管しています。これは通常は問題ありませんが、償還したい人が多すぎるとすぐに問題が発生する可能性があります。) したがって、準備金は「本物」を保管する場所です。送信目的の資産。そのロジックとセキュリティは送信者と受信者の両方によって信頼されます。送信側と受信側の対応する資産はデリバティブになりますが、「実際の」準備資産によって 100% 裏付けられます。パラチェーンが適切に動作していると仮定すると(つまり、バグがなく、そのガバナンスがリザーブを盗んで逃亡することを決定していない)、これにより派生DOTは基礎となるリザーブDOTとほぼ同じ値になります。リザーブ資産はリザーブチェーン上の送信者/受信者のソブリンアカウント(つまり、送信者または受信者のチェーンによって管理されるアカウント)に保持されているため、パラチェーンに問題がない限り、これらの資産は十分に保護されると信じる十分な理由があります。の。
WithdrawAsset((Parent, 10_000_000_000).into()),
InitiateReserveWithdraw {
assets: All.into(),
dest: ParentThen(Parachain(1000)).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositReserveAsset {
assets: All.into(),
max_assets: 1,
dest: ParentThen(Parachain(2001)).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
]),
},
]),
},
転送メカニズムに戻ると、送信者は準備金に対し、送信者が所有する資産を(同じ資産の独自バージョンの準備金として使用して)受信者のソブリン口座に転送するように指示します。送信者側!) 受信者に新しいアセットを通知します。これは、送信者と受信者が互いのロジックやセキュリティを信頼する必要はなく、予備として使用されるチェーンのロジックやセキュリティのみを信頼する必要があることを意味します。ただし、これは 3 者間で調整する必要があることを意味しており、全体的なコスト、時間、複雑さが増大します。
WithdrawAsset((Parent, 10_000_000_000).into()),
InitiateReserveWithdraw {
assets: All.into(),
dest: ParentThen(Parachain(1000)).into(),
xcm: /* snip */
}
必要な XCM を見てみましょう。今回は、パラチェーン 2000 から 1 つの DOT を、パラチェーン 1000 のリザーブバックド DOT を使用するパラチェーン 2001 に送信します。繰り返しになりますが、料金は送信者にすでに支払われているものとします。
/*snip*/
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositReserveAsset {
assets: All.into(),
max_assets: 1,
dest: ParentThen(Parachain(2001)).into(),
xcm: /* snip */
},
]),
/*snip*/
前にも言いましたが、少し複雑になります。プロセスを見てみましょう。外部部分は、送信側 (パラチェーン 2000) で 1 DOT を引き出し、Statement (パラチェーン 1000) で対応する 1 DOT を引き出します。このために、指示どおりに実行する InitiateReserveWithdraw を使用します。
/*snip*/
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
]),
/*snip*/
現在、ステートミントの保有登録簿に 1 つの DOT を保有しています。他のことをする前に、Statement で実行時間を稼ぐ必要があります。このプロセスも見慣れたものです。
ReserveAssetDeposited((Parent, 10_000_000_000).into()),
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
料金の支払いには独自の 1 DOT を使用し、XCM 操作ごとに 100 万を想定しています。この 1 回の操作の支払い後、1 DOT (手数料を差し引いて、怠け者なので All.into() を使用するだけ) を Parachain 2001 のソブリン アカウントに入金しますが、これは予備資産として行われます。これは、を意味します。また、Statement に対して、この受信チェーンに通知 XCM を送信して、転送と、結果として生じるデリバティブ資産に対して実行されるいくつかの命令を通知するよう依頼します。 DepositReserveAsset ディレクティブは常に機能するとは限りません。機能するには、dest がリザーブ チェーン上で資金を合理的に保持でき、リザーブ チェーンが XCM を送信できる場所である必要があります。ブラザーパラチェーンはまさにその要件に適合します。
最後の部分は、パラチェーン 2001 に到着するメッセージの部分を定義します。転送操作を開始するのと同じように、 DepositReserveAsset は新しいメッセージ (この場合は ReserveAssetDeposited ) を作成して送信します。このメッセージには、定義した XCM プログラムが含まれていますが、受信パラチェーンに到達します。次のようになります。
(これは、Statementt が実際には手数料を取らず、1 DOT 全体が通過したことを前提としています。これは特に現実的ではないため、資産行の数値はこれよりも低くなる可能性があります。) このメッセージの多くは見覚えがあるはずです。前のセクションで見た ReceiveTeleportedAsset メッセージとの唯一の顕著な違いは、トップレベルのディレクティブ ReserveAssetDeposited です。これは同様の目的を達成しますが、「送信チェーンがアセットを破棄するので、同等のアセットをミントできる」という点が異なります。これは、「送信チェーンが資産を受け取り、保管しているため、完全な資産に裏付けられたデリバティブを鋳造できる」というものです。いずれにせよ、宛先チェーンはそれらをホールディング・リザーブに鋳造し、私たちはそれらを受信チェーン上の送信者のソブリン口座に預け入れます。 🎉
“
🏁 結論
