Data Location Assignment [OLD]

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

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

}

The reason the balance did not update initially is because, a new User variable which is a struct created in memory each time the update is called so the balance to state variable users mapping never got called.

1 Like

Change memory to storage.

1 Like

Hi @Caspian1234,
Welcome to the forum! It’s great to see you here :smiley: I hope you’ve been enjoying this course.

Apologies for the delay in giving you feedback on this assignment.

Your solution is correct but be careful not to mix up the names:

user is the name of the local variable. You’ve also used this to reference the mapping, but the mapping is users with an s. These details are important, because your code as it is will not execute correctly.

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

Data Location Assignment.

One possible solution to The Update:

constructor(){
User = (uint id, uint balance);
}
function addUser (uint_ id, string memory uint_balance) public{
User [id] = User (id, balance);

function updateBalance (uint_ id, string memory unit_balance) public{
User memory user = user [id]
User. balance = balance;
assert (balance [User id] == Previous User balance - amount);

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

1 Like

pragma solidity 0.5.1;
contract MemoryAndStorage {

mapping(User => uint) users;

}

struct User{
    uint id;
    uint balance;
}

function addUser(uint id, uint balance) public {
    users[id] = User(id, balance);
}
/*Memory is local storage, also we are dealing with "uint and we do not need to use "memory"since it's not a string varible in the argument "storage replace "memory"*/
function updateBalance(uint id, uint balance) public {
     User storage user = new users[_id];
     user.balance = balance;
}

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

}

1 Like

I fix that using similar function for both AddUser and Update balance : P
Not specifying the data allocation will save me some bites agains the other who chose the ‘storage’ fix ?

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

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

I think I’m using the same bites as the other longer solution :
User storage user = new users[_id];
user.balance = balance;

Since this direct mapping :
users[id].balance = balance;
works with ‘uint’ and they are stored in the storage.

1 Like

Hi @simoleo,

Both alternative solutions will consume the same amount of gas with optimization turned on. This is because they are effectively performing exactly the same operations.

Maybe it’s just a slip, but adding the new keyword to the following line is incorrect:

It should be:

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

Hi @jon_m thank you for pointing these out! appreciate it

1 Like

All that needed changing was the update function THe problem with it was that it created a new local variable User object within the function. Thus any changes made to this object would be separate from the original global user. Just allowed changes to be made to the original user!

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

Thought of in a simple way, the user id information is lost each time the function is run because it goes to memory. That information needs to be put into storage.

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

I did it the lazy way let’s say :slight_smile: Changed memory to storage in function updateBalance. That did the trick.

1 Like

@Martin_Offermann

that is 100% correct. but i would like to see your code :grinning:

1 Like

Well after thinking about it for a while and trying plenty of stuff, I decided to switch memory to storage in the updateBalance function !!! Worked just fine haha.

1 Like

Hi @Tumbleur,

Correct :ok_hand:
But as @abuga says above, we would like to see your code :wink:

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

When you create a new local variable such as below - doesn’t this incur extra gas charges?

The local variable is referencing the storage address but the local variable itself (pointer to the storage address of this particular user) will incur a gas fee.

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

Therefore, isn’t it more efficient to implement the solution as follows as you’re not creating any extra local variables?:

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

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

}
1 Like