There are three types of variables in Solidity:
- Global variables
- Provide information about the blockchain
- For example,
- State variables
- Declared outside a function
- Stored on the blockchain
- Also called "storage"
- Local variables
- Declared inside a function
- Not stored on the blockchain, stored in memory instead
- Erased between function calls
There are two types of data:
- Value types:
bytes32(fixed-size byte arrays)
- Reference types:
It's worth noting that
string are dynamically-sized byte arrays and are considered reference types. However,
bytes32 are value types since they're fixed-size byte arrays.
When using a reference type, you must explicitly provide the data location where the type is stored. There are three data locations:
storageis where the state variables are stored, and its lifetime is the lifetime of the contract
memorymeans variables are temporary and erased between external function calls
calldatabehaves mostly like
memory, but is immutable
For reference types in function arguments, you must declare them as
If possible, use
calldata as the data location because it avoids copying, reduces gas usage, and ensures that the data cannot be modified. Arrays and structs with
calldata data location can also be returned from functions, but it is not possible to allocate such types.
It is also a best practice to use
external if you expect that the function will only ever be called externally, and use
public if you need to call the function internally. The difference between both is that
public function arguments are copied to
memory, while in
external functions, arguments are read directly from
calldata, which is cheaper than memory allocation.
external functions are sometimes more efficient when they receive large arrays.
- Assignments between
calldata) always create an independent copy.
- Assignments from
memoryonly create references.
- Assignments from
storageto a local storage variable also only assign a reference.
- All other assignments to