Data Location Assignment [OLD]

Yes, that’s right, @Obi :ok_hand:
It’s one of several possible alternatives. If you take a look at some of the other student posts in this discussion thread, you’ll be able to see the others :slight_smile:

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

}

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

Nice solution @fayemui :ok_hand:
And welcome to the forum — good to see you in here! I hope you’re enjoying this course. If you have any questions or are unsure about anything, check out the discussion threads here as you’ll find lots of useful information. But if you can’t find what you’re looking for, then please post your question and we’ll do our best to help you out :slight_smile:

1 Like

pragma solidity 0.5.1;

contract MemoandStorage {

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

On line 16, the updateBalance function should use storage to persist the balance change. When using memory, the updatedBalance would be held only for the function execution and not persisted.

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

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

}

My fix directly updates the state variable user mapping instead of modifying a new local variable.

1 Like

I simply changed the memory to storage in the update function, which makes the code work, but I suspect there may be a more elegant way.

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

I just changed the state variable directly, because this way you will change a variable, which is storage by default.

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

}
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;
}
}type or paste code here
1 Like

Hi @gabor

There are several other alternatives (which you will find by taking a look at some of the other posts here in this discussion topic) — but I’ll let you be the judge of whether they are more “elegant” or not :wink:

1 Like

Nice solution @mickymax777 :ok_hand:

I particularly like your unusual use of type or paste code here syntax at the end of the contract. Nice alternative! :wink: :laughing:

1 Like

whahaha, typo :sweat_smile:

1 Like

image

i should have commented out extra part related to the variable user :grin: :sweat_smile:

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

}

1 Like

Initially I changed the data location type in the updateBalance function from memory to storage and it did work. However, after reading some responses in the forum I went back and changed the updateFunction to modify the mapping directly instead of creating a local user variable.

This solution costs less ETH than changing the data location to storage.

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

}

1 Like

After some trial and errors I found two solutions:

solution number 1: The update balance function is performed but results are only stored in the memory and lost after the execution of the function. Thus, the results of the functions need to be pushed to the user map. Therefore, add a push instruction to the function.

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

Solution number 2: The update balance function is performed but results are only stored in the memory and lost after the execution of the function. Change memory into storage.

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

1 Like

It was the data location that had to be changed.

Changed User memory user = users[id]; to User storage user = users[id];

1 Like