Интеграция с XCM (Polkadot)
XCM (Cross-Consensus Message Format) — язык для коммуникации между блокчейнами в Polkadot экосистеме. Не транспортный протокол, а именно язык: набор инструкций, описывающих что нужно сделать на удалённой цепи. XCM сообщение — это программа, которую получающая цепь интерпретирует и исполняет.
Это принципиально иная модель по сравнению с EVM bridge-ами. Там: lock on source, mint on destination. Здесь: sovereign account — у каждой parachain есть счёт на каждой другой цепи, и XCM может управлять этим счётом. Настоящий interoperability, не просто перенос токенов.
Polkadot архитектура: что нужно знать
Relay chain (Polkadot, Kusama) — центральный координатор. Обеспечивает shared security для подключённых parachain-ов. Сама relay chain не предназначена для приложений — только consensus и XCM routing.
Parachain — специализированный блокчейн, подключённый к relay chain через slot auction. Имеет собственную логику (runtime), разработанную с помощью Substrate/FRAME.
XCMP (Cross-Chain Message Passing) — транспортный механизм для передачи XCM сообщений между parachain-ами. Существуют также VMP (Vertical Message Passing): UMP (Upward, parachain → relay) и DMP (Downward, relay → parachain).
Sovereign account — ключевая концепция. Каждая цепь имеет детерминированный адрес на каждой другой цепи (вычисляется из chainId/paraId). XCM может управлять средствами на sovereign account — это основа cross-chain операций.
XCM instruction set
XCM V3 (актуальная версия) содержит набор инструкций. Наиболее используемые:
WithdrawAsset - снять активы с sovereign account отправителя
BuyExecution - купить execution time (оплата комиссий)
DepositAsset - зачислить активы на указанный счёт
TransferAsset - перевести активы напрямую
Transact - исполнить произвольный call на целевой цепи
ReportHolding - отчитаться об активах на holding register
SetErrorHandler - установить обработчик ошибок
XCM сообщение — последовательность инструкций, которая выполняется на виртуальной машине XCVM. У XCVM есть registers: holding (временное хранилище активов), origin, surplus weight и другие.
Типичное cross-chain transfer (DOT из Polkadot в Parachain)
// На Polkadot relay chain: отправить DOT на parachain 2000
let message = Xcm(vec![
WithdrawAsset((Here, 1_000_000_000_000u128).into()), // 1 DOT из sovereign account
BuyExecution {
fees: (Here, 100_000_000u128).into(), // оплата execution на dest
weight_limit: Limited(Weight::from_parts(1_000_000_000, 65536)),
},
DepositAsset {
assets: All.into(),
beneficiary: AccountId32 {
network: None,
id: recipient_account_id,
}.into(),
},
]);
// Отправка через pallet-xcm
pallet_xcm::Pallet::<T>::send_xcm(
Here, // origin
Parachain(2000).into(), // destination
message,
)?;
Это Rust код в Substrate runtime. Для frontend взаимодействия используется Polkadot.js API.
Multilocations: адресация в XCM
MultiLocation — универсальный способ указать адрес чего угодно (цепи, аккаунта, актива) в XCM. Состоит из parents (сколько уровней вверх подняться) и interior (путь вниз).
// Сама текущая цепь
MultiLocation { parents: 0, interior: Here }
// Relay chain (на один уровень выше)
MultiLocation { parents: 1, interior: Here }
// Parachain 2000 (через relay chain)
MultiLocation { parents: 1, interior: Parachain(2000) }
// Аккаунт на Parachain 2000
MultiLocation {
parents: 1,
interior: X2(Parachain(2000), AccountId32 { network: None, id: account_id })
}
// Актив (например, USDC на Statemint/Asset Hub)
MultiLocation {
parents: 1,
interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1337))
}
Неправильный MultiLocation — самая частая причина failed XCM. Активы и аккаунты должны быть адресованы корректно с точки зрения получающей цепи.
HRMP каналы: предварительное условие
Для передачи XCM между parachain-ами нужно открыть HRMP (Horizontal Relay-routed Message Passing) канал. Это двухстороннее: para A открывает запрос, para B принимает. Каждая операция — это XCM сообщение в relay chain через root origin.
В реальности открытие HRMP — governance операция: нужно пройти referendum на Polkadot, или если обе стороны используют sudo в тестовой среде — через sudo.
// Запрос на открытие HRMP канала (отправляется как XCM от para A в relay chain)
let open_request = Xcm(vec![
WithdrawAsset((Here, deposit_amount).into()),
BuyExecution { /* ... */ },
Transact {
origin_kind: OriginKind::Native,
require_weight_at_most: Weight::from_parts(1_000_000_000, 8000),
call: relay_chain::Call::Hrmp(
hrmp::Call::hrmp_init_open_channel {
recipient: para_b_id,
proposed_max_capacity: 8,
proposed_max_message_size: 1024,
}
).encode().into(),
},
]);
Asset registration и Asset Transactor
Перед тем как XCM может перемещать актив, цепь-получатель должна знать об этом активе — зарегистрировать его MultiLocation маппинг. На Asset Hub (Statemint) это делается через assets pallet. На кастомной parachain — через asset-registry или аналог.
Asset Transactor — компонент runtime который знает как обработать конкретный тип актива из XCM. Конфигурируется в xcm-executor:
pub type AssetTransactors = (
// Нативная валюта (parachain token)
CurrencyAdapter<Balances, IsConcrete<SelfReserve>, LocationToAccountId, AccountId, ()>,
// Fungible assets через pallet-assets
FungiblesAdapter<
Assets,
ConvertedConcreteId<AssetId, Balance, AsPrefixedGeneralIndex<AssetsPalletLocation, AssetId, JustTry>, JustTry>,
LocationToAccountId,
AccountId,
NoChecking,
CheckingAccount,
>,
);
Это Rust конфигурация xcm-executor — execution engine XCM на стороне runtime. Корректная конфигурация Asset Transactor определяет что parachain может принять через XCM.
xcm-executor: вес и barriers
XCM executor исполняет инструкции. Две критические конфигурации:
Barriers — фильтры, разрешающие или запрещающие исполнение XCM от разных источников:
pub type Barrier = (
TakeWeightCredit, // использовать вес из BuyExecution
AllowTopLevelPaidExecutionFrom<Everything>, // разрешить любой source, если оплачен вес
AllowKnownQueryResponses<PolkadotXcm>, // ответы на наши query
);
Weigher — оценка веса (gas в понятиях Substrate) для XCM инструкций. FixedWeightBounds — фиксированный вес на инструкцию. WeightInfoBounds — через benchmark данные. Занижение веса → execution limit exceeded, потеря активов.
Teleport vs Reserve Transfer
Два механизма cross-chain transfer активов:
Teleport — доверенный: актив уничтожается на source и создаётся на destination. Требует взаимного доверия: обе цепи должны считать друг друга trusted teleporters. Используется между relay chain и Asset Hub — они доверяют друг другу.
Reserve Transfer — через резерв: актив блокируется на reserve chain (где он нативен), на destination mintится производный актив. Sovereign account source chain на reserve chain хранит backing. Более универсальный механизм для цепей без взаимного доверия.
// Reserve transfer через pallet-xcm (Polkadot.js API совместимо)
pallet_xcm::Pallet::<T>::limited_reserve_transfer_assets(
origin,
dest: Box::new(destination.into()),
beneficiary: Box::new(beneficiary.into()),
assets: Box::new(assets.into()),
fee_asset_item: 0,
weight_limit: Unlimited,
)?;
Polkadot.js API: frontend интеграция
Для фронтенда используется @polkadot/api:
import { ApiPromise, WsProvider } from '@polkadot/api'
const wsProvider = new WsProvider('wss://rpc.polkadot.io')
const api = await ApiPromise.create({ provider: wsProvider })
// Отправить limited_reserve_transfer_assets
const tx = api.tx.xcmPallet.limitedReserveTransferAssets(
{ V3: destination },
{ V3: beneficiary },
{ V3: assets },
0, // feeAssetItem
'Unlimited'
)
await tx.signAndSend(senderAccount, ({ status }) => {
if (status.isInBlock) console.log('In block:', status.asInBlock.toString())
})
@polkadot/apps — открытый исходный код Polkadot.js Apps, хорошая отправная точка для понимания как строить XCM frontend. @paraspell/sdk — высокоуровневый SDK специально для XCM транзакций, скрывает сложность MultiLocation конфигурации.
Тестирование XCM
Chopsticks — инструмент для форка реальных Polkadot/Kusama сетей локально. Позволяет тестировать XCM между форками реальных parachain-ов без деплоя:
npx @acala-network/chopsticks xcm \
--relaychain=polkadot \
--parachain=acala \
--parachain=astar
XCM Emulator — xcm-emulator crate для тестирования XCM в Rust unit tests. Позволяет симулировать несколько цепей в одном тесте.
Rococo — публичная тестовая relay chain для Polkadot. Регистрация parachain slot — через Rococo faucet и governance.
Стек разработки
| Компонент | Технология |
|---|---|
| Runtime (parachain) | Substrate + FRAME + xcm-executor |
| XCM конфигурация | Rust + polkadot-sdk |
| Frontend | @polkadot/api + @paraspell/sdk |
| Тестирование | Chopsticks + xcm-emulator |
| Кошелёк | Polkadot.js Extension, SubWallet, Talisman |
Сроки
XCM интеграция в существующую parachain (добавить возможность отправлять/получать активы через XCM, HRMP конфигурация): 4-6 недель. Включает runtime конфигурацию xcm-executor, asset registration, тестирование через Chopsticks.
Разработка parachain с нуля с полной XCM поддержкой, custom Asset Transactor, несколькими HRMP каналами: 3-5 месяцев. Substrate разработка требует глубоких знаний Rust и FRAME.
XCM сложнее в отладке чем EVM — ошибки часто «тихие» (активы застревают на sovereign account). Тщательное тестирование через Chopsticks обязательно перед mainnet.







