Memory v calldata
Memory
Used for storing variables that are only needed temporarily during the execution of a function, and cannot be accessed outside the function.
can be used for both declaring function parameters and within function logic
mutable (variable values are modifiable)
non-persistent (the value does not persist after the transaction has completed)
Calldata
Calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.
used to hold function arguments passed in from an external caller; user or another contract.
immutable: calldata is read-only and cannot be modified by the function.
calldata is cheaper than memory.
memory vs calldata
By declaring
calldata
, you can avoid the overhead of copying data intomemory
and reduce the amount of gas needed to execute the function. [CALLDATALOAD]
memory
is more expensive thancalldata
. Because, it will copy the data from calldata into local memory, as an additional step. [CALLDATACOPY]
Why bother using memory then?
We cannot modify
calldata
; read-onlyIf you need to modify function arguments that are stored in
calldata
, you must first copy them intomemory
.So in this scenario, we are better served declaring
myBytes
asmemory
Alternatively
memory can be cheaper than calldata if you need to do modifications to the external data passed to the function.
use
calldata
when you are not going to modify the value of the variable passed ascalldata
inside the function.
If you only need to read the data, you can save some gas by storing it in calldata.
More on calldata
calldata
is where data from external calls to functions are stored.calldata
contains parameters of a function as allocated by the external callermsg.data
of an external call is held incalldata
A byte of calldata costs either 4 gas (if it is zero) or 16 gas (if it is any other value).
In external calls to functions (when passing parameter string), opt to use calldata
string
, instead of memory
string
.
Gotcha!
One gotcha on this is that if you pass in a string (or bytes) from an internal function, where you had just created that string in memory, then you can't use calldata
here.
Example
when execution moves from line 4 to 5, it is not an external call. There is no
msg.data
that holdscalldata
to be passed intocallFunction
so in the absence of msg.data, there is no calldata that can be accessed.
Why is calldata cheaper?
calldata are only parameters of a function which is declared as external, which value is allocated by the caller, that's why it's gas cost is lower.
EXCEPTION: Layer-2
In the context of a rollups/layer-2, calldata goes from the cheapest resource to the most-expensive resource.
Links
Last updated