I am developing a dApp, and this line of code is in it:

    function generateActiveStakers() public  {   
    delete actives;
    for (uint i = 0; i < stakers.length; i++) { 

        if (isDeposited[stakers[i]]==true) {

This is working currently, but if I do this in the numbers of thousands of people, is it going to work? I am concerned about gas costs etc. If not, any alternatives?


While I don't think this is a duplicate, I am going to liberally quote from an answer to another (similar, but still different enough to justify both imho) question.

From this answer:

The more lines of code or the more complex the calculations you do, state variables you access and/or store/modify, the higher the gas that will be used.

(pabloruiz55 is referring to the cost of gas in gas units here, as in the amount of gas units each EVM opcode costs. You pay gas by taking the amount of gas units your function expended and multiplying by the gas price you offer, provided that the product is less than the gas limit, or (in psuedocode):

yourCostInGwei = gasPrice * sumGasUnitsInOperation > gasLimit ? gasLimit : gasPrice * sumGasUnitsInOperation

moving along:

Reading from the blockchain still consumes gas but you don't have to pay for it, so reading is free. BUT, you are still bound by gas limits. Even if you don't have to pay for the gas, gas is consumed and if the function does some heavy computing it will run out of gas and fail.

Even if this for loop was read-only (no push), it would almost certainly still fail if it was iterating over a set that large. But at least it would be free. Once the push is in there, and it becomes a write-operation, it will almost certainly fail and charge you your gas limit. That means you'd have to pay dearly for the right to have your operation fail on the blockchain.

You ask for alternatives, but don't give much of a description for what you're trying to do. At first glance it looks like you're trying to determine who has staked funds in a contract at a given point in time. If that is correct, one suggestion could be doing the calculation off-chain. Is there a reason why this needs to be done on-chain? There is a good chance that you can write a script in your language of choice that queries the balanceOf (or similar) on the target contract, and assembles the list off chain. You may be able to scrape events to do the same.

Alternatively, you might be able to create a system where the users claim rewards instead of them being pushed. (This is making some guesses about code that isn't shown here, so it might be off-base.) This might allow you to avoid using arrays, which can get tricky with gas, and use something like mappings instead. Mappings aren't iterable (well, most of the time), but if the user is coming and withdrawing, they can put their address in the mapping, and get how much they are entitled to from there.

Hope that helps!

  • 1
    Yep, I'll have to move this off-chain. Thank your for your help
    – user68609
    Apr 22 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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