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

关键功能说明

  1. 跨链消息路由:pallet-xcm-bridge-hub-router负责将XCM消息路由到正确的桥接目标链。

  2. 资产转移:通过WithdrawAsset/BuyExecution/DepositAsset指令组合实现跨链资产转移。

  3. 安全保证:提供消息确认和防重放机制,确保资产转移的安全性。

  4. 费用管理:处理跨链操作中的费用支付和执行权重限制。

注意事项

  • 使用前需要正确配置源链和目标链的UniversalLocation
  • 需要确保目标链支持相应的XCM指令
  • 跨链操作可能需要支付额外的桥接费用
  • 建议在生产环境使用前充分测试跨链交互

这个库是Polkadot生态系统的重要组成部分,为跨链互操作性提供了关键基础设施。通过合理配置和使用,可以实现安全高效的跨链资产转移和消息通信。


1 回复

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

简介

pallet-xcm-bridge-hub-router是一个用于Polkadot/Kusama生态系统的Substrate pallet,专门设计用于跨链通信(XCM)消息的桥接路由和安全资产转移。它作为XCM消息的中继路由器,允许不同平行链之间通过桥接中心(hub)进行通信和资产转移。

主要功能

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

安全注意事项

  1. 确保正确配置XCM执行器和障碍(Barrier)以防止恶意消息
  2. 设置适当的权重和费用机制防止DoS攻击
  3. 定期更新桥接路由表以反映网络拓扑变化
  4. 实施适当的错误处理和回滚机制

最佳实践

  1. 在测试网充分测试跨链交互
  2. 监控桥接中心的状态和消息队列
  3. 为跨链交易设置合理的gas限制和费用
  4. 考虑使用XCM的版本控制机制确保兼容性

通过pallet-xcm-bridge-hub-router,开发者可以构建复杂的跨链应用,实现资产和数据的无缝转移,同时保持高水平的安全性。

回到顶部