Nice solution @R0bert
… and good to see you back here in the forum! … I hope you’re enjoying the course
Nice solution @R0bert
… and good to see you back here in the forum! … I hope you’re enjoying the course
Was afraid this would take me the whole day, just tried to change ‘memory’ to ‘storage’ (so it’s stored permanently) and it worked!
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;
}
}
Turns out I was WAYY over thinking this at first.
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;
}
}
Great being back! Finally some time to get back to coding !
Hello:D
This took me longer than expected. Got the right answer in the first 15min but struggled to compile, deploy and trigger the right contract in remix I noted that today haha what a fail guys
Anyway, finally I got it.
Since we are just asked to update the balance, I didn’t add the incoming balance to the existing one also I would do that in a diffrent function called addFunds or something like this
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.11;
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;
}
}
// SPDX-License-Identifier: undefine
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 {
User memory user = users[id];
user.balance = balance; // change balance
// user.balance += balance; // increment balance
users[id]=user;
}
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;
}
}
Nice solution @Bensen
Good point
In fact, 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 add an amount to the user’s existing balance instead. So, I would still just have the one updateBalance() function — changing its name to addFunds() if you want — and replace the assignment operator =
in the second line of code …
… with an addition assignment operator +=
user.balance += balance;
In addition, if we add to, instead of replacing, the existing balance, I think the code will look clearer and more readable if we also change the name of the balance
parameter to amount
, because we are adding an amount to the balance, rather than replacing it with a new balance …
function updateBalance(uint id, uint amount) public {
User storage user = users[id];
user.balance += amount;
}
There is always more than one solution to these assignments, and alternative interpretations are equally valid and to be encouraged. You can always add comments to your code to explain anything you’ve done a bit differently or are unsure about
Just let me know if you have any questions.
Nice alternative solutions, @LELUK911
Even though you probably realised that the initial idea of this assignment is to update the existing balance by replacing it with the new one (your main solution), I actually think that it makes more sense to do what you’ve shown in your in-line comment as an alternative, and add an amount to the user’s existing balance using the addition assignment operator +=
(instead of the assignment operator =
).
However, if we add to, instead of replacing, the existing balance, I think the code will look clearer and more readable if we also change the name of the balance
parameter to amount
, because we are adding an amount to the balance (to give a new total balance), rather than replacing it with the new total balance.
Just let me know if you have any questions
Hi @imran82,
Your solution won’t compile and you should have got a red compiler error for this line …
This is because you are trying to assign the new balance to the balance property of an undefined user
variable. You either need to first define user
in a line of code above, or directly reference the User
instance (the user’s record) in the mapping and assign the new balance to that.
Have a go at correcting this. Let me know if you have any questions, or if you need any more help
i am not able to compile because new remix version doesnt let me to compile with older version
Try activating Auto Compile (mark the Auto Compile box under Compiler Configuration in the Solidity Compiler panel in Remix).
Remix should then automatically select the correct compiler version (0.7.5) in the Compiler field at the top of the Solidity Compiler panel. If it doesn’t, then you can manually select it from the dropdown.
If, for some reason, you only have one compiler version available to you in this dropdown (e.g. the latest, 0.8.11) then just change your contract’s pragma statement to this same version.
You need to be able to compile your contracts, otherwise you won’t identify any errors. You also won’t be able to deploy your contracts if they haven’t been compiled.
If you can only compile with the latest version (v0.8), you can still do the course with this version instead of v.0.7.5 (used in the videos). There is only one syntax change in v.0.8 that affects this course, which I can explain to you if necessary. Just let me know.
Thanks for help. Now remix id is working properly. It was giving error as i was using struct instead of mapping. Now i have updated it
function updateBalance(uint id, uint balance) public {
users[id].balance = balance;
}
Thanks for pointing it out. I hope you will help me out in future also.
so my original explanation was wrong.
but my code was right so yay?!
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 {
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 {
User storage user = users[id]; // use storage instead of memory for referen to location of storage user
user.balance = balance;
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
In the updateBalance function, store the User data in storage instead of memory. Data stored in memory will not persist after their function scope finishes. Data stored in storage will persist after the function finishes executing.
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 @DeMarco_Saunders
… and welcome to the forum! I hope you’ve been enjoying the course
What was your original explanation? … and do you now understand how the solution you’ve chosen (with the local storage variable) works? You’ll find a full explanation in this post.
Just let me know if you have any questions.
Nice solution @fooku
… and welcome to the forum! I hope you’ve been enjoying the course
You definitely have the right idea here
When we define the data location of a local variable as storage
, this creates a storage pointer . This references the value already saved in persistent storage which is assigned to it: in our case users[id]
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.