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;
}
}```
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.7.5;
contract MemoryAndStorage {
mapping (uint => user) userList; // used different naming for ease of use
struct user{
uint id;
uint balance;
}
function addUser(uint id,uint balance) public {
userList[id] = user(id,balance);
}
function updateUser(uint id,uint balance) public{
userList[id].balance = balance;
}
function getbalance(uint id) view public returns(uint){
return userList[id].balance;
}
}
pragma solidity 0.7.5;
contract UsersBalances {
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 performed a simple change where the “updateBalance” function changes the balance directly to the mapping instead of altering a memory-located variable. This doesn’t account for any require/assert statements that should be added to verify correct usage.
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 changed memory to storage in the updatebalance function
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;
}
}
hello @Pyjama_Man,
I’ve written these lines of code but it is not updating the balance and I don’t know why, could you please help me?
pragma solidity 0.8.14;
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{
uint previousBalance = users[id].balance;
User storage user = users[id];
user.balance = balance;
assert(users[id].balance == previousBalance + balance);
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
depends on what you want update balance to do your assert is throwing an error because you are setting the
user.balance = balance;
to new balance not adding to previous balance so the code you want to have is
user.balance += balance;
or if you want to just overwrite the balance then assert should be
assert(users[id].balance == balance);
thanks I understand the problem now
If we want to modify any storage data within the functions, we should define the data as a storage data in the function because any data variable in the function parameter section and function’s content section is memory type data.
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 memory user = users[id];
// user.balance = balance;
users[id].balance = balance;
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
I just replaced memory with storage since you need to permanently store the new mapping data in order to actually change it outside of the function updateBalance.
My solution is below:
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;
}
}
I just changed the line for function updateBalance from User memory to User Storage and the getBalance function is updating.
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];
users[id].balance = balance;
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
//There are two ways actually)
I changed “memory” to “storage” in the “updateBalance” function.
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;
}
}```
My solution was to update the State Variable directly with the input provided from updateBalance
function.
Solution below:
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; // solution
// User memory user = users[id];
// user.balance = balance;
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
Have 2 questions.
I understand the 2 solutions have no difference in the expected outcome of the function.
First question is, if I use solution 1, does it mean that I now have a new variable user
in the state variablestorage that can be used in other functions? Can i simply use user(uint id)
somewhere else in the code now?
Second question is, since solution 2 does not create a new state variable, or some new kind of mapping for user = users[id]
in persistent storage, does it cost less gas to compute function for solution 2, or even cost less gas for the whole contract that contains solution 2 vs solution 1? i’m just assuming here less calculations / less storage memory used would cost less gas - is this assumption correct?
Solution 1:
function updateBalance(uint id, uint balance) public {
User storage user = users[id];
user.balance = balance;
}
Solution 2:
function updateBalance(uint id, uint balance) public {
users[id].balance = 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 {
uint data = id ;
users[id].balance += balance;
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}
the variable user
just exist inside the function body and it will be removed once the execution of the function finished.
Indeed, the solution 2 might use less gas than the sol1, you can try creating both functions with a name like updateBalanceS
and updateBalance
where S
will use the variable storage, then you can run each on remix and check the gas used by each of them.
Carlos Z
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 {
//The following does not work to update the user's balance
// because 'user' is only in memory
//User memory user = users[id];
//user.balance = balance;
users[id].balance = balance; // this does update the balance
}
function getBalance(uint id) view public returns (uint) {
return users[id].balance;
}
}