Rust区块链开发库parachains-common的使用:支持Polkadot和Substrate的平行链通用功能模块

Rust区块链开发库parachains-common的使用:支持Polkadot和Substrate的平行链通用功能模块

安装

在项目目录中运行以下Cargo命令:

cargo add parachains-common

或者在Cargo.toml中添加以下行:

parachains_common = "23.0.0"

基本信息

  • 版本: 23.0.0
  • 许可证: Apache-2.0
  • 大小: 49.2 KiB
  • 发布时间: 1天前

示例代码

以下是一个使用parachains-common库的基本示例:

use parachains_common::{AccountId, Balance, BlockNumber};
use sp_runtime::traits::{BlakeTwo256, Hash};
use frame_support::parameter_types;

// 定义平行链的基本参数
parameter_types! {
    pub const BlockHashCount: BlockNumber = 250;
    pub const MaximumBlockWeight: u32 = 1024;
    pub const MaximumBlockLength: u32 = 2 * 1024;
    pub const AvailableBlockRatio: (u8, u8) = (4, 5);
}

// 创建平行链配置
pub struct Runtime;
impl parachains_common::Config for Runtime {
    type AccountId = AccountId;
    type Balance = Balance;
    type BlockNumber = BlockNumber;
    type Hash = sp_core::H256;
    type Hashing = BlakeTwo256;
    
    // 使用参数类型
    type BlockHashCount = BlockHashCount;
    type MaximumBlockWeight = MaximumBlockWeight;
    type MaximumBlockLength = MaximumBlockLength;
    type AvailableBlockRatio = AvailableBlockRatio;
}

fn main() {
    // 初始化平行链运行时
    let runtime = Runtime;
    
    // 在此处可以添加平行链特定的逻辑
    println!("平行链运行时已初始化");
}

完整示例demo

以下是基于parachains-common构建的完整平行链示例:

// 引入必要的库和模块
use parachains_common::{AccountId, Balance, BlockNumber};
use sp_runtime::{
    traits::{BlakeTwo256, Hash},
    Permill
};
use frame_support::{
    parameter_types,
    traits::{ConstU32, ConstU64},
};
use sp_core::H256;

// 定义平行链参数
parameter_types! {
    pub const Version: &'static str = "1.0";
    pub const BlockHashCount: BlockNumber = 250;
    pub const MaximumBlockWeight: u32 = 1024;
    pub const MaximumBlockLength: u32 = 2 * 1024;
    pub const AvailableBlockRatio: Permill = Permill::from_percent(80);
    pub const MinimumPeriod: u64 = 5000;
}

// 定义Runtime结构体
pub struct Runtime;

// 实现parachains_common的Config trait
impl parachains_common::Config for Runtime {
    type AccountId = AccountId;
    type Balance = Balance;
    type BlockNumber = BlockNumber;
    type Hash = H256;
    type Hashing = BlakeTwo256;
    
    type BlockHashCount = BlockHashCount;
    type MaximumBlockWeight = ConstU32<1024>;
    type MaximumBlockLength = ConstU32<2 * 1024>;
    type AvailableBlockRatio = AvailableBlockRatio;
    type MinimumPeriod = ConstU64<5000>;
}

// 平行链模块实现
mod pallet_parallel {
    use super::*;
    
    // 平行链存储项
    #[frame_support::pallet]
    pub mod pallet {
        use frame_support::pallet_prelude::*;
        
        #[pallet::config]
        pub trait Config: parachains_common::Config {}
        
        #[pallet::pallet]
        pub struct Pallet<T>(_);
    }
}

// 主函数
fn main() {
    // 初始化运行时
    let runtime = Runtime;
    
    // 模拟区块生成
    println!("开始生成平行链区块...");
    
    // 模拟交易处理
    for i in 1..=5 {
        println!("处理区块 {} 中的交易", i);
        // 这里可以添加实际的交易处理逻辑
    }
    
    println!("平行链运行完成");
}

功能说明

parachains-common库提供了以下主要功能:

  1. 基本类型定义:如AccountId、Balance、BlockNumber等
  2. 哈希算法支持:如BlakeTwo256
  3. 平行链配置:通过Config trait实现
  4. 参数类型:用于定义平行链运行时参数

