I have seen people use both memory
and calldata
keywords when writing Solidity. Specifically, they are used when declaring function parameters.
When should I use memory
and when should I use calldata
?
Ethereum Stack Exchange is a question and answer site for users of Ethereum, the decentralized application platform and smart contract enabled blockchain. It only takes a minute to sign up.
Sign up to join this communityI have seen people use both memory
and calldata
keywords when writing Solidity. Specifically, they are used when declaring function parameters.
When should I use memory
and when should I use calldata
?
memory
and calldata
(as well as storage
) are keywords that define the data area where a variable is stored. To answer your question directly, memory
should be used when declaring variables (both function parameters as well as inside the logic of a function) that you want stored in memory (temporary), and calldata
must be used when declaring an external function's dynamic parameters.
The easiest way to think about the difference is that calldata
is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.
Breaking this down, let's first look at memory
. memory
's lifetime is limited to a function call and is meant to be used to temporarily store variables and their values. Values stored in memory
do not persist on the network after the transaction has been completed. Some notable implementation details about memory are as follows:
This answer is a great resource to understand memory.
calldata
is very similar to memory in that it is a data location where items are stored. It is a special data location that contains the function arguments, only available for external function call parameters. From the Solidity docs:
Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.
This is the cheapest location to use, but it has a limited size. In particular, that means that functions may be limited in their number of arguments.1 Notable implementation details about calldata
are as follows:
The following is a valid example of code using memory
and calldata
:
pragma solidity 0.5.11;
contract Test {
string stringTest;
function memoryTest(string memory _exampleString) public returns (string memory) {
stringTest = "example"; // You can modify memory
string memory newString = stringTest; // You can use memory within a function's logic
return stringTest; // You can return memory
}
function calldataTest(string calldata _exampleString) external returns (string memory) {
// cannot modify or return _exampleString
}
}
One good way to think about the difference and how they should be used is that calldata
is allocated by the caller, while memory
is allocated by the callee.