Variables
There are three types of variables in Solidity:
- Global variables
- Provide information about the blockchain
- For example,
block.number
,block.timestamp
, ormsg.sender
- 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
References:
https://docs.soliditylang.org/en/v0.7.6/units-and-global-variables.html
https://solidity-by-example.org/variables
Data Types
There are two types of data:
- Value types:
YourContract
,address
,bool
,uint256
,int256
,enum
, andbytes32
(fixed-size byte arrays) - Reference types:
array
,mapping
, andstruct
It's worth noting that bytes
and string
are dynamically-sized byte arrays and are considered reference types. However, byte
(bytes1
), bytes2
, ..., bytes32
are value types since they're fixed-size byte arrays.
References:
https://docs.soliditylang.org/en/v0.7.6/types.html#value-types
https://docs.soliditylang.org/en/v0.7.6/types.html#reference-types
Data Location
When using a reference type, you must explicitly provide the data location where the type is stored. There are three data locations:
storage
is where the state variables are stored, and its lifetime is the lifetime of the contractmemory
means variables are temporary and erased between external function callscalldata
behaves mostly likememory
, but is immutable
For reference types in function arguments, you must declare them as memory
or calldata
.
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.
References:
https://docs.soliditylang.org/en/v0.7.6/types.html#data-location
https://medium.com/coinmonks/solidity-storage-vs-memory-vs-calldata-8c7e8c38bce
https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc
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.
References:
https://medium.com/newcryptoblock/best-practices-in-solidity-b324b65d33b1
Assignment Behaviour
- Assignments between
storage
andmemory
(or fromcalldata
) always create an independent copy. - Assignments from
memory
tomemory
only create references. - Assignments from
storage
to a local storage variable also only assign a reference. - All other assignments to
storage
always copy.
References:
https://docs.soliditylang.org/en/v0.7.6/types.html#data-location-and-assignment-behaviour