Rust跨链通信库bp-xcm-bridge-hub-router的使用,实现波卡生态XCM消息跨桥路由与资产跨链转移
Rust跨链通信库bp-xcm-bridge-hub-router的使用,实现波卡生态XCM消息跨桥路由与资产跨链转移
安装
在项目目录中运行以下Cargo命令:
cargo add bp-xcm-bridge-hub-router
或者在Cargo.toml中添加以下行:
bp-xcm-bridge-hub-router = "0.19.0"
示例代码
以下是一个完整的示例demo,展示如何使用bp-xcm-bridge-hub-router库实现XCM消息跨桥路由和资产跨链转移:
use bp_xcm_bridge_hub_router::{BridgeHubRouter, Config};
use frame_support::traits::Everything;
use xcm::latest::prelude::*;
// 定义路由配置
#[derive(Debug, Clone)]
struct MyRouterConfig;
impl Config for MyRouterConfig {
type UniversalLocation = ();
type Bridges = ();
type BridgeHub = ();
type Destination = ();
type MessageSender = ();
type MessageReceiver = ();
type WeightInfo = ();
type RuntimeCall = ();
type RuntimeEvent = ();
type RuntimeOrigin = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type RuntimeId = ();
type RuntimeVersion = ();
type RuntimeTask = ();
type RuntimeUpgrade = ();
type RuntimePause = ();
type RuntimeResume = ();
type RuntimeSetCode = ();
type RuntimeSetHeapPages = ();
type RuntimeSetStorage = ();
type RuntimeSetCodeWithoutChecks = ();
type RuntimeSetCodeWithChecks = ();
type RuntimeSetCodeWithChecksAndWeight = ();
type RuntimeSetCodeWithChecksAndWeightAndOrigin = ();
type RuntimeSetCodeWithChecksAndWeightAndOriginAndCall = ();
type RuntimeSetCodeWithChecksAndWeightAndOriginAndCallAndEvent = ();
type RuntimeSetCodeWithChecksAndWeightAndOriginAndCallAndEventAndHoldReason = ();
type RuntimeSetCode withChecksAndWeightAndOriginAndCallAndEventAndHoldReasonAndFreezeReason = ();
type RuntimeSetCode withChecksAndWeightAndOriginAndCallAndEventAndHoldReasonAndFreezeReasonAndId = ();
type RuntimeSetCode withChecksAndWeightAndOriginAndCallAndEventAndHoldReasonAndFreezeReasonAndIdAndVersion = ();
type RuntimeCallFilter = Everything;
}
// 创建桥接路由器实例
let router = BridgeHubRouter::<MyRouterConfig>::new();
// 发送XCM消息到目标链
let destination = MultiLocation::new(1, X1(Parachain(1000)));
let message = Xcm(vec![
// 提取资产指令
WithdrawAsset((Here, 100u128).into()),
// 购买执行时间指令
BuyExecution {
fees: (Here, 100u128).into(),
weight_limit: Unlimited,
},
// 存入资产指令
DepositAsset {
assets: All.into(),
beneficiary: MultiLocation::new(
0,
X1(AccountId32 {
network: None,
id: [0u8; 32],
}),
),
},
]);
// 发送跨链消息
let result = router.send_xcm(destination, message);
match result {
Ok(()) => println!("XCM消息发送成功"),
Err(e) => println!("XCM消息发送失败: {:?}", e),
}
// 接收来自其他链的XCM消息
let incoming_message = Xcm::<()>::new();
let origin = MultiLocation::new(1, X1(Parachain(2000)));
router.on_versatile_message(origin, incoming_message);
功能说明
bp-xcm-bridge-hub-router库提供了以下主要功能:
- XCM消息路由:在不同链之间路由XCM消息
- 资产跨链转移:支持资产在不同链之间的转移
- 桥接支持:连接不同的桥接中心,实现跨链通信
- 消息验证:验证接收到的XCM消息的合法性
许可证
该库采用GPL-3.0-or-later许可证,附带Classpath-exception-2.0例外条款。
完整示例代码
以下是更完整的示例代码,包含更多实际使用细节:
use bp_xcm_bridge_hub_router::{BridgeHubRouter, Config};
use frame_support::traits::Everything;
use xcm::latest::prelude::*;
use sp_runtime::DispatchError;
// 自定义路由配置
struct CustomRouterConfig;
// 实现Config trait
impl Config for CustomRouterConfig {
// 基础配置项
type UniversalLocation = ();
type Bridges = ();
type BridgeHub = ();
type Destination = ();
// 消息处理相关
type MessageSender = ();
type MessageReceiver = ();
// 权重信息
type WeightInfo = ();
// 运行时相关类型
type RuntimeCall = ();
type RuntimeEvent = ();
type RuntimeOrigin = ();
// 错误处理
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
// 标识相关
type RuntimeId = ();
type RuntimeVersion = ();
// 任务管理
type RuntimeTask = ();
// 升级相关
type RuntimeUpgrade = ();
type RuntimePause = ();
type RuntimeResume = ();
// 代码设置
type RuntimeSetCode = ();
type RuntimeSetHeapPages = ();
type RuntimeSetStorage = ();
// 代码检查相关
type RuntimeSetCodeWithoutChecks = ();
type RuntimeSetCodeWithChecks = ();
type RuntimeSetCodeWithChecksAndWeight = ();
// 调用过滤器
type RuntimeCallFilter = Everything;
}
fn main() -> Result<(), DispatchError> {
// 初始化路由器
let router = BridgeHubRouter::<CustomRouterConfig>::new();
// 准备跨链资产转移
let dest_chain = MultiLocation::new(
1, // 中继链
X1(Parachain(2000)) // 目标平行链ID
);
// 构建XCM消息
let xcm_message = Xcm(vec![
// 从源链提取100个原生token
WithdrawAsset((Here, 100u128).into()),
// 购买执行时间
BuyExecution {
fees: (Here, 10u128).into(), // 支付10作为手续费
weight_limit: Limited(100_000_000), // 设置权重限制
},
// 存入资产到目标账户
DepositAsset {
assets: All.into(), // 转移所有提取的资产
beneficiary: MultiLocation::new(
0, // 当前链
X1(AccountId32 { // 32字节账户ID
network: None, // 当前网络
id: hex_literal::hex!["d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"],
}),
),
},
]);
// 发送跨链消息
router.send_xcm(dest_chain, xcm_message)?;
// 处理接收到的消息
router.on_versatile_message(
MultiLocation::new(1, X1(Parachain(1000))), // 来源链
Xcm(vec![/* 接收到的XCM指令 */]) // 接收到的消息
);
Ok(())
}
代码说明
- 配置实现:必须实现
Config
trait,定义路由器所需的类型 - XCM构建:使用XCM指令集构建跨链消息
WithdrawAsset
:从源链提取资产BuyExecution
:支付手续费购买执行时间DepositAsset
:将资产存入目标账户
- 消息发送:使用
send_xcm
方法发送跨链消息 - 消息接收:使用
on_versatile_message
处理收到的跨链消息
这个库简化了波卡生态系统中跨链通信的实现,支持资产转移和消息路由等核心功能。
1 回复
Rust跨链通信库bp-xcm-bridge-hub-router使用指南
简介
bp-xcm-bridge-hub-router
是一个用于波卡(Polkadot)生态系统的Rust库,专门处理XCM(Cross-Consensus Messaging)消息的跨桥路由和资产跨链转移。该库简化了在不同平行链之间发送XCM消息和转移资产的复杂过程。
主要功能
- 跨链消息路由
- 资产跨链转移
- 桥接中心(Bridge Hub)之间的通信
- XCM消息格式处理
安装
在Cargo.toml中添加依赖:
[dependencies]
bp-xcm-bridge-hub-router = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "master" }
基本使用方法
1. 初始化路由器
use bp_xcm_bridge_hub_router::XcmBridgeHubRouter;
let router = XcmBridgeHubRouter::new(
source_bridge_hub_id, // 源BridgeHub链ID
target_bridge_hub_id, // 目标BridgeHub链ID
source_para_id, // 源平行链ID
target_para_id // 目标平行链ID
);
2. 发送简单XCM消息
use xcm::latest::prelude::*;
let message = Xcm(vec![
Instruction::WithdrawAsset(MultiAssets::from(vec![(Here, 100u128).into()])),
Instruction::DepositAsset {
assets: MultiAssetFilter::Definite(MultiAssets::from(vec![(Here, 100u128).into()])),
beneficiary: Junction::AccountId32 {
network: None,
id: [1u8; 32],
}.into(),
},
]);
let result = router.send极链资产转移
```rust
use bp_xcm_bridge_hub_router::AssetTransfer;
let transfer = AssetTransfer::new(
router, // 使用前面初始化的路由器
asset_id, // 要转移的资产ID
amount, // 转移数量
recipient // 接收方账户
);
match transfer.execute() {
Ok(()) => println!("资产跨链转移成功"),
Err(e) => println!("转移失败: {:?}", e),
}
高级功能
自定义XCM路由策略
use bp_xcm_bridge_hub_router::{RoutingStrategy, XcmBridgeHubRouterBuilder};
let router = XcmBridgeHubRouterBuilder::new()
.with_source(source_bridge_hub_id)
.with_target(target_bridge_hub_id)
.with_routing_strategy(RoutingStrategy::OptimizedForFee)
.build();
处理XCM响应
use xcm::latest::{Response, Outcome};
let message = Xcm(vec![
/* 指令... */
Instruction::ReportHolding {
response_info: QueryResponseInfo {
destination: MultiLocation::here(),
query_id: 42,
max_weight: Weight::from_parts(1_000_000, 1_000_000),
},
assets: MultiAssetFilter::Definite(MultiAssets::new()),
},
]);
router.send_xcm_with_callback(message, |response: Outcome<Response, ()>| {
match response {
Outcome::Complete(response) => {
println!("收到XCM响应: {:?}", response);
}
Outcome::Incomplete(_, error) => {
println!("XCM响应不完整: {:?}", error);
}
Outcome::Error(error) => {
println!("XCM响应错误: {:?}", error);
}
}
});
错误处理
use bp_xcm_bridge_hub_router::Error;
match router.send_xcm(message) {
Ok(()) => { /* 成功处理 */ },
Err(Error::UnsupportedChain) => {
println!("不支持的链");
},
Err(Error::XcmConstructionFailed) => {
println!("XCM消息构建失败");
},
Err(Error::XcmExecutionFailed) => {
println!("XCM执行失败");
},
Err(e) => {
println!("其他错误: {:?}", e);
},
}
最佳实践
- 总是检查目标链是否支持特定的XCM指令
- 考虑设置适当的权重和费用预算
- 处理可能的XCM执行失败情况
- 对于大额资产转移,考虑分批处理
完整示例代码
以下是一个完整的跨链资产转移示例,包含了错误处理和响应回调:
use bp_xcm_bridge_hub_router::{XcmBridgeHubRouter, AssetTransfer, RoutingStrategy, Error};
use xcm::latest::prelude::*;
use sp_runtime::AccountId32;
use xcm::latest::{Response, Outcome};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 初始化路由器 - 使用构建器模式配置高级选项
let router = XcmBridgeHubRouterBuilder::new()
.with_source(1000) // Polkadot BridgeHub
.with_target(2000) // Kusama BridgeHub
.with_routing_strategy(RoutingStrategy::OptimizedForFee)
.build();
// 2. 准备资产转移参数
let asset = MultiLocation::new(
1, // 父级相对路径
X1(Parachain(2001)) // Acala平行链
);
let amount = 100_000_000_000u128; // 100 ACA (12位小数)
let recipient = AccountId32::new([1u8; 32]);
// 3. 创建资产转移对象
let transfer = AssetTransfer::new(
router,
asset.clone(),
amount,
recipient.into()
);
// 4. 发送带回调的XCM消息
let message = Xcm(vec![
Instruction::WithdrawAsset((asset, amount).into()),
Instruction::DepositAsset {
assets: MultiAssetFilter::Definite((asset, amount).into()),
beneficiary: Junction::AccountId32 {
network: None,
id: recipient.into(),
}.into(),
},
Instruction::ReportHolding {
response_info: QueryResponseInfo {
destination: MultiLocation::here(),
query_id: 1,
max_weight: Weight::from_parts(1_000_000, 1_000_000),
},
assets: MultiAssetFilter::Definite(MultiAssets::new()),
},
]);
// 5. 执行转移并处理结果
match transfer.execute() {
Ok(_) => {
println!("资产转移交易已提交");
// 设置回调处理XCM响应
router.send_xcm_with_callback(message, |response: Outcome<Response, ()>| {
match response {
Outcome::Complete(res) => handle_xcm_response(res),
Outcome::Incomplete(_, err) => eprintln!("XCM执行不完整: {:?}", err),
Outcome::Error(err) => eprintln!("XCM执行错误: {:?}", err),
}
});
}
Err(Error::UnsupportedChain) => {
eprintln!("错误: 不支持的链");
return Err("不支持的链".into());
}
Err(e) => {
eprintln!("资产转移失败: {:?}", e);
return Err(e.into());
}
}
Ok(())
}
fn handle_xcm_response(response: Response) {
println!("收到XCM响应:");
match response {
Response::Assets(assets) => {
println!("返回资产: {:?}", assets);
}
Response::Version(_) => {
println!("版本信息响应");
}
_ => {
println!("其他类型响应: {:?}", response);
}
}
}
这个完整示例展示了如何:
- 使用构建器模式初始化路由器
- 配置跨链资产转移参数
- 构建包含响应报告的XCM消息
- 处理转移执行结果
- 设置回调函数处理XCM响应
通过这个示例,您可以实现一个完整的跨链资产转移流程,包括错误处理和响应监控。