0

i have this contract: https://0bin.net/paste/HELe1bA6#57cIhOxKhJDpqh56tzBb9SYzsh4MraWkbL+2AslB5Nc

How can I do a foreach in mapping _balances ?

I need to share the balance with everyone who has the token, I think about doing it in foreach, but if you have another better option, please talk

1 Answers1

1

You cannot directly iterate a mapping or enumerate the keys that exist because all keys in a hash table do definitely exist ... it's just that most of them have 0x0 values.

You can only solve the problem by creating a structure that uses a mapping for effective random access and an array for iteration. It's up to you to maintain the structure.

Have a look at the last two suggestions here: Are there well-solved and simple storage patterns for Solidity?

The Solidity CRUD pattern has evolved a bit, now a library and of course the source code version keeps advancing. Have a look over here for a library and an explanation of what it's doing.

https://medium.com/robhitchens/solidity-crud-epilogue-e563e794fde

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
  • I had read a way every time I manipulated the token I saved it in an array, but I thought it was a bad idea, since the balance already has this, I wanted to avoid spending on gas – Augusto Furlan Feb 20 '21 at 22:09
  • Yes, you want to optimize for gas/performance. If you do indeed need to iterate then the construction of the data structure that enables it is your responsibility because the EVM is not doing it for you. Are you sure you need to? https://blog.b9lab.com/the-joy-of-minimalism-in-smart-contract-design-2303010c8b09 – Rob Hitchens Feb 21 '21 at 18:37
  • I need to send dividends to everyone who has my tokens, see how many have a moment and send the amount proportional to his. Would there be another way? – Augusto Furlan Feb 21 '21 at 19:48
  • Yes, there is, and you absolutely must not rely on iteration to get it done. You have to "invert control" and "amortize the work." Given a user Alice, her balance at a certain time, a gross distribution based on that balance and other variables like circulating supply at the time, a contract can compute the distribution Alice would have received if it was pushed to her. This can be processed a number of ways, e.g. claimed (and processed) by Alice, or included in a balance figure. – Rob Hitchens Feb 21 '21 at 21:01
  • For example, Alice's funds that are available to spend would be a) the balance of her account, plus b) her unprocessed distributions that she is entitled to that are known (computable) to the contract. So, why not add them together and return the sum? The next step is to clear out unprocessed distributions at the first opportunity. For example, whenever her balance changes (send or receive), someone is paying for gas, and this is an opportunity to add up the unprocessed distributions, add to the plain old "balance" and zero out unprocessed distributions. – Rob Hitchens Feb 21 '21 at 21:05
  • There are some decisions to make about who should pay for what gas and when and you need to make sure workload debt never gets too big, but generally, you are inverting the process so there is never a "big bang" distribution on chain (because it won't scale) but the contract keeps up with actual on-chain requirements at all times while making incremental progress on large-scale processes. – Rob Hitchens Feb 21 '21 at 21:08