Solidity Data Storage Locations Comparison

Solidity Data Storage Locations Comparison

Storage vs Memory vs Calldata

Β·

3 min read

Solidity is a programming language that is specifically designed for smart contracts on the Ethereum blockchain. One important aspect of Solidity is the concept of storage locations. In Solidity, variables can be stored in three different locations: storage, memory, and calldata. Each of these locations has its own unique characteristics, and it is important for Solidity developers to understand how each of them works. In this blog post, we will compare storage vs memory vs calldata in Solidity with examples.

Storage

Storage is a permanent storage location that is written to the blockchain. Variables stored in storage are persistent and can be accessed by any function within the contract. However, accessing variables in storage is more expensive than accessing variables in memory, as it requires a read or write to the blockchain.

Here is an example :


contract Example{

uint256[] arr = [1,2,3,4,5];

//Gas Used: 4642
function func3 () view external { 
    uint result = 0;
  for (uint i = 0; i < arr.length; ++i) {
     result += i;
  }
}
}

Memory

Memory is a temporary storage location that is used to store variables during contract execution. Variables stored in memory are not persistent and are lost when the function execution ends. Accessing variables in memory is less expensive than accessing variables in storage.


contract Example{
uint256[] arr = [1,2,3,4,5];
//Gas Used : 3902
function func1 (uint[] memory nums /*nums=[1,2,3,4,5]*/) pure external { 
    uint result = 0;
  for (uint i = 0; i < nums.length; ++i) {
     result += i;
  }
}
}

Also, it is worth noting that while using memory, a copy of the variables is created, whereas in storage only a reference/pointer of that variable is created.

Calldata

Calldata is a temporary storage location that is used to pass arguments to a function.

You should try to use calldata wherever possible but keep in mind is read-only and cannot be modified by the function.

Accessing variables in calldata is least expensive than accessing variables in storage or memory.

Here is an example of a Solidity function that uses calldata:

contract Example{
 // Gas Used: 2416
function func2 (uint[] calldata nums /*nums=[1,2,3,4,5]*/) pure external { 
    uint result = 0;
  for (uint i = 0; i < nums.length; ++i) {
     result += i;
  }
}
}

Conclusion

Summing up,


contract Example{

uint256[] arr = [1,2,3,4,5];

function func1 (uint[] memory nums) pure external { // 3902
    uint result = 0;
  for (uint i = 0; i < nums.length; ++i) {
     result += i;
  }
}

function func2 (uint[] calldata nums) pure external { // 2416
    uint result = 0;
  for (uint i = 0; i < nums.length; ++i) {
     result += i;
  }
}

function func3 () view external { //4642
    uint result = 0;
  for (uint i = 0; i < arr.length; ++i) {
     result += i;
  }
}
}

Solidity provides three different storage locations: storage, memory, and calldata.

Storage is a permanent storage location that is written to the blockchain and is more expensive to access than memory or calldata.

Memory is a temporary storage location that is used to store variables during contract execution and is less expensive to access than storage.

Calldata is a temporary storage location that is used to pass arguments to a function and is the least expensive to access.

By understanding the differences between these storage locations, Solidity developers can write more efficient and effective smart contracts.

Β