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库提供了以下主要功能:

  1. XCM消息路由:在不同链之间路由XCM消息
  2. 资产跨链转移:支持资产在不同链之间的转移
  3. 桥接支持:连接不同的桥接中心,实现跨链通信
  4. 消息验证:验证接收到的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(())
}

代码说明

  1. 配置实现:必须实现Config trait,定义路由器所需的类型
  2. XCM构建:使用XCM指令集构建跨链消息
    • WithdrawAsset:从源链提取资产
    • BuyExecution:支付手续费购买执行时间
    • DepositAsset:将资产存入目标账户
  3. 消息发送:使用send_xcm方法发送跨链消息
  4. 消息接收:使用on_versatile_message处理收到的跨链消息

这个库简化了波卡生态系统中跨链通信的实现,支持资产转移和消息路由等核心功能。


1 回复

Rust跨链通信库bp-xcm-bridge-hub-router使用指南

简介

bp-xcm-bridge-hub-router是一个用于波卡(Polkadot)生态系统的Rust库,专门处理XCM(Cross-Consensus Messaging)消息的跨桥路由和资产跨链转移。该库简化了在不同平行链之间发送XCM消息和转移资产的复杂过程。

主要功能

  1. 跨链消息路由
  2. 资产跨链转移
  3. 桥接中心(Bridge Hub)之间的通信
  4. 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);
    },
}

最佳实践

  1. 总是检查目标链是否支持特定的XCM指令
  2. 考虑设置适当的权重和费用预算
  3. 处理可能的XCM执行失败情况
  4. 对于大额资产转移,考虑分批处理

完整示例代码

以下是一个完整的跨链资产转移示例,包含了错误处理和响应回调:

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);
        }
    }
}

这个完整示例展示了如何:

  1. 使用构建器模式初始化路由器
  2. 配置跨链资产转移参数
  3. 构建包含响应报告的XCM消息
  4. 处理转移执行结果
  5. 设置回调函数处理XCM响应

通过这个示例,您可以实现一个完整的跨链资产转移流程,包括错误处理和响应监控。

回到顶部