Data Location Assignment [OLD]

Hey @cryptoGerry!

Your answer is actually the cheapest of the possible alternatives in terms of gas :ok_hand: Nice one!

By the way, in case you didn’t know…
Before you type in your code to post it here in the forum, click on the </> icon in the menu at the top of the text editor. You will see 2 sets of 3 back ticks.
```
```
If you now input your code between these, you will end up with nicely formatted code, which is then also easier for you to organise with the correct spacing and indentation etc. You should then end up with something like:

function updateBalance(uint id, uint balance) public {
   users[id].balance = balance;
}
1 Like

Your answer is actually the cheapest of the possible alternatives in terms of gas :ok_hand: Nice one!
Thought you’d be interested to know that, as you were discussing gas cost with @gabba a few days ago :slight_smile:

2 Likes

Thank you for the observation!

1 Like
pragma solidity 0.5.1;
contract MemoryAndStorage {

    mapping(uint => User) users;

    struct User{
        uint id;
        uint balance;
    }

    function addUser(uint id, uint balance) public {
        users[id] = User(id, balance);
    }

    function updateBalance(uint id, uint balance) public {
         User storage user = users[id];
         user.balance = balance;
    }

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }

}
1 Like

@filip i hope this also could work instead of writing storage instead of memory?
By default it will use storage

pragma solidity 0.5.1;
contract MemoryAndStorage {

mapping(uint => User) users;

struct User{
    uint id;
    uint balance;
}

function addUser(uint id, uint balance) public {
    users[id] = User(id, balance);
}

function updateBalance(uint id, uint balance) public {
    //  User memory user = users[id];
     users[id].balance = balance;
}

function getBalance(uint id) view public returns (uint) {
    return users[id].balance;
}

}

1 Like
pragma solidity 0.5.1;
contract MemoryAndStorage {

    mapping(uint => User) users;

    struct User{
        uint id;
        uint balance;
    }

    function addUser(uint id, uint balance) public {
        users[id] = User(id, balance);
    }

    function updateBalance(uint id, uint balance) public {
         users[id].balance = balance;
    }

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }

}
1 Like

Hi @Gandharv_dalal!

Absolutely! :+1:
And this is actually the cheapest of the possible alternatives in terms of gas! :muscle:

2 Likes

Hey @Yves_T! Welcome to the course! I hope you’re enjoying it and learning loads :slightly_smiling_face:
Your answer is actually the cheapest of the possible alternatives in terms of gas :ok_hand: Nice one!

1 Like

Thank you for you response :slight_smile:

1 Like

pragma solidity 0.5.1;
contract MemoryAndStorage {

mapping(uint => User) users;

struct User{
    uint id;
    uint balance;
}

function addUser(uint id, uint balance) public {
    users[id] = User(id, balance);
}

function updateBalance(uint id, uint balance) public {
     //User memory user = user[id]; change memory to storage 
     //this change allows updates to be stored outside the function after it is run 
     User storage user = users[id];
     user.balance = balance;
}

function getBalance(uint id) view public returns (uint) {
    return users[id].balance;
}

}

1 Like

My choice was to change memory to storage in the updateBalance function

User storage user = users[id];

1 Like

The problem was that the User was altered in memory but the actual mapping was never updated. A very simple solution is to update the User in the mapping directly.

In addition, to prevent updateBalance() from adding a new user when called with an id that does not exist in the mapping, I’ve added bool exists to the User struct.

pragma solidity 0.5.1;
contract MemoryAndStorage {

    mapping(uint => User) users;

    struct User{
        uint id;
        uint balance;
        bool exists;
    }

    function addUser(uint id, uint balance) public {
        users[id] = User(id, balance, true);
    }

    function updateBalance(uint id, uint balance) public{
        require(users[id].exists, 'User does not exist');
        
        users[id].balance = balance;
    }

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }

}
1 Like

Good morning,

To correct this issue, I simply changed memory to storage in our update balance function:

function updateBalance(uint id, uint balance) public {
User storage user = users[id];
user.balance = balance;

After testing, the correction fixed the issue. I can certainly see why data locations can be dangerous if not setup correctly.

1 Like

pragma solidity 0.5.12;

contract MemoryandStorage{

mapping(uint => User) users;

struct User{
    uint id;
    uint balance;
}

function addUser (uint id, uint balance)public {
    users[id]= User(id,balance);
}

function updateBalance(uint id, uint  balance) public{
    
    users[id].balance= balance;
}

function getBalance(uint id) public view returns (uint){
    return users[id].balance;
}

}

1 Like

Creating a memory location of the user and updating it, does not update on the underlying storage location - what i did was just to update the mapping itself:

users[id].balance = balance

1 Like

Change this to:

    function updateBalance(uint id, uint balance) public {
         users[id].balance = balance;
    }
 function updateBalance(uint id, uint balance) public {
        users[id].balance = balance;
    }
2 Likes

Mappings can only have the location of storage, which persists. Using the mapping, we can directly update the balance value of the id key.

    function updateBalance(uint id, uint balance) public {
         //User memory user = users[id];   Used locally, then discarded.
         
         users[id].balance = balance;   // users' mapped to storage data location.
    }
2 Likes

pragma solidity 0.5.1;
contract MemoryAndStorage {

mapping(uint => User) users;

struct User{
    uint id;
    uint balance;
}

function addUser(uint id, uint balance) public {
    users[id] = User(id, balance);
}

function updateBalance(uint id, uint balance) public {
     //User memory user = users[id];
     //user.balance = balance;
     users[id].balance = balance;
}

function getBalance(uint id) view public returns (uint) {
    return users[id].balance;
}

}

1 Like

@Capaburro, @Kronuss1987

Hi @letscrypto,

Just to clarify…both of the following are valid solutions, although the second one is very slightly cheaper in terms of gas.

4 Likes