[Ethereum] Solidity for loop over a huge amount of data

contract-designcontract-developmentsoliditystorage

I want to use a function to find all tokens of a user in solidity, so I use a for loop to iterate over all tokens and look if the addresses do match. But my function always returns zero for 10Mio iterations, so I implemented a test function to see where the limits are. Does solidity have a problem with huge for loops? For example I tried the following test function, which returns always 0 if the number of iteration is above around 3'000'000. It looks like there is a timeout for a function to run?

function testLoop(uint256 num) external view returns(uint256 res) {
        uint256 i=0;
        uint256 cnt=0;

        for(i;i<num;i++) {
            cnt++;
        }

        return cnt;
    }

Best Answer

Yes, the EVM has a problem with unbounded loops. The gas consumed increases with each iteration until it hits the block gasLimit and the function can't run at all. Consequently, unbounded iteration is an anti-pattern.

Consider inverting control so the clients call the contract one row at a time. The contract can expose helper functions to return the length of the list, the key (to a mapping) at a row in the list, and the details of a struct stored in a mapping for a given key.

There are some example implementations over here: Are there well-solved and simple storage patterns for Solidity?

The "Mapped Struct with Index" works as described above.

Hope it helps.

Related Topic