4

I need to change the balances of all the accounts in my custom pallet, For that first i need to fetch the accounts in the pallet. How to do this?

7
  • Of a pallet different than FRAME System? Or for FRAME System? (the default for Substrate blockchains)
    – Shawn Tabrizi
    Apr 26, 2023 at 19:27
  • Might be duplicate of: substrate.stackexchange.com/questions/180/…
    – Shawn Tabrizi
    Apr 26, 2023 at 19:29
  • @ShawnTabrizi I'm building new custom pallet, their I need to fetch all the accounts present in our chain_state and then increase some balance.How to perform this? Apr 27, 2023 at 5:30
  • What do you mean "change"? Through transfer or migration? Apr 27, 2023 at 6:35
  • @AurevoirXavier I need to add 10 unit balance to all the accounts after every 5 blocks. Can we Do it? Apr 27, 2023 at 7:08

2 Answers 2

3

You can use storage iter keys, and put this logic in on_initialize.

Pseudo code:

fn on_initialize(n: BlockNumber) {
  // Run this every 5 blocks.
  if n % 5 != 0 { return; }

  <Accounts<T>>::iter_keys().for_each(|a| {
    transfer(a, 10 * UNIT);
  });
}

Note, if the Accounts map is large, this would require a lot of weight. Be careful with this.


I don't agree with @bkchr's comment.

As I said this would cost a lot of weight, you need to pay more attention to this.

But it's still reasonable to have this in the pallet.

If your pallet is about building up a small group. And there are always a few people in the group(your_pallet::Accounts<T>), it's okay to use this.

In the past, this is exactly how staking reward distribution got implemented in Substrate. But as the number of Kusama validators/nominators grows up, they have to find another way to do this.

So, I won't say this is wrong at all. Just take some measures before you use this. Check if this fits your case.

5
2

The idea of increasing the balance of every account every 5 blocks is a bad idea. Your chain would be very easily attack-able by creating a lot of accounts and thus forcing you to iterate over all these accounts. There are multiple ways to achieve what you are trying to do, without killing your chain.

  1. If you only have a subset of accounts. You could have a map of LastUpdated<AccountId, Block>. Then users would need to call a mint function and that calculates the amount of coins they are getting since the last time they called mint and then you need to update LastUpdated. This is a "lazy" way where the user need to do interact with the chain to get its funds.

  2. If you really want to increase the balance of every account. You could make every account balance be a percentage of the total supply. Then each time you want to increase the balance of all the accounts, you simply increase the total supply. But be aware that while this would work, nothing in FRAME is written in such a way currently.

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.