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;
}
}
Switch keyword memory to storage. So the problem was that memory was only saving user balance while the function ran ,so anything happening after was not getting saved. Replacing memory with storage allows the user balance data to persist over time and function executions.
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;
}
}
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]; // replace memory to storage
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;
}
}
Nice solution @Renz
… and it’s good to see you back here in the forum! I hope you’re enjoying the course
On the whole, your explanation is good. Here are some additional comments …
It was a temporary copy of the whole User
struct instance (stored in the mapping) which was first stored in memory …
User memory user = users[id];
Then, the new balance was assigned to the balance property of this temporary copy, where it was only saved until the function had finished executing, at which point it was lost …
user.balance = balance;
Yes … and it’s interesting to understand how this actually happens …
When we define the data location of a local variable as storage
, this creates a storage pointer. This only points to (references) the value already saved in persistent storage which is assigned to it (in our case users[id]
); it doesn’t create or store a separate copy of this value, as it would if we defined the data location as memory
. A storage pointer is like a temporary “bridge” during execution of the function to wherever in the contract state it points to (in our case a specific User
struct instance in the mapping).
Any value which is then assigned to a property of the local “pointer” ( user
) will effectively update that same property of the specific User
instance in the mapping which is referenced by the pointer. This enables a specific user’s balance (stored persistently in the mapping) to be reassigned with the new balance
(input into the function), before our “bridge” disappears when the function finishes executing…
user.balance = balance;
Just let me know if you have any questions.
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] = User(id,_balance);
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
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;
}
}
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;
}
}
pragma solidity 0.8.7;
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] = User(id, balance);
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
Hi @thanasornsawan,
Your solution has, effectively, made the updateBalance function exactly the same as the addUser function.
While this does still work…
I assume you’ve already seen the 2 alternative solutions suggested in the follow-up video. Can you see how they are more suitable?
You may also find this related discussion interesting, which starts in the post I’ve linked to and continues over several more.
Just let me know if you have any questions
Nice solution @firequo
… and it’s good to see you back here in the forum! I hope you’re enjoying the course
Hi @Tomaage ,
Your solution has made the updateBalance function exactly the same as the addUser function…
While this does still work…
I assume you’ve already seen the 2 alternative solutions suggested in the follow-up video. Can you see how they are more suitable?
You may also find this related discussion interesting, which starts in the post I’ve linked to and continues over several more.
Just let me know if you have any questions
Thanks Jon . I posted before I saw the solution because if it was something flawed I did not see, its good to have this forum point it out to me so I learn from it.
When I did enginering school, we had a hydrolics enigneer who would always make us install our test equipment the worng way, or les optimal wasy, so we we could see the mistake when we turned it on and everything was shaking and making strange noises, and then understand better why the correct way was more optimal.
Yes… posting your own solution, and then seeing if the feedback you get matches what you realised yourself when you checked the solution code, and having a good think through any additional points that are raised … is a great way to learn
@jon_m thank you for help describe concept.My logic not well much.
Yes,I already see the 2 alternative solutions suggested in the follow-up video.It use just property inside users.Not replace value as I do.
//solution 1
users[id].balance = balance;
//solution 2
User storage user = users[id];
user.balance = _balance;
Hi @thanasornsawan,
Both your solution and the ones shown in the follow-up video replace values. The difference is that…
-
Your solution replaced the whole
User
struct instance (the value mapped to an address key in theusers
mapping). This isn’t wrong, but as you’ve understood, it’s unnecessary. -
The two alternative solutions shown in the follow-up video replace just the
uint
value stored in the struct instance’sbalance
property.
I’m sure this is what you’ve understood, but I just wanted to clarify the correct terminology.
I hope that’s helpful
no idea but I gave it my best shot and it seems to be working to me… lol Moving on to see others and the solution in next video
Nice solution @casadcode
Just make sure that you use the more recent Solidity version 0.7.5 (as used in the course videos). It doesn’t make any difference for this assignment, but it will for the rest of the course.
Also, for your next assignments, please don’t post screen shots, because we can’t copy and paste your code in order to execute and test it, if we need to. Instead, follow the instructions in this FAQ: How to post code in the forum
Let me know if you have any questions
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;
}
}