Data Location Assignment

pragma solidity 0.7.5;
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

Nice solution @kylecullen :ok_hand:

You’ve also made a great attempt at an explanation :+1:

By assigning users[id] to a local storage variable, we create a local “pointer” called user.

This points to (references)  users[id]===> the user record in the mapping (users) which is mapped to the id input into the function.

The user records are struct instances with the properties defined in the User struct, and the local “pointer” has these same properties — notice that it has also been declared with the data type User . Any value which is assigned to a property of the local “pointer” (user) is effectively updating that same property of a specific user record in the mapping …

The local variable user creates a temporary “bridge” to the mapping during execution of the function. This enables a specific user’s balance (stored persistently in the mapping) to be reassigned with the newbalance (input into the function), before this “bridge” is lost when the function finishes executing.

Let me know if you have any questions :slight_smile:

pragma solidity 0.7.5;

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; // new code
     //User memory user = users[id];
     //user.balance = balance;
}

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

}

1 Like

Nice solution @Markeljan_Sokoli :ok_hand:

… and welcome to the forum! I hope you’re enjoying the course :slightly_smiling_face:

Hi, I found that a memory variable was being used so the changes were not permanent. I decided to directly make the assigment.

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

pragma solidity 0.7.5;

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;
    // assuming if user is just a copy in memory of the users[id] then
     users[id] = user;
}

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

}

1 Like
pragma solidity 0.7.5;
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

Looking back I supposed I should have just used ‘=’ instead of ‘+=’.

I was thinking back to the Bank contract when considering updateBalance

1 Like

pragma solidity 0.7.5;
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

Nice solution @Shadowstep2003 :ok_hand:

As you realised afterwards, the initial idea of this assignment is to update the existing balance by replacing it with the new one. Despite this, I actually think that it makes more sense to do what you have done, and add an amount to the existing balance using the addition assignment operator += (instead of the assignment operator = ). However, if you add to, instead of replacing, the existing balance, I think your code would be clearer and more readable if you also changed the name of the balance parameter to amount, because you are adding an amount to the balance, rather than replacing it with a new balance.

Just let me know if you have any questions :slight_smile:

pragma solidity 0.7.5;
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
pragma solidity 0.7.5;
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;
    }

}

I changed memory to storage so that the new data is persistent and I removed some of the code from the updateBalance function because there is already a mapping for “users” that we can utilise.

1 Like

Nice solution and explanation @unwise_guy :ok_hand:
… and good to see you back here in the forum after a while :slight_smile:

That’s correct … and by doing it this way (assigning the new balance directly to the user instance in the mapping), there is no need to explicitly specify the data location as storage, because all state variables and mappings are automatically saved in persistent storage.


pragma solidity 0.7.5;
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
function updateBalance(uint id, uint balance) public {
         User memory user = users[id];
         user.balance = balance;
         users[id].balance = user.balance;
    }

The balance gets lost once the function execution is done. We didn’t really save anything on the user. A pretty simple solution is to get the users using the id and change the balance from that map.

1 Like

pragma solidity 0.7.5;
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;
}

}

at first i thought my solution wrong, good thing i deleted the previous deployed contract and deploy the new one to check if its correct. hahahahaha

1 Like

Nice solution @rpacho :ok_hand:

We did … but only temporarily in memory. We need to save the new balance persistently in storage. And that’s what your 3rd line does :+1:

pragma solidity 0.7.5;
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
// SPDX-License-Identifier: UNLICENCED

pragma solidity 0.7.5;

contract MemoryAndStorage {

    mapping(uint => User) users;
    address admin;

    struct User{
        uint id;
        uint balance;
    }
    
    
    constructor() {
        admin = msg.sender;
    }
    

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

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

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }
    
    
    modifier mIsAdmin() {
        require(msg.sender == admin);
        _;
    }

}
1 Like

Nice solution @Langren :ok_hand:

… and good to see you back here in the forum! I hope you’re enjoying the course :slight_smile: