Skip to content

Commit 11e4b55

Browse files
committed
fix: weigh messages and execute done
1 parent 0ea64f7 commit 11e4b55

File tree

9 files changed

+352
-1
lines changed

9 files changed

+352
-1
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.20;
3+
4+
/**
5+
* @title XcmCaller
6+
* @dev A contract to interact with the IXcm precompile at a fixed address.
7+
*/
8+
contract XcmCaller {
9+
// The address of the IXcm precompiled contract.
10+
address private immutable XCM_PRECOMPILE_ADDRESS = 0x00000000000000000000000000000000000a0000;
11+
12+
/**
13+
* @notice Forwards the xcmExecute call to the precompiled IXcm contract.
14+
* @param message The Versioned XCM message to send.
15+
* @param weight The maximum amount of weight to be used to execute the message.
16+
*/
17+
function callXcmExecute(bytes calldata message, IXcm.Weight calldata weight) external {
18+
IXcm(XCM_PRECOMPILE_ADDRESS).execute(message, weight);
19+
}
20+
21+
/**
22+
* @notice Forwards the xcmSend call to the precompiled IXcm contract.
23+
* @param destination The destination location, encoded according to the XCM format.
24+
* @param message The Versioned XCM message to send.
25+
*/
26+
function callXcmSend(bytes calldata destination, bytes calldata message) external {
27+
IXcm(XCM_PRECOMPILE_ADDRESS).send(destination, message);
28+
}
29+
30+
/**
31+
* @notice Forwards the weighMessage call to the precompiled IXcm contract.
32+
* @param message The XCM message to send.
33+
* @return weight The estimated weight cost.
34+
*/
35+
function callWeighMessage(bytes calldata message) external view returns (IXcm.Weight memory) {
36+
return IXcm(XCM_PRECOMPILE_ADDRESS).weighMessage(message);
37+
}
38+
39+
receive() external payable {}
40+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
title: Precompiles
22
nav:
33
- index.md
4-
- 'Interact With Precompiles': interact-with-precompiles.md
4+
- 'Interact With Precompiles': interact-with-precompiles.md
5+
- 'XCM Precompile': xcm-precompile.md
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: Interact with the XCM Precompile
3+
description: Learn how to use the XCM precompile to send cross-chain messages, execute XCM instructions, and estimate costs from your smart contracts
4+
---
5+
6+
# XCM Precompile
7+
8+
## Introduction
9+
10+
The XCM (Cross-Consensus Message) precompile enables Polkadot Hub developers to access XCM functionality directly from their smart contracts. This precompile enables contracts to send cross-chain messages, execute XCM instructions locally, and estimate execution costs—all through a standardized Solidity interface.
11+
12+
Located at the fixed address `0x00000000000000000000000000000000000a0000`, the XCM precompile offers three primary functions: `execute` for local XCM execution, `send` for cross-chain message transmission, and `weighMessage` for cost estimation. This guide demonstrates how to interact with the XCM precompile through Solidity smart contracts using [Remix IDE](/develop/smart-contracts/dev-environments/remix.md){target=\_blank}.
13+
14+
## Precompile Interface
15+
16+
The XCM precompile implements the `IXcm` interface, which defines the structure for interacting with XCM functionality:
17+
18+
```solidity title="IXcm.sol"
19+
--8<-- "https://raw.githubusercontent.com/paritytech/polkadot-sdk/cb629d46ebf00aa65624013a61f9c69ebf02b0b4/polkadot/xcm/pallet-xcm/src/precompiles/IXcm.sol"
20+
```
21+
22+
The interface defines a `Weight` struct that represents the computational cost of XCM operations. Weight has two components: `refTime` (computational time on reference hardware) and `proofSize` (size of the proof needed for execution). All XCM messages must be encoded using the [SCALE codec](/polkadot-protocol/parachain-basics/data-encoding/#data-encoding){target=\_blank}, Polkadot's standard serialization format.
23+
24+
For further information, check the [`precompiles/IXCM.sol`](https://github.com/paritytech/polkadot-sdk/blob/cb629d46ebf00aa65624013a61f9c69ebf02b0b4/polkadot/xcm/pallet-xcm/src/precompiles/IXcm.sol){target=\_blank} file present in the `pallet-xcm`.
25+
26+
## XCM Caller Contract
27+
28+
The `XcmCaller` contract provides a convenient wrapper around the XCM precompile, handling the low-level interactions and providing a more user-friendly interface:
29+
30+
```solidity title="XcmCaller.sol"
31+
--8<-- "code/develop/smart-contracts/precompiles/xcm-precompile/XcmCaller.sol"
32+
```
33+
34+
The contract utilizes an immutable address that points to the XCM precompile and provides three wrapper functions corresponding to the precompile's interface methods. The `receive()` function enables the contract to accept tokens, which may be required for specific XCM operations.
35+
36+
### Weight a Message
37+
38+
The `weighMessage` function estimates the computational cost required to execute an XCM message. This is crucial for understanding the resources needed before actually executing or sending a message.
39+
40+
To test this functionality in Remix:
41+
42+
1. Copy and paste the `IXCM` interface and the `XCMCaller` contract into a Solidity file
43+
2. Compile the contract
44+
45+
![](/images/develop/smart-contracts/precompiles/xcm-precompile/xcm-precompile-01.webp)
46+
47+
3. Deploy the `XcmCaller` contract
48+
49+
![](/images/develop/smart-contracts/precompiles/xcm-precompile/xcm-precompile-02.webp)
50+
51+
4. Call `callWeighMessage` with a SCALE encoded XCM message. For example, for testing, you can use the following encoded XCM message:
52+
53+
```text title="encoded-xcm-message-example"
54+
0x050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e
55+
```
56+
57+
This encoded message represents a sequence of XCM instructions:
58+
59+
- **[Withdraw Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#withdrawasset){target=\_blank}**: This instruction removes assets from the local chain's sovereign account or the caller's account, making them available for use in subsequent XCM instructions.
60+
- **[Buy Execution](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#buyexecution){target=\_blank}**: This instruction purchases execution time on the destination chain using the withdrawn assets, ensuring the message can be processed.
61+
- **[Deposit Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: This instruction deposits the remaining assets into a specified account on the destination chain after execution costs have been deducted.
62+
63+
This encoded message is provided as an example. You can craft your own XCM message tailored to your specific use case as needed
64+
65+
The function returns a `Weight` struct containing `refTime` and `proofSize` values, which indicate the estimated computational cost of executing this message. If successful, after calling the `callWeighMessage` function, you should see the `refTime` and `proofSize` of the message:
66+
67+
![](/images/develop/smart-contracts/precompiles/xcm-precompile/xcm-precompile-03.webp)
68+
69+
### Execute a Message
70+
71+
The `execute` function runs an XCM message locally using the caller's origin. This is useful for executing XCM instructions that don't require cross-chain communication.
72+
73+
To execute a message:
74+
75+
1. First, ensure that your contract has enough funds to cover the execution costs of calling the XCM message. Check the [Test Token](/develop/smart-contracts/connect-to-polkadot#test-tokens){target=\_blank} section for more information
76+
2. Call `callWeighMessage` with your XCM message to get the required weight
77+
3. Use the returned weight values when calling `callXcmExecute`
78+
4. Pass the same XCM message bytes and the weight obtained from the previous step. For example, using the same message from the weighing example, you would call `callXcmExecute` with:
79+
80+
- `message`: The encoded XCM message bytes.
81+
- `weight`: The `Weight` struct returned from `callWeighMessage`.
82+
83+
You can examine the full extrinsic structure for this operation [here](https://dev.papi.how/extrinsics#networkId=localhost&endpoint=wss%3A%2F%2Ftestnet-passet-hub.polkadot.io&data=0x1f03050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e0750c61e2901daad0600).
84+
85+
5. Click on the **Transact** button to execute the xcm message:
86+
87+
![](/images/develop/smart-contracts/precompiles/xcm-precompile/xcm-precompile-04.webp)
88+
89+
If successful, you will see the following output in the Remix terminal:
90+
91+
![](/images/develop/smart-contracts/precompiles/xcm-precompile/xcm-precompile-05.webp)
92+
93+
Also, you can verify that the execution of this specific message succeeded by checking that the beneficiary account of the xcm message has received the funds accordingly.
94+
95+
### Send a Message
96+
97+
The `send` function transmits an XCM message to a destination chain. This is the core functionality for cross-chain communication.
98+
99+
To send a message:
100+
101+
1. Prepare your destination location encoded in XCM format
102+
2. Prepare your XCM message (similar to the execute example)
103+
3. Call `callXcmSend` with both parameters
104+
105+
The destination parameter must be encoded according to XCM's location format, specifying the target parachain or consensus system. The message parameter contains the XCM instructions to be executed on the destination chain.
106+
107+
Unlike `execute`, the `send` function doesn't require a weight parameter since the destination chain will handle execution costs according to its own fee structure.
108+
109+
## Conclusion
110+
111+
The XCM precompile provides a powerful interface for cross-chain interactions within the Polkadot ecosystem. By understanding how to properly encode messages, estimate weights, and execute or send XCM instructions, developers can build sophisticated cross-chain applications that leverage the full potential of Polkadot's interoperability features.
112+
113+
<!-- The examples in this guide demonstrate the basic patterns for interacting with the XCM precompile through Remix IDE. For more comprehensive examples and testing scenarios, check out the [XCM Hardhat example](https://github.com/polkadot-developers/polkavm-hardhat-examples){target=\_blank} which provides additional tools and test cases for working with XCM precompiles in a development environment. -->
151 KB
Loading
183 KB
Loading
171 KB
Loading
172 KB
Loading
166 KB
Loading

0 commit comments

Comments
 (0)