Memory vs Storage | copy vs reference — Solidity

Moid Khan
CoinsBench
Published in
3 min readJul 22, 2022

--

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 memoryArraylocalArrayMemory ) 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 :) ❤️

--

--

CSE grad | Front end & Blockchain Dev. Looking to make the next best thing in web3 :)