pragma solidity 0.8.7; contract MemoryAndStorage { struct User{ uint id; uint balance; } // state variable - using storage mapping(uint => User) Users; // PUBLIC // addUser creates a new user with the passed in _id and _balance, // adding them to the users state variable. function addUser(uint _id, uint _balance) public { // only add if the user doesn't exist require(!_userExists(_id), "user already exists, please use updateBalance()"); Users[_id] = User(_id, _balance); _assertUserBalance(_id, _balance); } // updateBalance will modify a users balance if the passed in user // _id is found. function updateBalance(uint _id, uint _balance) public { _requireUserExists(_id); Users[_id].balance = _balance; _assertUserBalance(_id, _balance); } // getBalance returns the users balance if the passed in user _id // is found. function getBalance(uint _id) view public returns (uint) { _requireUserExists(_id); return Users[_id].balance; } // PRIVATE // _userExists verifies if the passed in user _id is found or not. function _userExists(uint _id) private view returns(bool) { User memory u = Users[_id]; if (u.id == 0) { return false; } return true; } // _assertUserBalance verifies the user.balance matches the passed // in _balance. function _assertUserBalance(uint _id, uint _balance) private view { assert(_userExists(_id)); assert(Users[_id].balance == _balance); } // _requireUserExists requires that the passed in user _id is found // in users. function _requireUserExists(uint _id) private view { require(_userExists(_id), "User doesn't exist, please create the user first."); } }