XCM reference

⚠️ WARNING: This page contains potentially outdated information. Reading it might still be useful, yet we suggest taking it with a grain of salt.

Please refer to the `polkadot-sdk-docs` crate for the most up-to-date documentation on this topic.

This section provides reference information for the cross-consensus message (XCM) format.

Instructions

As you learned in Cross-consensus communication, the XCM executor is a program that executes an ordered set of instructions in a virtual machine running on the recipient consensus system. It's worth noting that some instructions are dependent on other instructions. The order in which instructions are listed in the Instruction enumeration reflects some of these dependencies. For example, an asset must be added to the holding register before it can be deposited somewhere else. In general, you also use a similar order for instructions when you construct a message to be sent to the receiving system. However, for your convenience, this reference section lists the instructions in alphabetic order instead of the order in which they are defined.

BuyExecution

Pays for the execution of the current message by removing assets from the holding register. You must specify the fees parameter to identify the asset to remove from the holding register to pay execution fees. You can also specify a weight_limit for the maximum fee to be purchased. If the weight_limit you specify is lower than the estimated weight of the message, the XCM executor stops execution with the TooExpensive error.

ParameterDescription
feesSpecifies the assets to be removed from the holding register to pay transaction fees.
weight_limitSpecifies the maximum weight to be purchased to pay execution fees. If you don't specify a limit, the weight is treated as unlimited up to the maximum you specify to be removed from the holding register.

The following example illustrates the settings for a BuyExecution instruction:

{
  BuyExecution: {
    fees: {
      id: {
        Concrete: {
          parents: 0
          interior: Here
        }
      }
      fun: {
        Fungible: 1,000,000
      }
    }
    weightLimit: {
      Limited: 1,000,000
    }
  }
}

The following example illustrates using the instruction in a Rust program:

BuyExecution { fees, weight_limit } => {
    if let Some(weight) = Option::<u64>::from(weight_limit) {
        // pay for `weight` using up to `fees` of the holding register.
        let max_fee =
            self.holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
        let unspent = self.trader.buy_weight(weight, max_fee)?;
        self.holding.subsume_assets(unspent);
    }
    Ok(())
},

ClaimAsset

Creates assets that are being held on behalf of the location identified in the origin register. You must specify the assets parameter to identify the assets to be claimed. The asset you specify must match exactly with the assets available to be claimed by the origin with the given ticket. You must specify the ticket using the MultiLocation type. The claim ticket for the asset is an abstract identifier to help locate the asset to be claimed.

ParameterDescription
assetsSpecifies the assets to be claimed.
ticketSpecifies a location to help identify the asset to be claimed.

ClearError

Clears the error register. You can use this instruction to manually clear the last error from the error register.

ClearOrigin

Clears the origin register. You can use this instruction to ensure that later instructions cannot take over the authority of the original origin. For example, if you have instructions that are being relayed from an untrusted source, as is often the case with ReserveAssetDeposited, you can use ClearOrigin to prevent the original origin from being used to execute the instruction.

The following example appends the ReserveAssetDeposited and ClearOrigin instructions to an existing message:

let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin];
message.extend(xcm.0.into_iter());

DepositAsset

Subtracts the specified asset from the holding register and deposits on-chain equivalent assets under the ownership of the specified beneficiary. You must specify the assets to remove using the MultiAssetFilter type.

ParameterDescription
assetsSpecifies the asset to remove from the holding register.
max_assetsSpecifies the maximum number of unique assets or asset instances to remove from the holding register. Only the first max_assets number of unique assets or asset instances that match the assets specified are removed, prioritized under standard asset ordering. If there are any additional unique assets or asset instances, they will remain in the holding register.
beneficiarySpecifies the new owner of the assets.

The following example illustrates a simple message that includes a DepositAsset instruction:

ParaA::execute_with(|| {
        let message = Xcm(vec![
            WithdrawAsset((Here, send_amount).into()),
            buy_execution((Here, send_amount)),
            DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Parachain(2).into() },
        ]);
        // Send withdraw and deposit
        assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message.clone()));
    });

DepositReserveAsset

Removes the assets from the holding register and deposits on-chain equivalent assets into the sovereign account under the ownership of the destination. This instruction also sends a follow-up message to destination of the ReserveAssetDeposited instruction with the given effects.

ParameterDescription
assetsSpecifies the asset to remove from the holding register.
max_assetsSpecifies the maximum number of unique assets or asset instances to remove from the holding register. Only the first max_assets number of unique assets or asset instances that match the assets specified are removed, prioritized under standard asset ordering. If there are any additional unique assets or asset instances, they will remain in the holding register.
destinationSpecifies the location whose sovereign account will own the assets and thus the effective beneficiary for the assets and the notification target for the reserve asset deposit message.
xcmSpecifies additional instructions to execute on the destination location following the ReserveAssetDeposited instruction.

DescendOrigin

Changes the origin to some interior location within the context of the current value in the origin register.

ParameterDescription
interiorSpecifies an interior location to place in the origin register.

ExchangeAsset

Reduces assets in the holding register up to the amount specified by the give parameter and increases assets in the holding register with a minimum amount of alternative assets specified by the receive parameter.

ParameterDescription
giveSpecifies the assets to be removed from the holding register.
receiveSpecifies the assets to be increased in the holding register. Any fungible assets specified for the receive parameter can be increased by an amount greater than expressed, but the holding register can't accrue assets not stated in receive.

HrmpChannelAccepted

Sends a notification message that an open channel request has been accepted by the recipient. After sending this notification, the channel is opened when the relay chain session changes. This message should originate directly on the relay chains and is intended to be sent by the relay chain to a parachain.

ParameterDescription
recipientSpecifies the parachain identifier for the recipient parachain that has accepted the previous open-channel request.

HrmpChannelClosing

Sends a message to notify a recipient that the sender who initiated the request to open a channel has decided to close the channel. After sending this notification, the channel is closed when the relay chain session changes. This message should originate directly on the relay chains and is intended to be sent by the relay chain to a parachain.

ParameterDescription
initiatorSpecifies the parachain identifier for the parachain that initiated the channel close operation.
senderSpecifies the parachain identifier of the sender side of the channel being closed.
recipientSpecifies the parachain identifier of the receiver side of the channel being closed.

HrmpNewChannelOpenRequest

Sends a request from a parachain to the relay chain to open a new channel for communication with another parachain. Messages passed using the HRMP transport protocol are always routed through a relay chain. This message should originate directly on the relay chains and is intended to be sent by the relay chain to a parachain.

ParameterDescription
senderSpecifies the sender in the to-be opened channel. Also, the initiator of the channel opening.
max_message_sizeSpecifies the maximum size of a message proposed by the sender.
max_capacitySpecifies the maximum number of messages that can be queued in the channel.

InitiateReserveWithdraw

Reduces the value of the holding register by the assets and sends XCM instructions beginning with WithdrawAsset to a reserve location.

ParameterDescription
assetsSpecifies the assets to remove from the holding register.
reserveSpecifies a valid location that acts as a reserve for all specified assets. The sovereign account of this consensus system on the reserve location will have appropriate assets withdrawn and effects will be executed on them. There will typically be only one valid location on any given asset/chain combination.
xcmSpecifies additional instructions to execute on the assets after they are withdrawn on the reserve location.

InitiateTeleport

Removes the assets from the holding register and sends a message beginning with ReceiveTeleportedAsset instruction to a specified destination location.

NOTE: The destination location MUST respect the origin for the instruction as a valid teleportation origin for all assets. If it does not, then the assets may be lost.

ParameterDescription
assetsSpecifies the assets to remove from the holding register.
destinationSpecifies a valid location that respects teleports coming from this location.
xcmSpecifies additional instructions to execute on the destination location following the ReceiveTeleportedAsset instruction.

QueryHolding

Sends a QueryResponse message with the assets value equal to the holding contents, or a portion thereof.

ParameterDescription
query_idSpecifies the identifier for the query that is used for the query_id field of the QueryResponse message.
destinationSpecifies the location to where the QueryResponse message should be sent.
assetsSpecifies a filter for the assets that should be reported back.
max_response_weightSpecifies the value to be used for the max_weight field of the QueryResponse message.

The following example illustrates a QueryHolding instruction that returns a QueryResponse with the identifier query_id_set:

ParaA::execute_with(|| {
	let message = Xcm(vec![
			QueryHolding {
				query_id: query_id_set,
				dest: Parachain(1).into(),
				assets: All.into(),
				max_response_weight: 1_000_000_000,
			},
	]);
});

QueryResponse

Provides expected information from the origin.

ParameterDescription
query_idSpecifies the identifier for the query that resulted in this message being sent.

| response: Expresses the content of the message that resulted from the query instruction. | max_weight | Specifies the maximum weight that handling this response should take. If proper execution requires more weight than you specify, an error is returned. If the execution requires less than you specify, the difference might be added to the surplus weight register at run time.

The Response type is used to express information content in the QueryResponse XCM instruction. Depending on the query, it can represent the following different data types:

  • Null
  • Assets { assets: MultiAssets }
  • ExecutionResult { result: Result<(), (u32, Error)> }
  • Version { version: Compact }

The following example illustrates checking that a QueryResponse message was received and the information in the response is a newly deposited asset:

ParaA::execute_with(|| {
	assert_eq!(
			parachain::MsgQueue::received_dmp(),
			vec![Xcm(vec![QueryResponse {
					query_id: query_id_set,
					response: Response::Assets(MultiAssets::new()),
					max_weight: 1_000_000_000,
			}])],
	);
});

ReceiveTeleportedAsset

Accrues assets into the holding register equivalent to the assets removed from the current origin. The origin must be trusted to have removed the assets as a consequence of sending this message.

ParameterDescription
assetsSpecifies the assets that have been removed from the origin.

RefundSurplus

Increases the refunded weight register to the value of the surplus weight register. This instruction enables fees previously paid using the BuyExecution instruction to be moved into holding register to match the amount added to the refunded weight register.

ReportError

Reports the contents of the error register to the specified destination using XCM. A QueryResponse message of type ExecutionOutcome is sent to the destination with the given query_id and the outcome of the XCM.

ParameterDescription
query_idSpecifies the value to use for the query_id field of the QueryResponse message.
destinationSpecifies the location to where the QueryResponse message should be sent.
max_response_weightSpecifies the value to be used for the max_weight field of the QueryResponse message.

ReserveAssetDeposited

Adds derivative assets to the holding register to represent the assets received from the value in the origin register. The origin must be trusted to act as a reserve for the assets.

ParameterDescription
assetsSpecifies the assets that have been received into the sovereign account of the local consensus system on from †he origin.

SetAppendix

Sets the appendix register. The appendix register provides any code that should run after the current program completes execution. After the current program ends successfully, or after an error where the Error Handler is empty, the appendix register is cleared and its contents are used to replace the programme register. The estimated weight of this instruction must include the estimated weight of the appendix code. At run-time,the surplus weight register should be increased by the estimated weight of the appendix prior to being changed.

ParameterDescription
appendix: Xcm: The value to which to set the Appendix Register.

SetErrorHandler

Sets the error handler register. The error handler register provides any code that should run if the program encounters an error. After a program encounters an error, this register is cleared and its contents are used to replace the programme register. The estimated weight of this instruction must include the estimated weight of the error_handler code. At run-time, the surplus weight register should be increased by the estimated weight of the error handler prior to being changed.

ParameterDescription
error_handlerSpecifies the value to set in the error handler register.

SubscribeVersion

Sends a QueryResponse message to Origin specifying XCM version in the response field. Any upgrades to the local consensus that result in a later version of XCM being supported should elicit a similar response.

ParameterDescription
query_idSpecifies the value to be used for the query_id field of the QueryResponse message.
max_response_weightSpecifies the value to be used for the max_weight field of the QueryResponse message.

Transact

Dispatches the encoded call using the dispatch-origin for the call as expressed by the context you specify using the origin_type parameter.

ParameterDescription
origin_typeSpecifies a context for expressing the message origin as a dispatch origin.
max_weightSpecifies the maximum amount of weight to expend while dispatching the encoded call. If the dispatch requires more weight than you specify, execution stops and an error is returned. If the dispatch requires less than you specify, the difference might be added to the surplus weight register at run time.
callSpecifies the encoded transaction to execute on the receiving system.

TransferAsset

Withdraws assets from the ownership of Origin and deposit equivalent assets under the ownership of beneficiary.

ParameterDescription
assetsSpecifies the asset to be transferred.
beneficiarySpecifies the new owner for the assets.

TransferReserveAsset

Withdraws assets from the ownership of the current origin and deposits equivalent assets under the ownership of the sovereign account for the destination. This instruction also sends an additional message with ReserveAssetDeposited and any instructions specified with the xcm parameter to the specified destination.

ParameterDescription
assetsSpecifies the asset to be transferred.
destinationSpecifies the location whose sovereign account will own the assets and thus the effective beneficiary for the assets and the notification target for the reserve asset deposit message.
xcmSpecifies the instructions that should follow the ReserveAssetDeposited instruction, which is sent onwards to destination.

The following example illustrates using the TransferReserveAsset instruction that contains a message with two additional instructions:

let mut message = Xcm(vec![TransferReserveAsset {
    assets,
    dest,
    xcm: Xcm(vec![
        BuyExecution { fees, weight_limit: Unlimited },
        DepositAsset { assets: Wild(All), max_assets, beneficiary },
    ]),
}]);

Trap

Throws an error of type Trap.

ParameterDescription
idSpecifies the value to be used for the parameter of the thrown error.

UnsubscribeVersion

Cancels the effect of a previous SubscribeVersion instruction from Origin.

WithdrawAsset

Removes the specified assets from the sending account on the local consensus system and adds them to the value in the holding register.

ParameterDescription
assetsSpecifies the asset to remove from the sender. The asset must be owned by the must be owned by the account in the origin register.

Registers

Most XCVM registers can't be modified directly. They are set to specific values to start and are only be manipulated by specific instructions, under certain circumstances, or according to certain rules. The XCVM includes the following registers:

RegisterDescription
OriginStores the location for the authority the current program is running under.
HoldingStores the number of assets that exist under the control of the XCVM but have no on-chain representation.
Surplus weightStores the overestimation of weight previously calculated.
Refunded weightStores the portion of surplus weight that has been refunded.
ProgrammeStores the set of XCM instructions currently executing. This register holds the complete message—the program—in cross-consensus virtual machine.
Programme counterStores the instruction index for currently executing instruction. The value is incremented by one at the end of every successfully executed instruction. The register is reset to zero when the Programme register changes.
ErrorStores information about the last known error during program execution.
Error handlerStores code that should run if there's an error.
AppendixStores code that should run after the current program ends.

Origins

In some cases, you might want to manipulate the origin stored in the origin register to grant more or fewer permissions for performing specific operations or executing specific XCM instructions. You can use the following origin types to manipulate how the origin for XCM instructions is interpreted.

Origin typeDescription
NativeUse the native dispatch origin representation for the sender in the local runtime framework. For most chains, this is the Parachain or Relay origin if coming from a chain.
SovereignAccountUse the sovereign account of the sender. For most chains, this is the Signed origin.
SuperuserUse the superuser account. Normal account can't use this origin and in many cases it isn't available for any account to use. For most chains, this is the Root origin.
XcmUse the XCM native origin and the MultiLocation encoded directly in the dispatch origin unchanged. For most chains, this is the pallet_xcm::Origin::Xcm type.

The implications of using different origins depend on the code you are calling. Depending on your chain logic and permissions, you might not be able to generate the origin you want to use. For example, most users can't generate the Superuser origin, but it's possible for the chain logic to do so.

The following example illustrates specifying the origin type in a Transact instruction:

Transact {
	origin_type: OriginKind::SovereignAccount,
	require_weight_at_most: weight,
	call: call.encode().into(),
},

For additional examples of converting origins, see the origin_conversion module.

Errors

If the program executing XCM instructions encounters a problem, it stops execution and identifies the type of problem encountered with one of the following errors:

Error typeDescription
Overflow = 0An instruction caused an arithmetic overflow.
Unimplemented = 1The instruction is intentionally unsupported.
UntrustedReserveLocation = 2The origin register doesn't contain a valid value for a reserve transfer notification.
UntrustedTeleportLocation = 3The origin register doesn't contain a valid value for a teleport notification.
MultiLocationFull = 4The MultiLocation value too large to descend further.
MultiLocationNotInvertible = 5The MultiLocation value ascends more parents than the known number of ancestors of the local location.
BadOrigin = 6The origin register doesn't contain a valid value for executing the instruction.
InvalidLocation = 7The location parameter is not a valid value for the instruction.
AssetNotFound = 8The specified asset can't be found or isn't valid in the location specified for the instruction.
FailedToTransactAsset = 9An asset transaction—for example, an instruction to withdraw or deposit an asset—failed. In most cases, this type of error is caused by problems with type conversions.
NotWithdrawable = 10The specified asset can't be withdrawn, potentially due to lack of ownership, asset availability, or permissions.
LocationCannotHold = 11The specified asset can't be deposited under the ownership of a particular location.
ExceedsMaxMessageSize = 12There was an attempt to send a message that exceeded the maximum message size supported by the transport protocol.
DestinationUnsupported = 13There was an attempt to send a message that can't be translated into a format supported by the destination.
Transport = 14The destination is routable, but there's an issue with the transport mechanism.
Unroutable = 15The destination is known to be unroutable.
UnknownClaim = 16The claim specified for the ClaimAsset instruction isn't recognized or can't be found.
FailedToDecode = 17The function specified for the Transact instruction can't be decoded.
TooMuchWeightRequired = 18The function specified for the Transact instruction might exceed the weight limit allowed.
NotHoldingFees = 19The holding register doesn't contain any payable fees for the BuyExecution instruction to use.
TooExpensive = 20The fees declared to purchase weight in the BuyExecution instruction are insufficient.
Trap(u64) = 21Used by the Trap instruction to force an error intentionally. Its code is included.
ExpectationFalse = 22Used by ExpectAsset, ExpectError, and ExpectOrigin if the expectation was not true.

Concrete identifiers uniquely identify a single asset through its location in a consensus system relative to the context where an instruction is executed.