Data Location Assignment [OLD]

Hey all help required. I have a guess tho that on this contract bellow, i would need to assign the updated balance to the momory? The reason i presume the new updated balance is not showing is because its not getting stored in memory?

i have tried to add it in to the contract bellow but im getting Sytax error on the line…

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];
// MY EDIT IS BELLOW
         user memory .balance = balance;
    }

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

}

Thanks all.

Rob.

1 Like

Two possible solutions

  1. Use users[id].balance to update the balance directly
    function updateBalance(uint id, uint balance) public {
        users[id].balance = balance;
    }
  1. Change memory to storage in first line of updateBalance function
    function updateBalance(uint id, uint balance) public {
         User storage user = users[id];
         user.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);
    }
//Change memory to storage. This is because when you assign a storage type to
//a memory type, it will copy the data but it will not reflect in the storage
//mapping itself. It is only local for that methdod. So when you call another
//method the update wasn't dont on the actual user but on a copy of it. 
    function updateBalance(uint id, uint balance) public {
         User storage user = users[id];
         user.balance = bal;
    }

    function getBalance(uint id) view public returns (uint) {
        return users[id].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 memory user = users[id];
         //user.balance = balance;
         users[id].balance = balance;
    }

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

}

@filip Is it possible to set a string function parameter to stack storage instead of memory? If not, why not?

Hey @cryptoHawk, hope you are great.

I do not understand quite well your question, you mean why is not possible to use storage instead of memory for an string argument in a function?

Storage is like RAM, mean the data will be saved in a memory location that will be deleted after the function end his process.
While memory is to save data into the blockchain, then it will be available for other functions or contracts to ask data on it (if it’s public or external).

Carlos Z.

image

The reason why our balance never updated is because we never assigned the new value of the memory object (temporary object) to the main users mapping list. We had defined a local struct User object of memory inside the function meaning any updates made to this object will be lost after the function has finished executing, including the object itself.

To ensure the value of the User object inside the function is reflected inside the mapping list we have in storage we must take the temporary object’s balance and assign it to the User object inside the mapping list at the same id.

The most simple solution would’ve been to not even create a temporary object inside the function and instead only do:

image

We would achieve the same fix but with fewer lines of code and it’s more efficient as we save space in memory.

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 {

//change memory to storage so that the balance will be saved permanently as the state variable
     User storage user = users[id];
     user.balance = balance;
}

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

}

1 Like

No, I mean stack. Like this:

// State variable
string myName;

function setName(string stack newName) {
  myName = newName;
}

I’m wondering because filip said that stack was cheaper than memory storage.

did i do good @thecil? lol almost there with this one pal. Storage was the right way

1 Like

I solved this in two different ways, just to see if I could come up with different methods.

Solution 1:
Here I commented out the memory variable, and instead modified the next line to include the mapping reference directly.

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

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

}

Solution 2:
Here I changed the memory data location to the storage data location.

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

}

The problem both solved was to change the function from storing the changes in memory to storing the changes in storage.

The only thing I changed is from ‘memory’ to ‘storage’ inside of ‘updateBalance’ function. It works fine.

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

}

Hey rob, sorry to take that long to reply.

you almost have it man, you miss type on your function updateBalance, your syntax is not correct.

user memor .balance = balance;

should be users[id].balance = balance

Carlos Z

1 Like

i think my syntax ingerneral is poor. Its a complete new language to me. Once i finish up these courses ill go back and do all Programming courses again. I have a year subscription. I Have signed up for some Hackathon challenges on Polkadot to test my beginner skills. Im not being challenged enough on the exams its too easy for me to move on after a task. This on the other hand should give me more of a challenge. There is a wee one thats asking me to deploy a Solidity Smart Contract on Plasm Network. Lets see if i can do it within the time frame.

Remix would not compile it until the issue was fixed, and I just wasn’t sure so went straight to the solution. I used the second solution Filip proposed. I realize I have some work to do, I’m not understanding this as much as the JavaScript which I was very good at, but I think if I just move on I will get better. Sorry to have jumped straight to the solution, I think I need to do some more background reading and studying. Hopefully just persisting I will become more familiar with Solidity.

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

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

}

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 is better to use storage over memory. Storage is better for updating while the memory is used once the function is done.

The issue of not updating the balance is because of the usage of key word “memory” with the object User which was initiated and stored in the storage in the the function updateBalance.

Changing the key word “memory” to “storage” in the the function updateBalance can update the properties of the User obj in the storage and fix the issue!!

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

1 Like

I found 3 solutions:

function updateBalance1(uint id, uint balance) public {
     // 1. solution
     User memory user = users[id];
     user.balance = balance;
     users[id] = user;
}

function updateBalance2(uint id, uint balance) public {
     // 2. solution
     users[id].balance = balance;
}

function updateBalance3(uint id, uint balance) public {
     // 3. solution
     User storage user = users[id];
     user.balance = balance;
}
2 Likes

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