Data Location Assignment [OLD]

Replaced memory with storage seems to do the trick.

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

As you still could do it the traditional way as below, I am not yet completely convinced by storage keyword is needed.

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 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

pragma solidity 0.5.1;
contract DataAssignment1 {

mapping(uint => User) private 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

I just updated the updateBalance function. Removed the memory lane and just updated users[id].balance = balance;

1 Like

Hi @cherokee
You can do both:
Directly assign the value in your struct so you will update your contract storage.
users[id].balance=balance;
Or
explicitly writing in your smart contract that the variable you are modifying is a storage variable
User storage user = users[id];

By using memory you are declaring the user variable only locally

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 {
         users[id].balance = balance;
    }

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

}
1 Like

I just changed the User memory user = users[id]; in the following code User storage user = users[id];.
Then the updates will be stored. Another solution is deleting the whole line and direct change the variable in the mapping.

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

I spent thirty minutes looking to find a solution thinking “there is no way i only have to replace memory with storage, I must be missing something” :joy: Sometimes simple solutions work fine I guess

Edit: I watched the video solution, that’s even a better solution, I didn’t think about it!

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

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;
}

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

}

1 Like

to be honest i just found the answer in google.
I still don’t quite understand at this point in time why i cannot just use “users[id] = User(id, balance)” again in the updateBalance function to replace the existing value in the struct as an update.

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

My solution and your second options aswell


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 {
         users[id].balance = balance;
         //User storage user = users[id];
        // user.balance = balance;
    }

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

}

1 Like
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;
    }

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

}

It didn’t compile so I ran other blocks, discovered it was a compiler error,
so I changed the pragma to 5.12 and it compiled.

Tbh, with the code I just knew the data change wasn’t persistent,
so I started by changing a memory to storage and it worked.
I’ll go back and see if I can figure anything lese out before I watch the next vid.

1 Like

in the updateBalance function, the code creates a struct variable “user” that is per definition memory, so lost after the function is executed.
Right: 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;
}

}

I simply replaced memory with storage since the get update functions calls users[id].balance and users[id] after the updated balance is not saved to the system scope or storage. Resulting in the original balance being the only recognizable.

1 Like


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

1 Like

This line

User memory user = users[id];

is creating a new instance in memory with the data contained in the map “users”.

Then in the next line :

user.balance = balance;

the new instance is modified assigning the new balance BUT the real data contained in the map is never updated.

Then my solution is:

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;
}

}

Just change the data location from memory to storage.

1 Like
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

Hey @Stiefin! Welcome to the course! I hope you’re enjoying it and learning loads :slightly_smiling_face:
Your answer is actually the cheapest of the possible alternatives in terms of gas :ok_hand: Nice one!

By the way, I noticed you tried to format your code, but it didn’t work. In case you didn’t know, before you enter your code, you need to click on the </> icon in the menu at the top of the text editor. You will see 2 sets of 3 back ticks.
```
```
If you now input your code between these, you will end up with nicely formatted code, which is then also easier for you to organise with the correct spacing and indentation etc. You should then end up with something like:

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