Solidity Data locations | storage — memory — calldata

Al-Qa'qa'
Coinmonks
3 min readAug 15, 2023

--

Photo by Freepik on Freepik

Data location is an important topic in programming field, where you need to know where are your variables stored, and how can you access it.

In solidity, which is the programming language used to write smart contracts on Ethereum virtual machine, you have three options where you can store you variables, these options are:

  • storage
  • memory
  • calldata

We will discuss the difference between them, and when to use each on of them.

Storage

In storage all state variables are stored (the variables that are declared on contract level), here is an example:

contract MyContract {
uint256 public myNumber; // this variable is in storage by default
}

Storage means that the variable is stored in the blockchain, where each contract has its own separate storage space, which is in the form of an array of 2^256 32-byte values, all initialized to zero.

Memory and Calldata

Otherwise, memory and calldata are used to store temporary variables, variables that are needed in function scope only.

You can think of it like storage is the Hard Disk that uses to store data permanently, while memory and calldata are the RAM which stored temporarily.

Ok, what is the difference between them?

The difference is: in memory you can modify the data (change the value of the variable), but in calldata you can’t (you can just read the value), let’s take an example:

function printHelloName(string memory _name)
public
pure
returns (string memory)
{
_name = string.concat("Hello ", _name);
return _name;
}

In this example we changed _name value and returned it, and the function worked without any problems.

function printHelloName(string calldata _name)
public
pure
returns (string calldata)
{
_name = string.concat("Hello ", _name); // TypeError: Type literal_string "hello" is not implicitly convertible to expected type string calldata.
return _name;
}

If you tried to make it using calldata it will give you an error, since calldata can’t be changed.

You can use calldata if you will not change the variable, as in the following example:

function printHelloName(string calldata _name)
public
pure
returns (string calldata)
{
return _name;
}

In this example, we are not changing the variable _name value, so you can make it of type calldata, and you can make return type calldata, since you are returning only _name variable.

NOTE: return type can differs from the parameter value type, here is an example:

function printHelloName(string calldata _name)
public
pure
returns (string memory)
{
return string.concat("Hello" ,_name);
}

As you can see, we didn’t make any change to _name variable, so we made it of type calldata , but on the otherside, the returned value is not of type calldata now, as we are returning "Hello" + _name, so we should make the return string of type memory.

Another thing you should now is that any calldata can be of memory type since calldata is more restricted than memory, so you can use memory. But you can not replace memory by calldata.

Recap

  • Solidity data locations are: storage, memory, and calldata
  • storage is for storing variables permanently in the blockchain
  • memory and calldata are used to store temporary variables
  • You can edit memory variable type not calldata
  • Any calldata can be memory and not vice verca

--

--

Al-Qa'qa'
Coinmonks

Smart Contract Auditor | Smart Contract Security Researcher