Data Location Assignment

Hi,

Following is my solution to the 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 {
         //User memory user = users[id];
         users[id].balance = balance;
    }

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

}
1 Like

Hey Jon,

That is very true and has helped me with other subjects that I am or have learned.
Again, I appreciate the feedback :+1:

1 Like

Hello guys! This is one code change solution lol. I think most obvious and easy way :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 {
         User storage user = users[id];
         user.balance = balance;
    }

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

}
1 Like

Nice solution @ibn5x :ok_hand:

Even though the initial idea of this assignment is to update the existing balance by replacing it with the new one, 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 change 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.

Let me know if you have any questions :slight_smile:

Hey Thanks, @jon_m Happy accident that I misinterpreted the assignment then I guess. No questions for you now, your response makes total sense and has been dutifully noted. I appreciate your time.

1 Like

Hi, here is my code! Thanks.

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.8.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;
    }

}

I changed memory to storage and also change user.balance=balance to user.balance += balance;

1 Like
users[id].balance = balance;

the issue with the original code is that the balance was stored in memory, i.e. as a temporary data type because the ‘balance’ amount was set to a memory data type, not a permanent data type, i.e. not the storage data type.

1 Like

Thank you so much for the code review @jon_m. Incredible insight and valuable information on what are the thought process of a much more proficient Solidity programmer when it comes to generating a smart contract. Really appreciate the reply and all the constructive criticism. Looking forward from more guidance from you.

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;
    
    //SOLUTION 1
     User memory user = users[id];
     user.balance = balance;
     users[id] = user;
    
    //SOLUTION 2
    users[id] = User(id, balance);

     //SOLUTION 3
     User user = users[id];
     user.balance = balance;
     users[id] = user;
}

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

}

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

Even though the initial idea of this assignment is to update the existing balance by replacing it with the new one, 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 change 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 .

Let me know if you have any questions :slight_smile:

Nice solution @ZacSed :ok_hand:

Just be careful with the term data type. This refers to whether data is defined as uint, int, address, bool, string etc. Here you are highlighting differences in the duration data is stored for (either temporarily, or persistently). This is a result of data location (memory, or storage), and not data type.

Let me know if you have any questions :slight_smile:

Hi @RBeato,

Correct… although not very efficient in terms of gas cost or conciseness of code.

This solution makes the updateBalance function exactly the same as the addUser function.
While this does still work…

This is incorrect: the first line generates a red compiler error. The error message tells you what the specific nature of the error is: the data location for this complex data type (a User instance based on the User strut) must be explicitly declared for local variables.

Have you now found out what the 2 most efficient solutions are? If not, you will find them in other students’ solutions posted in this discussion topic.

Let us know if anything is unclear, or if you have any questions :slight_smile:

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 newBalance) public {
         users[id].balance = newBalance;
    }

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

}
1 Like

Thank you! I got it!

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

Hi guys, I figured that the problem in the starter code was that it was using a memory located temporary variable to assign the new balance value, so the fix was just simply using dot notation to directly access the users mapping (located in storage) and change the balance value of the user permanently.

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, and a very good explanation @mike_sutanto :ok_hand:

pragma solidity 0.8.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

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