You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Substrate的Nicks Pallet:将昵称设置改为向指定账户转账付费

刚接触Substrate和Rust的时候改Pallet确实容易摸不着头绪,我来一步步带你把Nicks的「预留货币设昵称」改成「向Alice付费设昵称」——你已经fork好仓库了,接下来就按下面的步骤来~

步骤1:明确核心修改方向

Nicks Pallet原本的set函数是用Reserve机制锁定用户余额来实现昵称设置,我们要把这部分替换成直接向Alice转账的逻辑,同时调整移除昵称时的退款逻辑(毕竟钱已经转走了,不需要再退还)。

步骤2:修改set函数的核心逻辑

找到你fork的Nicks Pallet里的src/lib.rs,定位到set可调用函数,把原来的预留代码换成转账逻辑:

#[pallet::call_index(0)]
#[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())]
pub fn set(origin: OriginFor<T>, name: Vec<u8>) -> DispatchResult {
    let who = ensure_signed(origin)?;
    // 校验昵称长度(保留原有逻辑)
    ensure!(name.len() <= T::MaxLength::get() as usize, Error::<T>::TooLong);

    // 替换原有的预留逻辑为转账给Alice
    let fee = T::ReservationFee::get();
    // 硬编码Alice的默认账户ID([1u8;32]是Alice的标准AccountId32)
    let alice = AccountId32::from([1u8; 32]);
    // 执行转账,KeepAlive保证用户转账后账户不会被销毁
    T::Currency::transfer(&who, &alice, fee, ExistenceRequirement::KeepAlive)?;

    // 更新昵称存储(原来的deposit字段现在可以存支付的费用,或者不需要的话可以修改存储结构)
    <NameOf<T>>::insert(&who, (name, fee));
    Self::deposit_event(Event::NameSet { who });
    Ok(())
}

注意:如果想以后灵活修改收款账户(比如不用硬编码Alice),可以在Pallet的Config trait里加一个关联类型type PaymentReceiver: Get<Self::AccountId>,然后在Runtime配置里指定收款账户就行。

步骤3:调整clear函数的退款逻辑

原来的clear函数会把预留的余额还给用户,现在钱已经转给Alice了,所以直接删除昵称存储即可:

#[pallet::call_index(1)]
#[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())]
pub fn clear(origin: OriginFor<T>) -> DispatchResult {
    let who = ensure_signed(origin)?;

    // 移除原来的退款逻辑,直接删除昵称记录
    <NameOf<T>>::take(&who).ok_or(Error::<T>::Unnamed)?;
    Self::deposit_event(Event::NameCleared { who });
    Ok(())
}
步骤4:编译并测试
  1. 先单独编译Pallet:在fork的Nicks Pallet目录下运行cargo build,确保没有编译错误。
  2. 回到你的Substrate项目根目录,编译整个Runtime:cargo build --release。
  3. 启动本地节点,用Polkadot JS Apps连接后,调用nicks.set函数测试:检查自己的余额是否减少,Alice的余额是否增加,昵称是否成功设置。
额外注意事项
  • 确保导入了sp_core::crypto::AccountId32,不然硬编码Alice的账户ID会报错。
  • 如果你修改了Pallet的Config trait(比如加了PaymentReceiver),需要在你的Runtime的lib.rs里更新Nicks的配置,比如:
    impl pallet_nicks::Config for Runtime {
        type Event = Event;
        type Currency = Balances;
        type ReservationFee = ConstU128<1000>; // 自定义付费金额
        type MaxLength = ConstU32<16>;
        type PaymentReceiver = ConstAccountId32<[1u8; 32]>; // 指定收款账户为Alice
    }
    
  • 如果要处理旧用户的预留数据(比如升级前已经设置昵称的用户),需要写存储迁移逻辑,把他们的预留余额直接转成已支付费用,或者退还后让他们重新付费设置。

内容的提问来源于stack exchange,提问作者Giovanni_Visione

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:12:42