Value Types in Solidity
Variables that belong to value types are always copied when they are used in an assignment or as a function argument.
They comprise:
- boolean: bool,
- integers: int and uint,
- [fixed point numbers],
- addresses: address and address payable,
- contract types,
- fixed-size byte arrays,
- dynamically-sized byte arrays,
- literals (address literals, rational and integer literals, string literals, hexadecimal literals),
- enums,
- function types
Reference Types [Topic]
Reference types are referenced by their name. You might get no copy of the reference type, depending on where it is stored. Instead, you modify the original data. Every reference type contains information where it is stored. There are three possible options: memory, storage, and calldata.
Assignments between different locations create a copy. If you, for example, assign a variable stored in memory to a variable in storage, a copy is created.
A reference means that changes to one variable are also visible in all other variables that refer to this data location.
The following assignment rules apply:
- Assignments between storage and memory (or from calldata) always create an independent copy.
- Assignments from memory to memory create a reference.
- Assignments from storage to local storage create a reference.
- All other assignments to storage create a copy.
You can read about this in more detail in the documentation: https://docs.soliditylang.org/en/v0.8.4/types.html#data-location-and-assignment-behaviour
You can test this with the following code. There, we create two arrays that we store in memory. We assign array1 to array2 and change a value in array2. Then we return array1. The result is that array1 mirrors the change we made to array2.
pragma solidity 0.8.20;
contract locationTest{
function createArray() public returns(uint8[3] memory){
uint8[3] memory memoryArray1 = [0,1,2];
uint8[3] memory memoryArray2 = memoryArray1;
memoryArray2[0] = 4;
return memoryArray1;
}
}
And here is an example for the assignment from storage to local storage:
pragma solidity 0.8.20;
contract locationTest{
uint[3] public storageArray1 = [0,1,2];
function localStorage() public{
uint[3] storage localStorageArray = storageArray1; // creates a reference
localStorageArray[0] = 4;
}
}
Reference types comprise:
- arrays,
- array slices,
structs