This time, we will talk about storage locations in Solidity programming language, specifically about thestorage
andmemory
locations. Not knowing what they represent and how they work can cause issues in our smart contracts.
Storage
Storage in smart contracts holds data between function calls. We can imagine thatstorage
would be as a hard drive in the computer. Even if we turn it off, the data stays and isn't erased. On the blockchain, what we write in storage is stored.
Storage by default
State variables
By default, Solidity will keep in storage smart contract's state variables.
contractStorageContract{structLuckyNumber{uint256number;stringreason;}mapping(address=>LuckyNumber)luckyNumbers;}
In this example smart contract's state variablesluckyNumbers
are kept in storage, and data will persist between function calls.
When we add and get the lucky number, we have a predictable outcome.
functionaddLuckyNumber(LuckyNumbermemoryluckyNumber)external{require(luckyNumber.number!=0,"Lucky number can't be 0!");require(luckyNumbers[msg.sender].number==0,"You already have set lucky number. Edit it if you have another one.");luckyNumbers[msg.sender]=luckyNumber;}functiongetMyLuckyNumber()externalviewreturns(uint256){require(luckyNumbers[msg.sender].number!=0,"You don't have a lucky number set yet.");LuckyNumbermemoryluckyNumber=luckyNumbers[msg.sender];returnluckyNumber.number;}
Local function variables
Local function variables of struct, array, or mapping are saved in storage by default. It means that if we declare these values in our functions, they are kept in storage, which can cause unexpected issues that are hard to track.
If we add a functioneditLuckyNumber
to our code example and mark a local copy asstorage
it will edit the state variable that we expect.
functioneditLuckyNumber(uint256luckyNumber)external{require(luckyNumber!=0,"Lucky number can't be 0!");require(luckyNumbers[msg.sender].number!=0,"You don't have a lucky number set yet.");LuckyNumberstorage_luckyNumber=luckyNumbers[msg.sender];_luckyNumber.number=luckyNumber;}
Memory
In memory, Solidity keeps all locally defined value types, which can be uint, string, etc., but not an array, a struct, or a mapping. Function arguments are kept in memory as well. Remember thatmemory
can't be used at the smart contract level, only locally in functions.
functionmultiplyByItself(uint256number)externalpurereturns(uint256){uint256result=number*number;returnresult;}
In this example, the function argumentnumber
that we pass in our function is stored in memory. Also, locally defined variable of theresult
is stored in memory and will be released as soon as the function's execution ends.
Pitfall using memory and storage
One of the major pitfalls of wrong usage of thestorage
andmemory
keywords in the Solidity programming language is that we declare a variable eitherstorage
ormemory
without thinking it through. First, keeping data instorage
will consume more gas because we need to pay for the block space. Second, we should ask ourselves whether we need to access data that we keep between the function calls. By function calls, there can be even two different functions.
If we define the_luckyNumber
in functioneditLuckyNumber
using thememory
keyword, it will edit this function locally only, and changes won't be written to the blockchain.
functioneditLuckyNumber(uint256luckyNumber)external{require(luckyNumber!=0,"Lucky number can't be 0!");require(luckyNumbers[msg.sender].number!=0,"You don't have a lucky number set yet.");LuckyNumbermemory_luckyNumber=luckyNumbers[msg.sender];_luckyNumber.number=luckyNumber;}
This function's outcome will result in editing the lucky number not working because we update it only locally.
TL;DR
Storing data using Solidity language in our smart contracts is a crucial thing. Life is easier with value types, but with arrays, structs, and mappings, it is more tricky. That's why it is essential to ask whenever we want to save these variables. Do we want data to persist between calling the smart contract or being saved locally while executing the function?
Links
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse