Skip to content

Multilocations

Introduction

A multilocation defines a specific point in the entire relay chain/parachain ecosystem relative to a given origin. It can be used to target a specific parachain, asset, account, or even a pallet inside a parachain.

Multilocations follow a hierarchical structure, in which some locations are encapsulated within others. For example, a relay chain encapsulates all of the parachains that are connected to it. Similarly, a parachain encapsulates all of the pallets, accounts, and assets that exist within it.

Hierarchy of multilocations

Defining a Multilocation

A multilocation contains two parameters:

  • parents - refers to how many "hops" up into a parent blockchain you need to take from a given origin. From the perspective of a parachain within the relay chain ecosystem, there can only be one parent, so the value for parents can only ever be 0 to represent the parachain or 1 to represent the relay chain. When defining universal locations that consider other consensus systems like Ethereum, parents can have higher values
  • interior - refers to how many fields you need to define the target point. From the relay chain, you can drill down to target a specific parachain, or account, asset, or pallet on that parachain. Since this downward movement can be more complex, Junctions are used to represent the steps needed to reach the target location and are defined by XN, where N is the number of Junctions required. If no Junctions are required to define the target point, its value would be Here as opposed to X1

For example,if you are targeting the relay chain specifically, you'll use Here since you aren't defining an account on the relay chain, a parachain, or a specific point within a parachain.

On the flip side, if you're targeting an account on the relay chain, or a parachain, or a specific point within a parachain, you'll use one or more Junctions, as needed.

Junctions

A Junction can be any of the following:

  • Parachain - describes a parachain using the parachain's ID

    { Parachain: INSERT_PARACHAIN_ID }
    
  • AccountId32 - describes a 32-byte Substrate-style account. Accepts an optional network parameter, which can be one of the following: Any, Named, Polkadot, or Kusama

    { AccountId32: { id: INSERT_ADDRESS, network: INSERT_NETWORK } }
    
  • AccountIndex64 - describes a 64-bit (8-byte) index for an account. Accepts an optional network parameter, which can be one of the following: Any, Named, Polkadot, or Kusama

    { AccountIndex64: { index: INSERT_ACCOUNT_INDEX, network: INSERT_NETWORK } }
    
  • AccountKey20 - describes a 20-byte Ethereum-style account, as is used in Moonbeam. Accepts an optional network parameter, which can be one of the following: Any, Named, Polkadot, or Kusama

    { AccountKey20: { key: INSERT_ADDRESS, network: INSERT_NETWORK } }
    
  • PalletInstance - describes the index of a pallet on the target chain

    { PalletInstance: INSERT_PALLET_INSTANCE_INDEX }
    
  • GeneralIndex - describes a nondescript index that can be used to target data stored in a key-value format

    { GeneralIndex: INSERT_GENERAL_INDEX }
    
  • GeneralKey - describes a nondescript key that can be used to target more complex data structures. This requires you to specify the data and the length of the data

    { GeneralKey: { length: INSERT_LENGTH_OF_DATA, data: [INSERT_DATA] } }
    
  • OnlyChild - describes the child of a location if there is only a one-to-one relation between the parent and child. This is currently not used except as a fallback when deriving context

  • Plurality - describes multiple elements that meet specific conditions or share common characteristics. This requires you to specify the Body ID and the Body Part that the Junction represents

    { Plurality: { id: INSERT_BODY_ID, part: INSERT_BODY_PART } }
    

When using Junctions, you'll use XN, where N is the number of Junctions required to reach the target location. For example, if you're targeting an account on Moonbeam from a parachain, parents needs to be set to 1, and you'll need to define two Junctions, the Parachain and the AccountKey20, so you'll use X2, which is an array that will contain each Junction:

{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 2004 },
      { AccountKey20: { key: 'INSERT_MOONBEAM_ADDRESS' } },
    ],
  },
};

Example Multilocations

Target Moonbeam from Another Parachain

To target a Moonbeam-based chain from another parachain, you would use the following multilocation:

{
  parents: 1,
  interior: {
    X1: [{ Parachain: 2004 }],
  },
};
{
  parents: 1,
  interior: {
    X1: [{ Parachain: 2023 }],
  },
};
{
  parents: 1,
  interior: {
    X1: [{ Parachain: 1000 }],
  },
};

Target an Account on Moonbeam from Another Parachain

To target a specific account on a Moonbeam-based chain from another parachain, you would use the following multilocation:

{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 2004 },
      { AccountKey20: { key: 'INSERT_MOONBEAM_ADDRESS' } },
    ],
  },
};
{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 2023 },
      { AccountKey20: { key: 'INSERT_MOONBEAM_ADDRESS' } },
    ],
  },
};
{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 1000 },
      { AccountKey20: { key: 'INSERT_MOONBEAM_ADDRESS' } },
    ],
  },
};

Target Moonbeam's Native Asset from Another Parachain

To target the native asset of a Moonbeam-based chain from another parachain, you would use the following multilocation:

{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 2004 },
      { PalletInstance: 10 }, // Index of the Balances Pallet on Moonbeam
    ],
  },
};
{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 2023 },
      { PalletInstance: 10 }, // Index of the Balances Pallet on Moonriver
    ],
  },
};
{
  parents: 1,
  interior: {
    X2: [
      { Parachain: 1000 },
      { PalletInstance: 3 }, // Index of the Balances Pallet on Moonbase Alpha
    ],
  },
};

Target Moonbeam from the Relay Chain

To target a Moonbeam-based chain from the relay chain, you would use the following multilocation:

{
  parents: 0,
  interior: {
    X1: [{ Parachain: 2004 }],
  },
};
{
  parents: 0,
  interior: {
    X1: [{ Parachain: 2023 }],
  },
};
{
  parents: 0,
  interior: {
    X1: [{ Parachain: 1000 }],
  },
};

Target the Relay Chain from Moonbeam

To target the relay chain from a Moonbeam-based chain, you would use the following multilocation:

{
  parents: 1,
  interior: Here,
};
{
  parents: 1,
  interior: Here,
};
{
  parents: 1,
  interior: Here,
};

Target an Account on the Relay Chain from Moonbeam

To target a specific account on the relay chain, you would use the following multilocation:

{
  parents: 1,
  interior: { X1: { AccountId32: { id: INSERT_RELAY_ADDRESS } } },
};
{
  parents: 1,
  interior: { X1: { AccountId32: { id: INSERT_RELAY_ADDRESS } } },
};
{
  parents: 1,
  interior: { X1: { AccountId32: { id: INSERT_RELAY_ADDRESS } } },
};

Target Another Parachain from Moonbeam

To target another parachain (for example, a parachain that has an ID of 1234) from Moonbeam, you would use the following multilocation:

{
  parents: 1,
  interior: {
    X1: [{ Parachain: 1234 }],
  },
};
{
  parents: 1,
  interior: {
    X1: [{ Parachain: 1234 }],
  },
};
{
  parents: 1,
  interior: {
    X1: [{ Parachain: 1234 }],
  },
};
Last update: January 25, 2024
| Created: October 28, 2023