这个库是构建Polkadot和Substrate平行链的基础组件,提供了许多通用功能模块,开发者可以在此基础上构建自己的平行链特定逻辑。


1 回复

以下是根据提供的内容整理的完整示例demo,先展示内容中的示例,然后给出扩展的完整实现:

内容中提供的示例代码

1. 集成平行链运行时

use parachains_common::{AccountId, Balance, BlockNumber};

pub type BlockNumber = parachains_common::BlockNumber;
pub type Balance = parachains_common::Balance;
pub type AccountId = parachains_common::AccountId;

#[frame_support::pallet]
pub mod pallet_my_parachain {
    use super::*;
    use frame_support::pallet_prelude::*;
    use parachains_common::{
        impls::CurrencyToVoteHandler,
        traits::Currency,
    };
    
    // 你的平行链pallet实现...
}

2. 使用XCMP功能

use parachains_common::{
    xcm::{
        prelude::*,
        v2::{Junction, NetworkId, MultiLocation},
    },
    xcm_sender::XcmSender,
};

fn send_xcm_message() {
    let dest = MultiLocation::new(
        1,
        X1(Junction::Parachain(2000)) // 目标平行链ID
    );
    
    let message = Xcm(vec![
        WithdrawAsset((Here, 100u128).into()),
        DepositAsset {
            assets: All.into(),
            max_assets: 1,
            beneficiary: MultiLocation::new(
                0,
                X1(Junction::AccountId32 {
                    network: NetworkId::Any,
                    id: [0u8; 32],
                }),
            ),
        },
    ]);
    
    XcmSender::<T>::send_xcm(dest, message).unwrap();
}

完整示例demo

完整平行链运行时集成示例

use frame_support::{parameter_types, traits::Everything};
use parachains_common::{AccountId, Balance, BlockNumber};
use sp_runtime::traits::IdentifyAccount;

// 类型别名保持与生态系统兼容
pub type BlockNumber = parachains_common::BlockNumber;
pub type Balance = parachains_common::Balance;
pub type AccountId = parachains_common::AccountId;
pub type Signature = sp_runtime::MultiSignature;
pub type AccountPublic = <Signature as sp_runtime::traits::Verify>::Signer;

parameter_types! {
    pub const BlockHashCount: BlockNumber = 2400;
    pub const SS58Prefix: u8 = 42;
}

impl frame_system::Config for Runtime {
    type BaseCallFilter = Everything;
    type BlockWeights = ();
    type BlockLength = ();
    type RuntimeOrigin = RuntimeOrigin;
    type RuntimeCall = RuntimeCall;
    type Index = u64;
    type BlockNumber = BlockNumber;
    type Hash = sp_core::H256;
    type Hashing = sp_runtime::traits::BlakeTwo256;
    type AccountId = AccountId;
    type Lookup = sp_runtime::traits::AccountIdLookup<AccountId, ()>;
    type RuntimeEvent = RuntimeEvent;
    type BlockHashCount = BlockHashCount;
    type DbWeight = ();
    type Version = ();
    type PalletInfo = PalletInfo;
    type AccountData = pallet_balances::AccountData<Balance>;
    type OnNewAccount = ();
    type OnKilledAccount = ();
    type SystemWeightInfo = ();
    type SS58Prefix = SS58Prefix;
    type OnSetCode = ();
    type MaxConsumers = frame_support::traits::ConstU32<16>;
}

#[frame_support::pallet]
pub mod pallet_my_parachain {
    use super::*;
    use frame_support::{pallet_prelude::*, traits::Currency};
    use parachains_common::impls::CurrencyToVoteHandler;
    
    #[pallet::pallet]
    pub struct Pallet<T>(_);
    
    #[pallet::config]
    pub trait Config: frame_system::Config {
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
        type Currency: Currency<Self::AccountId>;
    }
    
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        SomethingHappened { who: T::AccountId, amount: Balance },
    }
    
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::weight(10_000)]
        pub fn do_something(origin: OriginFor<T>, amount: Balance) -> DispatchResult {
            let who = ensure_signed(origin)?;
            Self::deposit_event(Event::SomethingHappened { who, amount });
            Ok(())
        }
    }
}

完整XCMP实现示例

use parachains_common::{
    xcm::{
        prelude::*,
        v2::{Junction, NetworkId, MultiLocation, WeightLimit},
    },
    xcm_sender::XcmSender,
    ParaId,
};

// 发送XCM消息的完整实现
pub fn send_asset_to_parachain(
    dest_para_id: ParaId,
    recipient: [u8; 32],
    amount: u128,
) -> Result<(), XcmError> {
    // 构建目标位置 (目标平行链)
    let dest = MultiLocation::new(
        1,  // 父级(中继链)
        X1(Junction::Parachain(dest_para_id.into())) 
    );
    
    // 构建接收者位置
    let beneficiary = MultiLocation::new(
        0,  // 当前链
        X1(Junction::AccountId32 {
            network: NetworkId::Any,
            id: recipient,
        })
    );
    
    // 构建XCM消息指令
    let message = Xcm(vec![
        // 从发送者账户提取资产
        WithdrawAsset((Here, amount).into()),
        // 初始化XCM手续费支付
        BuyExecution {
            fees: (Here, amount).into(),
            weight_limit: WeightLimit::Unlimited,
        },
        // 将资产存入目标账户
        DepositAsset {
            assets: All.into(),
            max_assets: 1,
            beneficiary,
        },
    ]);
    
    // 发送XCM消息
    XcmSender::<T>::send_xcm(dest, message)
}

// 接收XCM消息的配置
pub struct XcmConfig;

impl xcm_executor::Config for XcmConfig {
    type RuntimeCall = RuntimeCall;
    type XcmSender = XcmSender;
    type AssetTransactor = (); // 资产转换器实现
    type OriginConverter = (); // 来源转换器实现
    type IsReserve = (); // 储备资产检查
    type IsTeleporter = (); // 传送资产检查
    type LocationInverter = (); // 位置转换
    type Barrier = (); // 屏障检查
    type Weigher = (); // 权重计算
    type Trader = (); // 手续费处理
    type ResponseHandler = (); // 响应处理
    type AssetTrap = (); // 资产陷阱
    type AssetClaims = (); // 资产声明
    type SubscriptionService = (); // 订阅服务
}

完整共识配置示例

use parachains_common::{
    consensus::{Aura, SlotDuration},
    runtime_api::RuntimeApi,
};
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
use sp_consensus_aura::sr25519::AuthorityId;

pub fn aura_consensus(
    import_queue: Box<dyn sp_consensus::ImportQueue<Block>>,
    slot_duration: SlotDuration,
    can_author_with: sp_consensus::CanAuthorWith<Block>,
    block_import: Box<dyn sp_consensus::BlockImport<Block>>,
    sync_oracle: Box<dyn sc_network_sync::SyncOracle>,
) -> sc_service::error::Result<()> {
    let aura = Aura::new(slot_duration);
    
    let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuthorityId>(
        ImportQueueParams {
            block_import,
            justification_import: None,
            can_author_with,
            slot_duration,
            create_inherent_data_providers: move |_, ()| async move {
                Ok(())
            },
            spawner: Box::new(|fut| {
                tokio::spawn(fut);
            }),
            registry: None,
            check_for_equivocation: Default::default(),
            telemetry: None,
        },
    )?;

    let start_aura = StartAuraParams {
        slot_duration,
        client: Arc::new(client),
        block_import,
        sync_oracle,
        proposer_factory,
        create_inherent_data_providers: move |_, ()| async move {
            Ok(())
        },
        force_authoring: false,
        backoff_authoring_blocks: Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default()),
        keystore: keystore_container.sync_keystore(),
        can_author_with,
        slot_proportion: SlotProportion::new(0.5),
        telemetry: None,
    };

    sc_consensus_aura::start_aura::<_, _, _, _, _, AuthorityId>(start_aura)?;
    
    Ok(())
}

这些完整示例展示了如何在实际项目中使用parachains-common库的核心功能,包括运行时集成、XCMP通信和共识配置。

回到顶部