Rust跨链通信库pallet-xcm-bridge-hub-router的使用:实现XCM消息跨桥接路由和资产安全转移
Rust跨链通信库pallet-xcm-bridge-hub-router的使用:实现XCM消息跨桥接路由和资产安全转移
安装
在项目目录中运行以下Cargo命令:
cargo add pallet-xcm-bridge-hub-router
或者将以下行添加到您的Cargo.toml中:
pallet-xcm-bridge-hub-router = "0.19.0"
基本使用示例
pallet-xcm-bridge-hub-router是一个用于Polkadot生态系统的跨链消息(XCM)桥接路由库。以下是基本使用示例:
// 引入必要的模块
use frame_support::traits::Everything;
use pallet_xcm_bridge_hub_router::{Config, WeightInfo};
use xcm::latest::prelude::*;
// 配置桥接路由器
pub struct BridgeHubRouterConfig;
impl Config for BridgeHubRouterConfig {
type RuntimeEvent = RuntimeEvent;
type UniversalLocation = UniversalLocation;
type BridgedNetworkId = BridgedNetworkId;
type Bridges = ();
type WeightInfo = ();
type MessageExportPrice = ();
type DestinationVersion = ();
type MaxUnrewardedRelayerEntries = ConstU32<32>;
type MaxUnconfirmedMessages = ConstU32<32>;
}
// 发送XCM消息到桥接目标链
fn send_xcm_message_to_bridged_chain() {
let dest = MultiLocation::new(
1,
X1(Parachain(1000)) // 目标链的ParaId
);
let message = Xcm::<()>(vec![
Instruction::WithdrawAsset(MMultiAssets::new()),
Instruction::BuyExecution {
fees: MultiAssets::new(),
weight_limit: Unlimited,
},
Instruction::DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: MultiLocation::new(
0,
X1(AccountId32 {
network: None,
id: [0u8; 32],
}),
),
},
]);
// 通过桥接路由器发送消息
pallet_xcm_bridge_hub_router::Pallet::<Runtime>::send_message(
dest,
message,
);
}
完整示例代码
以下是一个更完整的示例,展示如何配置和使用pallet-xcm-bridge-hub-router实现跨链资产转移:
use frame_support::{
parameter_types,
traits::{ConstU32, Everything, OriginTrait},
};
use pallet_xcm_bridge_hub_router::{Config, WeightInfo};
use sp_runtime::traits::AccountIdConversion;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds,
LocationInverter, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
};
// 定义一些参数类型
parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
pub const RelayNetwork: NetworkId = NetworkId::Any;
pub const MaxInstructions: u32 = 100;
pub const BaseXcmWeight: u64 = 1_000;
pub const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(100));
}
// 桥接路由器配置
pub struct XcmBridgeHubRouterConfig;
impl Config for XcmBridgeHubRouterConfig {
type RuntimeEvent = RuntimeEvent;
type UniversalLocation = UniversalLocation;
type BridgedNetworkId = NetworkId;
type Bridges = ();
type WeightInfo = ();
type MessageExportPrice = ();
type DestinationVersion = ();
type MaxUnrewardedRelayerEntries = ConstU32<32>;
type MaxUnconfirmedMessages = ConstU32<32>;
}
// 资产转移函数
pub fn transfer_asset_to_bridged_chain(
dest: MultiLocation,
beneficiary: MultiLocation,
asset: MultiAsset,
amount: u128,
) -> Result<(), &'static str> {
let message = Xcm(vec![
WithdrawAsset(asset.clone().into()),
BuyExecution {
fees: asset.clone().into(),
weight_limit: Unlimited,
},
DepositAsset {
assets: asset.into(),
max_assets: 1,
beneficiary,
},
]);
// 通过桥接路由器发送XCM消息
pallet_xcm_bridge_hub_router::Pallet::<Runtime>::send_message(
dest,
message,
).map_err(|_| "Failed to send XCM message")?;
Ok(())
}
// 示例调用
fn example_usage() {
let dest_chain = MultiLocation::new(
1,
X1(Parachain(2000)) // 目标链ParaId
);
let beneficiary = MultiLocation::new(
0,
X1(AccountId32 {
network: None,
id: [1u8; 32], // 目标账户
}),
);
let asset = MultiAsset {
id: Concrete(MultiLocation::here()),
fun: Fungible(100u128), // 转账金额
};
transfer_asset_to_bridged_chain(dest_chain, beneficiary, asset, 100)
.expect("Failed to transfer asset");
}
关键功能说明
-
跨链消息路由:pallet-xcm-bridge-hub-router负责将XCM消息路由到正确的桥接目标链。
-
资产转移:通过WithdrawAsset/BuyExecution/DepositAsset指令组合实现跨链资产转移。
-
安全保证:提供消息确认和防重放机制,确保资产转移的安全性。
-
费用管理:处理跨链操作中的费用支付和执行权重限制。
注意事项
- 使用前需要正确配置源链和目标链的UniversalLocation
- 需要确保目标链支持相应的XCM指令
- 跨链操作可能需要支付额外的桥接费用
- 建议在生产环境使用前充分测试跨链交互
这个库是Polkadot生态系统的重要组成部分,为跨链互操作性提供了关键基础设施。通过合理配置和使用,可以实现安全高效的跨链资产转移和消息通信。
Rust跨链通信库pallet-xcm-bridge-hub-router使用指南
简介
pallet-xcm-bridge-hub-router
是一个用于Polkadot/Kusama生态系统的Substrate pallet,专门设计用于跨链通信(XCM)消息的桥接路由和安全资产转移。它作为XCM消息的中继路由器,允许不同平行链之间通过桥接中心(hub)进行通信和资产转移。
主要功能
- 跨链消息路由
- 资产安全转移
- 桥接中心间的通信
- XCM消息验证和转发
使用方法
1. 添加依赖
首先需要在runtime的Cargo.toml
中添加依赖:
[dependencies.pallet-xcm-bridge-hub-router]
default-features = false
git = 'https://github.com/paritytech/polkadot'
branch = 'master'
2. 配置runtime
在runtime中配置该pallet:
impl pallet_xcm_bridge_hub_router::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = xcm_executor::XcmExecutor<xcm_config::XcmConfig>;
type UniversalLocation = xcm_config::UniversalLocation;
type BridgedNetworkId = xcm_config::BridgedNetworkId;
type Bridges = xcm_config::Bridges;
type BridgeHubRouter = xcm_config::BridgeHubRouter;
}
3. 在construct_runtime!宏中添加
construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
// ... 其他pallet
XcmBridgeHubRouter: pallet_xcm_bridge_hub_router,
}
);
使用示例
1. 发送跨链XCM消息
use xcm::latest::prelude::*;
let message = Xcm(vec![
WithdrawAsset((Here, 100u128).into()),
BuyExecution {
fees: (Here, 100u128).into(),
weight_limit: Unlimited
},
DepositAsset {
assets: All.into(),
beneficiary: Junction::AccountId32 {
network: None,
id: ALICE.into()
}.into()
},
]);
pallet_xcm_bridge_hub_router::Pallet::<Runtime>::send_xcm(
Origin::signed(ALICE),
Parachain(2000).into(),
message
).unwrap();
2. 接收并处理XCM消息
在目标链上,需要配置XCM执行器来处理接收到的消息:
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter;
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = NativeAsset;
type IsTeleporter = ();
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type Trader = FixedRateOfFungible<WeightPrice, ()>;
type ResponseHandler = ();
type AssetTrap = ();
type AssetClaims = ();
type SubscriptionService = ();
}
3. 资产跨链转移
use xcm::latest::prelude::*;
let transfer_asset = MultiAsset {
id: Concrete(Here.into()),
fun Fungible(100u128),
};
let message = Xcm(vec![
ReserveAssetDeposited(vec![transfer_asset].into()),
ClearOrigin,
BuyExecution {
fees: (Here, 10u128).into(),
weight_limit: Unlimited
},
DepositAsset {
assets: All.into(),
beneficiary: Junction::AccountId32 {
network: None,
id: BOB.into()
}.into()
},
]);
pallet_xcm_bridge_hub_router::Pallet::<Runtime>::transfer_assets(
Origin::signed(ALICE),
Box::new(Parachain(2000).into()),
Box::new(Junction::AccountId32 {
network: None,
id: BOB.into()
}.into()),
Box::new(vec![transfer_asset].into()),
0,
Unlimited,
).unwrap();
完整示例demo
下面是一个完整的跨链资产转移示例,包含发送方和接收方的配置:
// 发送方链runtime配置
pub struct SenderRuntime;
impl pallet_xcm_bridge_hub_router::Config for SenderRuntime {
type RuntimeEvent = Event;
type XcmExecutor = xcm_executor::XcmExecutor<XcmConfig>;
type UniversalLocation = UniversalLocation;
type BridgedNetworkId = BridgedNetworkId;
type Bridges = Bridges;
type BridgeHubRouter = BridgeHubRouter;
}
// 接收方链runtime配置
pub struct ReceiverRuntime;
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = Call;
type XcmSender = XcmRouter;
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = NativeAsset;
type IsTeleporter = ();
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
type Trader = FixedRateOfFungible<WeightPrice, ()>;
type ResponseHandler = ();
type AssetTrap = ();
type AssetClaims = ();
type SubscriptionService = ();
}
// 跨链资产转移函数
fn transfer_assets_between_chains() {
// 发送方构建XCM消息
let message = Xcm(vec![
WithdrawAsset((Here, 100u128).into()),
BuyExecution {
fees: (Here, 10u128).into(),
weight_limit: Unlimited
},
DepositAsset {
assets: All.into(),
beneficiary: Junction::AccountId32 {
network: None,
id: BOB.into()
}.into()
},
]);
// 通过桥接路由器发送XCM消息
pallet_xcm_bridge_hub_router::Pallet::<SenderRuntime>::send_xcm(
Origin::signed(ALICE),
Parachain(2000).into(), // 目标链ID
message
).expect("Failed to send XCM message");
}
安全注意事项
- 确保正确配置XCM执行器和障碍(Barrier)以防止恶意消息
- 设置适当的权重和费用机制防止DoS攻击
- 定期更新桥接路由表以反映网络拓扑变化
- 实施适当的错误处理和回滚机制
最佳实践
- 在测试网充分测试跨链交互
- 监控桥接中心的状态和消息队列
- 为跨链交易设置合理的gas限制和费用
- 考虑使用XCM的版本控制机制确保兼容性
通过pallet-xcm-bridge-hub-router
,开发者可以构建复杂的跨链应用,实现资产和数据的无缝转移,同时保持高水平的安全性。