Hi Polkadot & Substrate developers,
This article presents a step-by-step Polkadot XCM tutorial, making a cross-chain asset transfer from a relay chain to a parachain, and vice versa, in a local environment.
1. Prerequisite
First, let’s set up the testing environment as following:
Rust:
nightly-2021–03–01
Relay chain code: Polkadot release-v0.9.9
Parachain code: Cumulus with ORML
https://github.com/OAK-Foundation/cumulus/tree/orml
Above code in OAK Network’s repo is a modified version of Cumulus framework with additional ORML modules.
Polkadot.js-apps UI
https://github.com/OAK-Foundation/apps/tree/orml
It is a modified version of polkadot.js/apps. Since we have added the ORML configuration to the blockchain, we need to resolve the type definition conflicts in the polkadot.js-apps by using aliases.
2. Integrating the ORML modules
In this section, we explain the ORML modules and the process of integrating them. We also shared the finished code in the repo below, so if you don’t want to go over the process manually you can skip this section.
https://github.com/OAK-Foundation/cumulus/tree/orml
About ORML modules
ORML provides a comprehensive general solution for various cross-chain token transactions. You can see the original code and detailed explanations here.
https://github.com/open-web3-stack/open-runtime-module-library
In this demo we have particularly integrated three important ORML modules into our code. They are,
orml-tokens: Fungible tokens module that implements Multi Currency trait.
orml-xcm-support: Provides traits, types, and implementations to support XCM integration.
orml-xtokens: Provides methods forXCM cross chain assets transfer.
Besides, we also referenced several other modules such as orml-currencies, orml-traits, orml-unknown-tokens, and applied Acala’s acala-primitives implementation to our code.
3. Fix typedef conflicts in polkadot.js-apps
Normally, in order to add a custom data we can set up the types in Settings -> Developer, however, in this case there’s a conflict between the tokens.accounts storage type AccountData and the original AccountData in Substrate.
We found a way to solve the problem by renaming the new AccountData in tokens.accounts to OrmlAccountData, using the typesAlias method mentioned in polkadot.js docs: type-crashes.
As shown in the screenshot below, the type name has changed to “OrmlAccountData.”
4. Setup local environment
4.1 Setup the relay chain and para-chain
The first step is to set up a relay chain and a parachain. Please refer to our previously posted tutorial on setting up the local environments .
[Tutorial] Polkadot Cross-Chain Message Passing (XCMP) demo with ping pallet
In general, the steps are:
1. Set up a Rococo relay chain network
2. Run the parachain collator node (running only one node is enough in this case, we are using para-id 2000 as an example)
3. Connect the parachain to the relay chain
4.2 Start up polkadot.j-apps UI
Run the following commands in polkadot.js/apps:
yarn
yarn run start
Relay chain portal URL:http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9944
Parachain portal URL:http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9951
5. Transfer asset from the relay chain to the para-chain
5.1 Transfer call
Run the xcmPallet.reserveTransferAssets in the relay chain’s portal:
http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics
The parameters are set as following:
In the screenshot the relay chain account is transferring 7 * 10¹⁵ planck(generally the smallest unit for Substrate blockchains are all planck) to the parachain account.
4.2 Transfer Results
You can check the tokens.account state in the parachain portal.
http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9951#/chainstate
Please note that the token unit OAK shown in the polkadot.js UI is not proper. OAK is the default token for the para-chain. Ideally, we want the transfer result to show the source chain’s token, which in this case is DOT.
Besides, the transferred amount shown 6.999 OAK (after transaction fees deduction) is calculated based on the precision(15 digits) of the para-chain token instead of that(12 digits) of the relay chain token. Using the 12 digits precision for calculation we would get the correct result 6999 DOT.
6. Transfer asset from the parachain to the relay chain
6.1 Transfer call
First, let’s top up our operating account on para-chain with some OAKs for gas fee.
Then, run the xtokens.transfer from the para-chain portal, with below parameters.
http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9951#/extrinsics
In this case a para-chain account transferred 3.1 DOTs to a relay chain account, which is 3.1 * 10¹⁵ planck, using the 15 digits precision from para-chain configuration.
5.2 Transfer Results
Now, let’s check account balance from the relay chain’s portal
http://localhost:3000/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/accounts
As shown in the screenshot, the relay chain account has received the transfer, which is 3099.9760 UNIT after gas fee deduction, calculated using 12 digits precision.
That’s all for today’s XCM cross-chain transfer tutorial.
Please let us know if you have encountered any problem with the methods explained above, and we will try our best to answer your questions.
Stay tuned for further information about the OAK Network here on Medium, Twitter and LinkedIn, as well as in our Discord Server!
Please check out our engineering and growth job openings, contact partner@oak.tech for partnerships, or contact@oak.tech for any general inquiries.
About Chris Li
Chris Li (LinkedIn) is the founder and CEO of Ava Protocol. Prior to establishing Ava Protocol, Chris gained valuable experience as a Messaging Protocol Engineer at Microsoft and as a successful serial entrepreneur. He is also a long-term EVM smart contract developer, Web3 Foundation grant recipient, and Polkadot core contributor.