Memory vs Storage | copy vs reference — Solidity
Persistent and temporary data storage.
Hey guys, in this blog I’ll be explaining memory and storage, which are two out of three areas where the Ethereum virtual machine stores data, behaves when they are accessed in a function and how we can write/access them — copy & reference. While initialising a variable in a function, we must specify where we are storing this data of the variable we are accessing.
Let me start by loosely explaining the two —
Storage
Persistent data area that can be called from within and outside the functions and also during transactions. Kind of like a global variable.
Memory
Temporary data that gets wiped out after a function call and has limited scope in its respective function.
We’ll be looking into 4 scenarios where either of the data areas accesses each other.
1. storage → memory
2. memory → storage
3. storage → storage
4. memory → memory
1. storage → memory
contract Test{
uint[] arrayStorage = [2]; function test( uint[] memory arrayMemory ) public returns ( uint[] memory, uint[] memory ){
arrayStorage = arrayMemory;
arrayStorage.push(4);
return ( arrayStorage, arrayMemory )
}}
Here, we are first initialising the arrayStorage
to [2]. We are calling the function test by passing an empty memory array → test ( [] ).
Then we are assigning the memory array ( here → [] ) to the storage array.
arrayStorage = []
After this, we are pushing a number ( arrayStorage.push(4)
)into the storage array.
arrayStorage = [4]
Lastly, we return the values —
arrayStorage = [4]
arrayMemory= []
2. memory → storage
contract Test{
uint[] arrayStorage = [2];function test( uint[] memory arrayMemory ) public returns ( uint[] memory, uint[] memory ){
arrayMemory= arrayStorage;
arrayStorage.push(4);
return ( arrayStorage, arrayMemory )
}}
Similarly, We are calling the function test by passing an empty memory array → test ( [] ). Since we can’t push to a memory array we’ll be pushing to the storage array arrayStorage.push(4);
. Then we are assigning the storage array ( here → [2] ) to the memory array.
arrayMemory = [2]
Lastly, we return the values —
arrayStorage = [2,4]
arrayMemory= [2]
3. storage → storage
contract Test{
uint[] arrayStorage = [2];function test( ) public returns ( uint[] memory, uint[] memory ){
uint[] storage localArrayStorage;
localArrayStorage = arrayStorage;
localArrayStorage.push(6);
arrayStorage.push(4);
return ( arrayStorage, localArrayStorage);
}}
Here, we are first initialising the arrayStorage
to [2] outside the function. After calling the function test(), firstly we define a new array localArrayStorage
. Next, we assign the arrayStorage
to the local storage array → localArrayStorage
localArrayStorage = [2]
After this, we push [4] into the localArrayStorage
and we push [6 ] into the arrayStorage
.
arrayStorage = [2,4,6]
localArrayStorage= [2,4,6]
As we have assigned a storage array to another storage array, any change in either of the arrays will reflect on both arrays.
4. memory → memory
contract Test{
uint[] arrayStorage = [2];function test( uint[] memory memoryArray ) public view returns ( uint[] memory, uint[] memory ){
uint[] memory localArrayMemory;
localArrayMemory= memoryArray;
memoryArray = arrayStorage;
return (localArrayMemory, memoryArray );
}}
Here, we are first initialising the arrayStorage
to [2] outside the function. After calling the function test( [] ) → passing the memory array as [], firstly we define a new array localArrayMemory. Next, we assign the arrayOfMemory
to the local memory array → localArrayMemory.
In this case, any change to either of the memory arrays before assigning themselves to each other ( localArrayMemory
→ memoryArray
or memoryArray
→localArrayMemory
) will not reflect either array, they remain independent.
localArrayMemory= []
memoryArray= [2]
Conclusion:
Storage arrays when assigned to another storage array are assigned by reference ( pointer ) and change in either of them will affect both the storage arrays. Memory arrays, when assigned to storage and vice-versa are assigned by copy. Lastly, when a memory array is assigned to another memory array, it is assigned by copy and no change happens on changing either of the arrays.
Thank you :) ❤️