xcm_docs/fundamentals.rs
1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3// This file is part of Polkadot.
4
5// Polkadot is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// Polkadot is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
17
18//! # XCM Fundamentals
19//!
20//! XCM standardizes usual actions users take in consensus systems, for example
21//! dealing with assets locally, on other chains, and locking them.
22//! XCM programs can both be executed locally or sent to a different consensus system.
23//! Examples of consensus systems are blockchains and smart contracts.
24//!
25//! The goal of XCM is to allow multi-chain ecosystems to thrive via specialization.
26//! Very specific functionalities can be abstracted away and standardized in this common language.
27//! Then, every member of the ecosystem can implement the subset of the language that makes sense
28//! for them.
29//!
30//! The language evolves over time to accomodate the needs of the community
31//! via the [RFC process](https://github.com/paritytech/xcm-format/blob/master/proposals/0032-process.md).
32//!
33//! XCM is the language, it deals with interpreting and executing programs.
34//! It does not deal with actually **sending** these programs from one consensus system to another.
35//! This responsibility falls to a transport protocol.
36//! XCM can even be interpreted on the local system, with no need of a transport protocol.
37//! However, automatic and composable workflows can be achieved via the use of one.
38//!
39//! At the core of XCM lies the XCVM, the Cross-Consensus Virtual Machine.
40//! It's the virtual machine that executes XCM programs.
41//! It is a specification that comes with the language.
42//!
43//! For these docs, we'll use a Rust implementation of XCM and the XCVM, consisting of the following
44//! parts:
45//! - [`XCM`](xcm): Holds the definition of an XCM program, the instructions and main concepts.
46//! - [`Executor`](xcm_executor): Implements the XCVM, capable of executing XCMs. Highly
47//! configurable.
48//! - [`Builder`](xcm_builder): A collection of types used to configure the executor.
49//! - [`XCM Pallet`](pallet_xcm): A FRAME pallet for interacting with the executor.
50//! - [`Simulator`](xcm_simulator): A playground to tinker with different XCM programs and executor
51//! configurations.
52//!
53//! XCM programs are composed of Instructions, which reference Locations and Assets.
54//!
55//! ## Locations
56//!
57//! Locations are XCM's vocabulary of places we want to talk about in our XCM programs.
58//! They are used to reference things like 32-byte accounts, governance bodies, smart contracts,
59//! blockchains and more.
60//!
61//! Locations are hierarchical.
62//! This means some places in consensus are wholly encapsulated in other places.
63//! Say we have two systems A and B.
64//! If any change in A's state implies a change in B's state, then we say A is interior to B.
65#![doc = simple_mermaid::mermaid!("../mermaid/location_hierarchy.mmd")]
66//!
67//! Parachains are interior to their Relay Chain, since a change in their state implies a change in
68//! the Relay Chain's state.
69//!
70//! Because of this hierarchy, the way we represent locations is with both a number of **parents**,
71//! times we move __up__ the hierarchy, and a sequence of **junctions**, the steps we take __down__
72//! the hierarchy after going up the specified number of parents.
73//!
74//! In Rust, this is specified with the following datatype:
75//! ```ignore
76//! pub struct Location {
77//! parents: u8,
78//! interior: Junctions,
79//! }
80//! ```
81//!
82//! Many junctions are available; parachains, pallets, 32 and 20 byte accounts, governance bodies,
83//! and arbitrary indices are the most common.
84//! A full list of available junctions can be found in the [format](https://github.com/paritytech/xcm-format#interior-locations--junctions)
85//! and [Junction enum](xcm::v4::prelude::Junction).
86//!
87//! We'll use a file system notation to represent locations, and start with relative locations.
88//! In the diagram, the location of parachain 1000 as seen from all other locations is as follows:
89//! - From the relaychain: `Parachain(1000)`
90//! - From parachain 1000 itself: `Here`
91//! - From parachain 2000: `../Parachain(1000)`
92//!
93//! Relative locations are interpreted by the system that is executing an XCM program, which is the
94//! receiver of a message in the case where it's sent.
95//!
96//! Locations can also be absolute.
97//! Keeping in line with our filesystem analogy, we can imagine the root of our filesystem to exist.
98//! This would be a location with no parents, that is also the parent of all systems that derive
99//! their own consensus, say Polkadot or Ethereum or Bitcoin.
100//! Such a location does not exist concretely, but we can still use this definition for it.
101//! This is the **universal location**.
102//! We need the universal location to be able to describe locations in an absolute way.
103#![doc = simple_mermaid::mermaid!("../mermaid/universal_location.mmd")]
104//!
105//! Here, the absolute location of parachain 1000 would be
106//! `GlobalConsensus(Polkadot)/Parachain(1000)`.
107//!
108//! ## Assets
109//!
110//! We want to be able to reference assets in our XCM programs, if only to be able to pay for fees.
111//! Assets are represented using locations.
112//!
113//! The native asset of a chain is represented by the location of that chain.
114//! For example, DOT is represented by the location of the Polkadot relaychain.
115//! If the interpreting chain has its own asset, it would be represented by `Here`.
116//!
117//! How do we represent other assets?
118//! The asset hub system parachain in Polkadot, for example, holds a lot of assets.
119//! To represent each of them, it uses the indices we mentioned, and it makes them interior to the
120//! assets pallet instance it uses.
121//! USDT, an example asset that lives on asset hub, is identified by the location
122//! `Parachain(1000)/PalletInstance(53)/GeneralIndex(1984)`, when seen from the Polkadot relaychain.
123#![doc = simple_mermaid::mermaid!("../mermaid/usdt_location.mmd")]
124//!
125//! Asset Hub also has another type of assets called `ForeignAssets`.
126//! These assets are identified by the XCM Location to their origin.
127//! Two such assets are a Parachain asset, like Moonbeam's GLMR, and KSM, from the cousin Kusama
128//! network. These are represented as `../Parachain(2004)/PalletInstance(10)` and
129//! `../../GlobalConsensus(Kusama)` respectively.
130//!
131//! The whole type can be seen in the [format](https://github.com/paritytech/xcm-format#6-universal-asset-identifiers)
132//! and [rust docs](xcm::v4::prelude::Asset).
133//!
134//! ## Instructions
135//!
136//! Given the vocabulary to talk about both locations -- chains and accounts -- and assets, we now
137//! need a way to express what we want the consensus system to do when executing our programs.
138//! We need a way of writing our programs.
139//!
140//! XCM programs are composed of a sequence of instructions.
141//!
142//! All available instructions can be seen in the [format](https://github.com/paritytech/xcm-format#5-the-xcvm-instruction-set)
143//! and the [Instruction enum](xcm::v4::prelude::Instruction).
144//!
145//! A very simple example is the following:
146//!
147//! ```ignore
148//! let message = Xcm(vec![
149//! TransferAsset { assets, beneficiary },
150//! ]);
151//! ```
152//!
153//! This instruction is enough to transfer `assets` from the account of the **origin** of a message
154//! to the `beneficiary` account. However, because of XCM's generality, fees need to be paid
155//! explicitly. This next example sheds more light on this:
156//!
157//! ```ignore
158//! let message = Xcm(vec![
159//! WithdrawAsset(assets),
160//! BuyExecution { fees: assets, weight_limit },
161//! DepositAsset { assets: AssetFilter(Wild(All)), beneficiary },
162//! ]);
163//! ```
164//!
165//! Here we see the process of transferring assets was broken down into smaller instructions, and we
166//! add the explicit fee payment step in the middle.
167//! `WithdrawAsset` withdraws assets from the account of the **origin** of the message for usage
168//! inside this message's execution. `BuyExecution` explicitly buys execution for this program using
169//! the assets specified in `fees`, with a sanity check of `weight_limit`. `DepositAsset` uses a
170//! wildcard, specifying all remaining `assets` after subtracting the fees and a `beneficiary`
171//! account.
172//!
173//! ## Next steps
174//!
175//! Continue with the [guides](crate::guides) for step-by-step tutorials on XCM,
176//! or jump to the [cookbook](crate::cookbook) to see examples.
177//!
178//! The [glossary](crate::glossary) can be useful if some of the terms are confusing.