0

What i want my code to do

Everytime the function is called the exampleValue of all users should be increased by 5

What the code actually does

When i compile it in Remix i get this error message:

TypeError: Integer constant expected. User[i].value = User[i] + 5; ^

Code

pragma solidity 0.6.0;

contract LoopingThroughArray {
    
    struct User {
        uint256 exampleValue;
        address id;
        
    }
    
    User[] public users;
    
    receive() external payable {
        for (uint i=0; i<=users.length; i++) {
            User[i].exampleValue = User[i] + 5;  // thats the line where i get the error
        }  
    }
    
    
} 

What i already tried

  • replacing the users.length with a constant uint both in- and outside of the function
  • using a normal function instead of the receive function
1

You have reference the mapping name at the index you want, which is a struct and the struct member for the math operations.

pragma solidity 0.6.0;

contract LoopingThroughArray {
    
    struct User {
        uint256 exampleValue;
        address id;
        
    }
    
    User[] public users;
    
    receive() external payable {
        for (uint i=0; i<=users.length; i++) {
            users[i].exampleValue = users[i].exampleValue + 5;
        }  
    }    
} 

CAUTION

I realize this is a contrived example for learning but it is worth mentioning for others who find this example. This approach won't scale. So, either there is a hard limit on users.length or the contract will fail when users.length is too large. This is because the total cost is the cost of one iteration times the number of users in the array. So.

transaction cost = iteration cost * numbers of users

Since there is a soft limit to the gas users would be willing to pay and a hard limit on the gas used by a single transaction in a block, it's not a scalable pattern.

Hope it helps.

4
  • Thank you! That it wont scale is something i havent thought about. Are there any resources you could recommend about scaling and gas cost of different different operations? – The Horse from Horsin Around Nov 18 '20 at 14:00
  • Ethereum makes you turn to classical (pre-database) data organization. Have a look at this. Other patterns include linked-list. There are even b-trees to use (with caution). It's very common to use mappings for random access, O(1) lookups. ethereum.stackexchange.com/questions/13167/… – Rob Hitchens Nov 18 '20 at 22:32
  • More about the problem and some fresh ways to think about it: blog.b9lab.com/getting-loopy-with-solidity-1d51794622ad: – Rob Hitchens Nov 18 '20 at 22:34
  • Your example hints are "process amortization" which is very advanced. Simply put, you have to make sure every function has a fixed gas cost at any scale, O(1). So, for things like "do this for all users" you have to invert control - when each user supplies gas, do this to their state. Have a look at this example of how to tackle such things. medium.com/@weka/… – Rob Hitchens Nov 18 '20 at 22:36

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.