Data Location Assignment


pragma solidity 0.7.5;
pragma abicoder v2;

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

I came to the conclusion that we don’t save the it in memory we must save it in storage. I have saved it in storage but it doesn’t change anything for me. Here is my code. What did I do wrong?

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.balance = balance;
        
    }

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

}

Please help.

You can simply remove “view” from the getBalance function and it will work like you want. When using view it means the function output is view-only, and you cannot change it.

EDIT: I thought I had the solution but this is incorrect. I must have pressed something else.
Here is my edited code:

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

The balance needs to be stored as persistent data instead of temporary, which is why we need to use storage instead of memory in the updateBalance function. Like Filip also said we can do this:

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

By changing the mapping directly it does the same thing as if we had used the storage data location

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

In this case if you are saving it to storage, you need to change “users.balance” to “user.balance”
Otherwise if you want change the mapping directly, you would use “users[id].balance”
Mods please correct me if I am wrong :sweat_smile:

Hey @FreeSpirit2222

You use both:

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

Or (even better)

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

Cheers,
Dani

Change memory to storage under updateBalance function.

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
diff --git a/memory-assignment.sol b/memory-assignment.sol
index 2f59127..e965700 100644
--- a/memory-assignment.sol
+++ b/memory-assignment.sol
@@ -13,8 +13,7 @@ contract MemoryAndStorage {
     }
 
     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) {

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

}

Here is my soluton where I set users[id].balance (from structure which is state and it saves into a storage) = balance (which is input of function updateBalance). So I did not save storage variable in memory, because it won’t be able to see after function is done. Memory variables are temporary saved, just within function. And the function getBalance just returns value that we input in updateBalance function.

1 Like

I keep getting this error

creation of MemoryAndStorage errored: Cannot convert undefined or null to object

when I try to deploy the contract on remix

edit, I just reloaded chrome and it’s fine now. weird

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

Very simple solution that updated the balance correctly at least ^^

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]; //Just changed "User memory user" to "User storage user"
         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;
    }

}

I write new balance directly into mapping

1 Like

Changed the data location type in the updateBalance function. Another option would have been to just recreate a new variable with the new input data in the updateBalance function :


function updateBalance(uint id, uint balance) public {
users[id] = User ( 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 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; //dictionary of users, index points to User type

    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]; //if memory, this changes nothing as memory is cleared at end of function
         User storage user = users[id]; //change memory to storage so value can actually be changed, this becomes pointer to actual value
         
         //another option is to change balance directly (since it is a state variable)
         //users[id].balance = balance;
         
         user.balance = balance;
    }

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


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 storage user = users[id];
        user.balance = balance;
    }
    
    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }
}
1 Like

The user was never saved, and the balance was overwritten before.

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

Edited, thought of it as adding to the balance xD

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

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