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 storage user = users[id];
         user.balance = balance;
    }

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

}```
2 Likes
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.5;
contract MemoryAndStorage {

    mapping (uint => user) userList; // used different naming for ease of use 

    struct user{
        uint id;
        uint balance;
    }

    function addUser(uint id,uint balance) public {
        userList[id] = user(id,balance);
    }

    function updateUser(uint id,uint balance) public{
        userList[id].balance = balance;
    }

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

}
1 Like
pragma solidity 0.7.5;
contract UsersBalances {

    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

I performed a simple change where the “updateBalance” function changes the balance directly to the mapping instead of altering a memory-located variable. This doesn’t account for any require/assert statements that should be added to verify correct usage.

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

}
2 Likes

I changed memory to storage in the updatebalance function

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

}
2 Likes

hello @Pyjama_Man,
I’ve written these lines of code but it is not updating the balance and I don’t know why, could you please help me?

pragma solidity 0.8.14;
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{
    uint previousBalance = users[id].balance;
    
    User storage user = users[id];
    user.balance = balance;
     
    assert(users[id].balance == previousBalance + balance);
}

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

}

1 Like

depends on what you want update balance to do your assert is throwing an error because you are setting the
user.balance = balance;
to new balance not adding to previous balance so the code you want to have is
user.balance += balance;
or if you want to just overwrite the balance then assert should be
assert(users[id].balance == balance);

thanks I understand the problem now

1 Like

If we want to modify any storage data within the functions, we should define the data as a storage data in the function because any data variable in the function parameter section and function’s content section is memory type data.


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

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

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

I just replaced memory with storage since you need to permanently store the new mapping data in order to actually change it outside of the function updateBalance.

My solution is below:

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

I just changed the line for function updateBalance from User memory to User Storage and the getBalance function is updating.

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

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

}

//There are two ways actually)

1 Like

I changed “memory” to “storage” in the “updateBalance” function.

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

My solution was to update the State Variable directly with the input provided from updateBalance function.

Solution below:

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

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

}
1 Like

Have 2 questions.

I understand the 2 solutions have no difference in the expected outcome of the function.

First question is, if I use solution 1, does it mean that I now have a new variable user in the state variablestorage that can be used in other functions? Can i simply use user(uint id) somewhere else in the code now?

Second question is, since solution 2 does not create a new state variable, or some new kind of mapping for user = users[id] in persistent storage, does it cost less gas to compute function for solution 2, or even cost less gas for the whole contract that contains solution 2 vs solution 1? i’m just assuming here less calculations / less storage memory used would cost less gas - is this assumption correct?

Solution 1:

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

Solution 2:

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

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 {
    uint data = id ;
    users[id].balance += balance; 
}

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

}

the variable user just exist inside the function body and it will be removed once the execution of the function finished.

Indeed, the solution 2 might use less gas than the sol1, you can try creating both functions with a name like updateBalanceS and updateBalance where S will use the variable storage, then you can run each on remix and check the gas used by each of them. :nerd_face:

Carlos Z

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 {
        //The following does not work to update the user's balance 
        // because 'user' is only in memory
         //User memory user = users[id];
         //user.balance = balance;

         users[id].balance = balance; // this does update the balance
    }

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