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:
storageis where the state variables are stored, and its lifetime is the lifetime of the contractmemorymeans variables are temporary and erased between external function callscalldatabehaves 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
storageandmemory(or fromcalldata) always create an independent copy. - Assignments from
memorytomemoryonly create references. - Assignments from
storageto a local storage variable also only assign a reference. - All other assignments to
storagealways copy.
References:
https://docs.soliditylang.org/en/v0.7.6/types.html#data-location-and-assignment-behaviour