如何修改 Nicks Pallet(在 Substrate 中)以通过将货币转移到另一个帐户而不是使用储备货币来设置昵称?

How to modify the Nicks Pallet (in Substrate) to set the nickname via a transfer of currency to another account, instead of using reserve currency?

在Nicks Pallet中,账户可以通过储备货币为自己设置昵称。我想修改此功能,改为要求向另一个特定帐户支付费用(现在我只想将费用发送到 Alice 帐户)以设置昵称。

这似乎应该是一个相当简单的修改,但由于我是 Substrate 和 Rust 的新手,这并不像我想象的那么简单。我已经对 Nicks Pallet 进行了分叉,但就是无法完全弄清楚如何从这里开始。

我正在使用 substrate 的本地克隆版本。

以下是您需要进行的高级更改:

  1. 为您的托盘配置引入新的 associated type Trait:
pub trait Trait: frame_system::Trait {
    // -- snip --
    // This is a new type that allows the runtime to configure where the payment should go.
    type PaymentReceiver: Get<Self::AccountId>;
}
  1. 更新 set_name 函数以使用不同的 Currency 函数。在这种情况下,我们想要 transfer 而不是 reserve:
// New import needed
use frame_support::traits::ExistenceRequirement::KeepAlive;
fn set_name(origin, name: Vec<u8>) {
    let sender = ensure_signed(origin)?;

    ensure!(name.len() >= T::MinLength::get(), Error::<T>::TooShort);
    ensure!(name.len() <= T::MaxLength::get(), Error::<T>::TooLong);

    let deposit = if let Some((_, deposit)) = <NameOf<T>>::get(&sender) {
        Self::deposit_event(RawEvent::NameChanged(sender.clone()));
        deposit
    } else {
        let deposit = T::ReservationFee::get();
        // The only change is made here...
        T::Currency::transfer(&sender, &T::PaymentReceiver::get(), deposit.clone(), KeepAlive)?;
        Self::deposit_event(RawEvent::NameSet(sender.clone()));
        deposit
    };

    <NameOf<T>>::insert(&sender, (name, deposit));
}
  1. 注释掉我们 unreserveslash_reserved 的代码部分,因为这些行为不适用于此新逻辑。

fn clear_name

// let _ = T::Currency::unreserve(&sender, deposit.clone());

fn kill_name

// T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit.clone()).0);
  1. 完成这些更改后,您的 pallet 应该可以正常编译:
substrate git:(master) ✗ cargo build -p pallet-nicks
   Compiling pallet-nicks v2.0.0-rc6 (/Users/shawntabrizi/Documents/GitHub/substrate/frame/nicks)
   Finished dev [unoptimized + debuginfo] target(s) in 2.48s
  1. 要在运行时实际使用这些更改,您需要使用这个新的 PaymentReceiver 特征对其进行配置:
// Here we define the value of the receiver
// `//Alice` -> `5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY`
// -> `0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d`
// Using: https://www.shawntabrizi.com/substrate-js-utilities/

ord_parameter_types! {
    pub const PaymentReceiverValue: AccountId = AccountId::from(
        hex_literal::hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")
    );
}

You may need to introduce the hex_literal crate into your runtime.

我们在 trait 实现中使用这个值:

impl pallet_nicks::Trait for Runtime {
    // -- snip --
    type PaymentReceiver: PaymentReceiverValue;
}

就是这样!如果这有帮助,请告诉我。