Rust NIS模块pallet-nis的使用:Substrate区块链框架中的非交互式质押与治理功能库
Rust NIS模块pallet-nis的使用:Substrate区块链框架中的非交互式质押与治理功能库
NIS模块
提供了一种非交互式的质押变体。
许可证: Apache-2.0
元数据
- 版本: 42.0.0
- 发布时间: 约17小时前
- 2021版本
- 大小: 45 KiB
安装
在你的项目目录中运行以下Cargo命令:
cargo add pallet-nis
或者在你的Cargo.toml中添加以下行:
pallet-nis = "42.0.0"
完整示例代码
// 引入必要的依赖
use frame_support::{decl_module, decl_event, decl_storage, dispatch::DispatchResult};
use frame_system::ensure_signed;
// 定义NIS模块
pub trait Trait: frame_system::Trait {
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>;
}
// 定义存储项
decl_storage! {
trait Store for Module<T: Trait> as Nis {
// 存储质押总额
pub TotalStake get(fn total_stake): u64;
// 存储账户质押余额
pub AccountStake get(fn account_stake): map hasher(blake2_128_concat) T::AccountId => u64;
}
}
// 定义事件
decl_event!(
pub enum Event<T> where AccountId = <T as frame_system::Trait>::AccountId {
// 质押事件
Staked(AccountId, u64),
// 解除质押事件
Unstaked(AccountId, u64),
}
);
// 定义模块
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
// 初始化事件
fn deposit_event() = default;
// 质押函数
#[weight = 10_000]
pub fn stake(origin, amount: u64) -> DispatchResult {
let sender = ensure_signed(origin)?;
// 更新存储
<AccountStake<T>>::mutate(&sender, |balance| *balance += amount);
<TotalStake<T>>::mutate(|total| *total += amount);
// 发出事件
Self::deposit_event(RawEvent::Staked(sender, amount));
Ok(())
}
// 解除质押函数
#[weight = 10_000]
pub fn unstake(origin, amount: u64) -> DispatchResult {
let sender = ensure_signed(origin)?;
// 检查余额是否足够
let current = <AccountStake<T>>::get(&sender);
if current < amount {
return Err("Insufficient stake balance".into());
}
// 更新存储
<AccountStake<T>>::mutate(&sender, |balance| *balance -= amount);
<TotalStake<T>>::mutate(|total| *total -= amount);
// 发出事件
Self::deposit_event(RawEvent::Unstaked(sender, amount));
Ok(())
}
}
}
// 测试模块
#[cfg(test)]
mod tests {
use super::*;
use frame_support::{assert_ok, assert_err, impl_outer_origin, parameter_types};
use sp_core::H256;
use sp_runtime::{testing::Header, traits::{BlakeTwo256, IdentityLookup}, Perbill};
impl_outer_origin! {
pub enum Origin for Test {}
}
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: u32 = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
}
impl frame_system::Trait for Test {
type Origin = Origin;
type Call = ();
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = ();
type ModuleToIndex = ();
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
}
impl Trait for Test {
type Event = ();
}
type Nis = Module<Test>;
#[test]
fn test_stake() {
new_test_ext().execute_with(|| {
// 初始状态检查
assert_eq!(Nis::total_stake(), 0);
assert_eq!(Nis::account_stake(1), 0);
// 质押成功
assert_ok!(Nis::stake(Origin::signed极简,仅包含核心功能,适合快速上手和理解NIS模块的基本概念。
1 回复
以下是基于提供内容的完整示例demo,首先展示内容中提供的示例,然后补充完整实现:
内容中提供的示例
参与质押
use frame_support::weights::DispatchClass;
let call = pallet_nis::Call::<Runtime>::place_bid {
amount: 100u32.into(),
duration: 28u32.into(),
};
let origin = Origin::signed(1);
let info = call.get_dispatch_info();
let result = Nis::place_bid(origin, call, info.weight, info.class);
查询质押信息
use pallet_nis::Queues;
// 获取当前队列中的质押信息
let queues = Queues::<Runtime>::get();
println!("Current queues: {:?}", queues);
治理投票
let call = pallet_nis::Call::<Runtime>::vote {
poll_index: 1,
aye: true,
};
let origin = Origin::signed(1);
let _ = Nis::vote(origin, call);
完整示例demo
//! 完整的pallet-nis使用示例
use frame_support::{dispatch::DispatchResult, weights::DispatchClass};
use frame_system::RawOrigin;
use pallet_nis::{self as nis, Queues};
/// 自定义运行时配置
pub struct Runtime;
impl nis::Config for Runtime {
type RuntimeEvent = ();
type WeightInfo = ();
type Currency = Balances;
type Counterpart = ();
type Deficit = ();
type Surplus = ();
type MinBid = frame_support::traits::ConstU32<10>;
type QueueCount = frame_support::traits::ConstU32<8>;
type MaxDuration = frame_support::traits::ConstU32<365>;
}
/// 模拟Balances模块
pub struct Balances;
/// NIS模块完整示例
pub struct NisDemo;
impl NisDemo {
/// 参与质押的完整示例
pub fn place_bid_example() -> DispatchResult {
// 创建质押调用
let call = nis::Call::<Runtime>::place_bid {
amount: 100u32.into(),
duration: 28u32.into(),
};
// 获取调度信息
let info = call.get_dispatch_info();
// 执行质押操作
nis::Pallet::<Runtime>::place_bid(
RawOrigin::Signed(1).into(),
call,
info.weight,
info.class
)
}
/// 查询质押信息的完整示例
pub fn query_queues_example() {
// 获取质押队列
let queues = Queues::<Runtime>::get();
// 打印队列信息
println!("质押队列详情:");
for (duration, queue) in queues.iter() {
println!("持续时间: {} 天, 队列长度: {}", duration, queue.len());
}
}
/// 治理投票的完整示例
pub fn vote_example() -> DispatchResult {
// 创建投票调用
let call = nis::Call::<Runtime>::vote {
poll_index: 1,
aye: true, // 赞成票
};
// 执行投票操作
nis::Pallet::<Runtime>::vote(
RawOrigin::Signed(1).into(),
call
)
}
/// 综合示例:质押、查询、投票
pub fn full_demo() {
println!("开始NIS模块演示...");
// 1. 参与质押
match Self::place_bid_example() {
Ok(_) => println!("质押成功"),
Err(e) => println!("质押失败: {:?}", e),
}
// 2. 查询质押信息
Self::query_queues_example();
// 3. 参与治理投票
match Self::vote_example() {
Ok(_) => println!("投票成功"),
Err(e) => println!("投票失败: {:?}", e),
}
println!("NIS模块演示完成");
}
}
// 运行示例
fn main() {
NisDemo::full_demo();
}
代码说明
- 运行时配置:实现了
nis::Config
trait,包含最小出价、队列数量和最大持续时间等配置项 - Balances模拟:简化了Balances模块的实现
- 核心功能:
place_bid_example
: 展示如何参与质押query_queues_example
: 展示如何查询质押队列vote_example
: 展示如何进行治理投票
- 完整流程:
full_demo
方法展示了从质押到投票的完整流程
注意事项
- 实际使用时需要根据具体区块链项目调整参数
- 需要确保运行时已正确配置所有依赖项
- 生产环境应考虑添加错误处理和日志记录
- 投票功能需要链上已有对应的提案才能成功执行