Nice solution @B_S
Yes … that works
Yes, that also works, but as you would already have assigned the new balance to the local user
variable’s balance property in what would be your line 18 …
user.balance = balance;
… you can just add …
users[id] = user;
to your line 19 instead. But whichever of these two versions you use, your chosen solution is better because …
- It is more concise and, in my opinion, clearer.
- It doesn’t create a separate copy of the
User
instance, which is stored in the mapping, and which we want to update with the new balance. Using a localmemory
variable creates a separate copy of theUser
instance and therefore consumes more gas. As well as being more concise, your chosen solution will also consume less gas.
Yes …basically, the mapping is being directly updated when you assign the new balance to the local storage
variable user
…
user.balance = balance;
This is how it works …
In the first line of code in the function body, by assigning users[id]
to a local storage
variable, we create a local “pointer” called user
. The important thing to understand here is that this “pointer” does not create an additional, separate state variable, and it also doesn’t create and store a copy of the User
instance mapped to the id
(key) input into the function .
Instead, the pointer only references this User
instance in the mapping, creating a temporary “bridge” to the mapping during execution of the function.
Any value which is assigned to a property of the local “pointer” (user
) …
user.balance = balance;
… is effectively updating 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” is lost when the function finishes executing.
So hopefully you can now see why the getBalance function successfully retrieves the new balance with this alternative solution as well.
In fact, even though the code is quite different, the low level operations performed by this method (using a local storage
variable as a “pointer”) are effectively the same as those performed by your chosen solution …
users[id].balance = balance;
Hopefully, my explanation above enables you to understand why this is so. As a result, both of these solutions consume more or less the same amount of gas.
So, you may now be wondering, why bother to create a pointer with a local storage
variable. From within a function, it is certainly simpler and more concise to just assign data to persistent storage by referencing a mapping directly, as we do with users[id].balance = balance;
However, sometimes using a local storage
variable as a pointer can be a useful intermediate step when performing more complex operations involving multiple properties and their values: it can help us to set our code out into separate logical steps, making it easier to read and understand.
Let me know if anything is still unclear, or if you have any further questions