Additional Solidity Concepts - Discussion

thanks for advise and explanation.

1 Like

My solution, which appears to work in testing:
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

Nice solution @chrisdbarnett :ok_hand:
… and welcome to the Academy forum! Great to see you here :slightly_smiling_face:

2 Likes

Hey Filip,
There is a discrepancy between the video and the code on github.
I expect you did this deliberately to keep us awake!
In the code its:

emit personDeleted(name, senior, owner);

In the video it’s:

emit personDeleted(name, senior, msg.sender);

This is the version that works.
Don’t ask me why, I’m just a student.

When do I get to build my crypto!

DOODESVILLE :nerd_face:

Hello Community!

I’m sorry if the topic was already covered above or if it’s for another section, but couldn’t find it so:

If I understood correctly, Filip mentioned in one of the videos that it’s not a good idea to use references like this

Person person = people[something];
person.property1 = newValue;
…some other modifications on person
people[something] = person;

Could you please confirm if that’s correct and elaborate me why is that so? @jon_m

1 Like

Hi Rusko,

This may refer to the Data Location Assignment, and the following possible solution (one of several alternatives):

function updateBalance(uint id, uint balance) public {
    User memory user = users[id];
    user.balance = balance;
    users[id] = user;            // added to update mapping
}

This is a very long-winded way of achieving the desired result. There is redundant code, and it is more costly on gas.

On the 3rd line of the function body, the value held temporarily in the local variable (user) is assigned to the mapping (users[id]). There is therefore no reason to also assign the data initially held in the mapping (referenced using users[id]) to the local variable (user) in the 1st line when defining it. If we are going to use a local variable stored in memory, we can simply define it initially, on the 1st line, as:

User memory user;

However, creating a separate local variable in memory still uses more gas than just changing memory to storage…

User storage user = users[id];
user.balance = balance;

… because this code doesn’t actually create a separate variable, but instead establishes a reference (a “pointer”) to the User instance stored in the mapping, and then uses this pointer to assign the new balance to this User instance in the 2nd line. In fact, this solution can also be made more concise as follows:

users[id].balance = balance;

This performs exactly the same operation, achieves the same result, and consumes the same amount of gas as the two-line solution using storage above. You can read more about
the reasoning and logic behind this here.

I hope this helps to clarify the issues, concepts and considerations with this code.

Just let us know if you have any further questions about this. :slight_smile:

3 Likes

:grinning: Hello all. Thanks for being here.

2 Likes

Accidentally posted my solution here instead of the correct place. My bad… :frowning:

1 Like

Thanks for correcting @Jethrodog :slight_smile:

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


}
1 Like

Changed to storage.

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

}
1 Like

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

}

1 Like

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; 
     // you could also just directly write users[id].balance = balance;
}

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

}

1 Like

Hey @filip

So, i figured out that it was a memory issue, and the updateBalance needed to be changed (only from you stating that we needed to look at the datalocation).

I still don’t think it works properly as the balance is just updated, not added to my previous inputted balance, unless that wasn’t the point ?

Thanks,
Jonathon

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

Hello,
I’m a little confused about temporary storage when defining variables within a function. Are all variables defined within a function stored in memory? If you create a string variable within a function is it automatically stored in memory??

Thanks,
Brian Y

1 Like

Hey @Brian_Y, hope you are ok.

All functions that have internal variables that will do something on their logic, are stored on the bytecode of the EVM (blockchain), but do not confuse the term “memory” with the memory syntax of solidity.

these are the data location used on solidity:

  • memory: whose lifetime is limited to an external function call
  • storage: the location where the state variables are stored, where the lifetime is limited to the lifetime of a contract
  • calldata: special data location that contains the function arguments.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

can u break it down on how u determine if it memory or storage u will input
how do u tell it memory or storage i didn’t really get the video

1 Like

do storage only work for uint

1 Like

pretty simple, when you need to save some data in the blockchain, you use storage. (permanently storage)

Use memory when you need to storage data just for few moments (like creating a variable that only will get data based on blockchain) to then be used to produce a different result.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

I must say im proud of myself for this 1. I had absolutely no coding experience before coming to the academy and until now ive always just settled for learning how coding works instead of actually trying to write code of my own. it took me weeks of reviewing notes and studying additional info to start being able to start from nothing and see the code in my mind. It was a lot of work for 1 line of code and after finally getting it right I see how simple the answer was but going back and taking the time to solve the problem on my own was worth it.

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=_user.balance;
}

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

}

1 Like