-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
140 additions
and
3 deletions.
There are no files selected for viewing
5 changes: 3 additions & 2 deletions
5
...-implementations/4-2-variable-storage-in-storage/4-2-1-uint8-uint128-uint256.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...rc/4-yul-implementations/4-2-variable-storage-in-storage/4-2-10-custom-types.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Custom Types | ||
|
||
A custom type or a user-defined value type allows you to create an alias of a native type in Solidity. This alias, will inherit and act as if it is the original type. It is defined by using the `type C is V syntax`, where `C` is the custom type, and `V` is the native type. To convert from the underlying type to the custom type, `C.wrap(<value>)` is used, and to convert from the custom type to the native underlying type, `C.unwrap(<value>)` is used [[6](https://docs.soliditylang.org/en/latest/types.html#user-defined-value-types)]. | ||
|
||
Custom types behave like their underlying types. | ||
|
||
```solidity | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
contract Yul { | ||
type CustomTypeUint8 is uint8; // Will behave like uint8. | ||
type CustomTypeUint256 is uint256; // Will behave like uint256. | ||
type CustomTypeInt128 is int128; // Will behave like int128. | ||
type CustomTypeAddress is address; // Will behave like address. | ||
type CustomTypeBytes4 is bytes4; // Will behave like bytes4. | ||
type CustomTypeBytes32 is bytes32; // Will behave like bytes32. | ||
// Slot 0. | ||
CustomTypeUint256 public customType = CustomTypeUint256.wrap(12000); | ||
// Slot 1. | ||
uint256 public underlyingType = CustomTypeUint256.unwrap(customType); | ||
function getCustomType() public view returns (bytes32) { | ||
assembly { | ||
mstore(0x80, sload(0x00)) | ||
return(0x80, 0x20) | ||
} | ||
} | ||
function getUnderlyingType() public view returns (bytes32) { | ||
assembly { | ||
mstore(0x80, sload(0x01)) | ||
return(0x80, 0x20) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
> 🚨 You cannot define custom types for `bytes` and `string`. |
70 changes: 70 additions & 0 deletions
70
...entations/4-2-variable-storage-in-storage/4-2-11-uint8[]-uint128[]-uint256[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# `uint8[]`, `uint128[]`, `uint256[]` | ||
|
||
Up till now, we've learnt about individual data types in Solidity and how they are stored in storage. Before we proceed to their array counterparts, we would want to go over how arrays are viewed in Solidity storage generally. This view is applied to all other types. | ||
|
||
Solidity recognizes two types of arrays, the fixed length array and the dynamic array. These two array types are | ||
treated differently by Solidity. | ||
|
||
## Fixed Arrays, `<type>[n]` | ||
|
||
Solidity views `<type>[n]` array elements as individual values. Which means that, these values are treated as if they | ||
were | ||
not in an array. If a `uint256[5]` array has 5 elements, they will occupy 5 slots, in their correct places. | ||
|
||
```solidity | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
contract Yul { | ||
// Slots 0 - 4. | ||
uint256[5] public fixedArray; | ||
// Slot 5. | ||
uint8[6] public fixedSmallArray; | ||
} | ||
``` | ||
In the code above, the `fixedArray` variable occupies 5 slots. This is because, it contains 5 `uint256` values. In | ||
Solidity, because the length of the array is fixed (in this case, 5), Solidity knows how much in storage to allocate | ||
for the storage of each individual value. It is seen as if they're 5 `uint256` values kept side by side. | ||
|
||
The `fixedSmallArray` occupies one slot, because, as explained, it will be seen as 6 `uint8` values kept side by | ||
side and they, like we have already discussed, will be packed into one slot. | ||
|
||
## Dynamic Arrays, `<type>[]` | ||
|
||
Dynamic arrays are stored just like fixed arrays, when it comes to packing, but in terms of knowing **where** in | ||
storage to store the array, a little bit of calculation is done. Because the length is dynamic, Solidity does not | ||
know how much space to allocate for the storage, therefore, the storage of a dynamic array starts at `keccak256(slot) | ||
`. Meaning that, if a dynamic array is declared at slot 0, the first element will be found `keccak256(0)`. | ||
|
||
To read the value of the other array elements from storage, they will be obtained by loading the storage at | ||
`keccak256(slot) + elementIndex`. Meaning that, if we had the above dynamic array that grew to 10 elements, and we | ||
would | ||
like to retrieve the value of the 9th element, it would be found at `keccak256(0) + 9`. | ||
|
||
```solidity | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
contract Yul { | ||
// Slot 0. | ||
uint256[] public dynamicArray; | ||
// Slot 1. | ||
uint8[] public dynamicSmallArray; | ||
} | ||
``` | ||
|
||
The values of the elements in the dynamicArray variable can be found at `keccak256(0) + elementIndex`. While the | ||
values for the `dynamicSmallArray` will be found at `keccak256(1)`, we didn't add any `elementIndex` here because | ||
the elements of `dynamicSmallArray` will be packed in one slot because they're `uint8` and will be packed. If they are | ||
more than enough to fit into the next slot, then, we can load the next storage location. | ||
|
||
## General `<type>[]` Deduction. | ||
|
||
Once the concept of type storages is understood, you can use that to figure out how the array versions of that type | ||
will be stored. | ||
|
||
You can use the knowledge of arrays to write to any array index, or read from an array index. | ||
|
||
To retrieve an element from a packed array is quite trick and is not readily advised. | ||
|
||
> 🚨 The use of Yul to read and write arrays is not advised. It is a very tricky business. |
3 changes: 3 additions & 0 deletions
3
...lementations/4-2-variable-storage-in-storage/4-2-12-int8[]-int128[]-int256[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `int8[]`, `int128[]`, `int256[]` | ||
|
||
Combine the knowledge of [int8, int128 and int256](4-2-2-int8-int128-int256.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
3 changes: 3 additions & 0 deletions
3
...ntations/4-2-variable-storage-in-storage/4-2-13-bytes1[]-bytes16[]-bytes32[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `bytes1[]`, `bytes16[]`, `bytes32[]` | ||
|
||
Combine the knowledge of [bytes1, bytes16, bytes32](4-2-3-bytes1-bytes16-bytes32.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
3 changes: 3 additions & 0 deletions
3
book/src/4-yul-implementations/4-2-variable-storage-in-storage/4-2-14-bytes[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `bytes[]` | ||
|
||
Combine the knowledge of [bytes](4-2-4-bytes.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
3 changes: 3 additions & 0 deletions
3
book/src/4-yul-implementations/4-2-variable-storage-in-storage/4-2-15-string[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `string[]` | ||
|
||
Combine the knowledge of [string](4-2-5-string.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
3 changes: 3 additions & 0 deletions
3
book/src/4-yul-implementations/4-2-variable-storage-in-storage/4-2-16-address[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `address[]` | ||
|
||
Combine the knowledge of [address](4-2-6-address.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
3 changes: 3 additions & 0 deletions
3
.../4-yul-implementations/4-2-variable-storage-in-storage/4-2-17-custom-types[].md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `Custom Types[]` | ||
|
||
Combine the knowledge of [Custom Types](4-2-10-custom-types.md) with [arrays](4-2-11-uint8%5B%5D-uint128%5B%5D-uint256%5B%5D.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters