1

I'm planning to write a pallet to distribute token to many users in substrate blockchain (Ex: 500k-1m users). Should I do a for loop in a user list and transfer token to them? Do you have any example?

2
  • Is it a one-time job? Or a call that you could call it multiple times?
    – AurevoirXavier
    Commented Oct 5, 2022 at 17:41
  • I like one-time job than call it multiple times. Do you know the advantage/disadvantage of each way. Just wonder can we distribute token to 500k-1m users with one-time job? Commented Oct 5, 2022 at 18:17

1 Answer 1

3

Both are easy to implement. But if it is an extrinsic call, you might need to pay more attention to the bandwidth/weight costs.


One-time job in migration way.

Find your Executive type in the runtime lib.rs and add a TokenDistribution:

pub type Executive = frame_executive::Executive<
    Runtime,
    Block,
    ChainContext<Runtime>,
    Runtime,
    AllPalletsWithSystem,
+   TokenDistribution,
>;

Define the struct TokenDistribution and implement OnRuntimeUpgrade for it:

use frame_support::traits::OnRuntimeUpgrade;

pub struct TokenDistribution;
impl OnRuntimeUpgrade for TokenDistribution {
    fn on_runtime_upgrade() -> Weight {
        let fund_account = x;
        let distribute_amount = y;

        load_user_list().into_iter().for_each(|user: AccountId| {
            // `Balances` is the pallet name of your `pallet-balances` 
            // instance which defines in the runtime `lib.rs`           
            Balances::transfer(
                Origin::signed(fund_account),
                user.into(),
                distribute_amount
            );
        });
        
        // Or you could calculate a more precise weight here
        RuntimeBlockWeights::get().max_block
    }
}

In the next runtime upgrade, the distribution will be applied.

I believe this is the cleanest way to do it.

And remember to remove these codes before the next-next runtime upgrade.

3
  • Can we do 500k-1m transactions in 1 extrinsic call. Is there any limit by BlockWeight or anything else? Commented Oct 6, 2022 at 7:49
  • 1
    I'm not pretty sure about that. But you could split it into multiple calls. It looks like this Vec<Scheduler::schedule(Utility::batch(Vec<transfer>))>. Make sure that your chain has pallet-scheduler and pallet-utility,
    – AurevoirXavier
    Commented Oct 6, 2022 at 8:17
  • hi @AurevoirXavier i want to call pallet_session set_keys. can you please guide me Commented Jan 16 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.