Skip to content

Commit

Permalink
📝 Review.
Browse files Browse the repository at this point in the history
  • Loading branch information
0xfps committed Jun 9, 2024
1 parent 9d650ea commit 9466e20
Show file tree
Hide file tree
Showing 14 changed files with 19 additions and 20 deletions.
2 changes: 1 addition & 1 deletion book/src/1-introduction/1-1-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ This is a book about Yul, a low-level, intermediate language written alongside S

Over the course of this book, we are going to go through what Yul is, why it is important, its advantage and disadvantage over Solidity and its implementations in a smart contract.

Also, we will see how storage and memory are laid out in Solidity and how we would harness the power of Yul to infiltrate and modify to our taste.
Also, we will see how storage and memory are laid out in Solidity and how we would harness the power of Yul to infiltrate and modify these to our taste.

Enjoy!
2 changes: 1 addition & 1 deletion book/src/1-introduction/1-2-what-is-yul.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ similar in many ways to Assembly but with higher-level features that make it eas

Yul was previously called **Julia** or **Iulia**.

Within the context of smart contract development, Yul is usually referred to as **Inline Assembly**. As it is very
Within the context of smart contract development, Yul is usually referred to as **Inline Assembly**, as it is very
similar to Assembly and is written within functions in smart contract code.
4 changes: 2 additions & 2 deletions book/src/1-introduction/1-3-why-is-yul-important.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

---

During smart contract development process, there are actions, or manipulations which are not feasible for the
During the smart contract development process, there are actions, or manipulations which are not feasible for the
programmer from the high-level Solidity code. Using Yul, the programmer is given much more fine-grained control over
the storage, memory and in some cases calldata layout of the EVM. This control also allows for much more gas efficient code to be written.
the storage, memory and in some cases `calldata` layout of the EVM. This control also allows for much more gas efficient code to be written.

The flexibility and gas optimization of Yul are what makes it important.
2 changes: 1 addition & 1 deletion book/src/1-introduction/1-4-yul's-advantages.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

---

As stated in the [previous chapter](1-3-why-is-yul-important.md), the ability to manipulate the storage, memory or calldata layout to the programmer's taste with an extra benefit of much more gas optimized code is Yul's major advantage over Solidity.
As stated in the [previous chapter](1-3-why-is-yul-important.md), the ability to manipulate the storage, memory or `calldata` layout to the programmer's taste with an extra benefit of much more gas optimized code is Yul's major advantage over high-level Solidity.
2 changes: 1 addition & 1 deletion book/src/1-introduction/1-6-code-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ Every piece of Yul code written here can be rerun on [Remix](https://remix.ether

Remix is an online smart contract development suite. It also offers a way of observing the process of EVM layouts and storage. It will be used over the course of this book, and you can replicate whatever we have done here on the suite.

It is also recommended that you keep [evm.codes](https://evm.codes) handy over your course of learning and practising Yul, and even after you've understood. It is a magnificent resource.
It is also recommended that you keep [evm.codes](https://evm.codes) handy over your course of learning and practising Yul, and even after you've understood the language. It is a magnificent resource.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
We have understood what the storage and memory are. Persistent and temporary, respectively. Now we are going to take a look at how these two data storage locations are laid out.

### Storage
Solidity's storage layout has a finite amount of space, which is broken down into 32-byte groups called `slots`, and each slot can hold a 256-bit value. These slots start from index 0 and can stretch to a theoretical index limit of somewhere around `(2^256) - 1`. It is safe to say that the storage can never get full. Cool, isn't it?
Solidity's storage layout has a finite amount of space, which is broken down into 32-byte groups called `slots`, and each slot can hold a 256-bit value. These slots start from index 0 and can stretch to an index limit of `(2^256) - 1`. It is safe to say that the storage can never get full. Cool, isn't it?

Values stored in storage slots are stored as `bytes32` values, and sometimes, can be packed, as we will see later on in this book. To retrieve the value of a Solidity storage variable, the 32-byte value stored in the corresponding slot is retrieved. In some cases - when the value in the slot has been packed -, the value retrieved is worked on by methods of shifting or masking to retrieve the desired value.

Expand All @@ -14,7 +14,7 @@ Values stored in storage slots are stored as `bytes32` values, and sometimes, ca
### Memory
Solidity's memory layout, unlike the storage layout is quite tricky. While the storage has a defined maximum slot
index of
`(2 **256) - 1` that can hold 32-byte values, the memory is a large group of 32-byte slots that their data can not
`(2^256) - 1` that can hold 32-byte values, the memory is a large group of 32-byte slots that their data can not
be retrieved by passing a slot index. But instead, data stored in the memory are retrieved by picking
a particular location and returning a specific number of bytes from that point in the memory.

Expand All @@ -25,7 +25,7 @@ You can imagine memory slots as laid out end to end, in a way that data retrieva
stopped at any point. Unlike storage that returns only the 32-bytes stored at an index, nothing more, nothing less.

If you do not understand that, do not
sweat it. You will get a better grasp of it when we talk about [variable storage in memory]().
sweat it. You will get a better grasp of it when we talk about [variable storage in memory](../4-yul-implementations/4-3-variable-storage-in-memory/4-3-0-variable-storage-in-memory.md) section.

These positions in memory start from `0x00` and are in groups of 32-bytes, meaning that the slots are in th is way:

Expand All @@ -51,6 +51,5 @@ for dynamic memory arrays and should never be written to (the free memory pointe
> 💡 It is safest to use `mload(0x40)` to get the next free memory pointer when trying to store data to memory as
> storing in a memory location with existing data overwrites that location.
> 💡 The positions we will use over the course of this book to access memory points will be written in hexadecimals
> (`0x**`)
as it's easier to read, since the EVM already deals in hexadecimals.
> 💡 The positions and values in memory that we will use over the course of this book to access memory points will be written in hexadecimals
> (`0x**`) as they are easier to read, since the EVM already deals in hexadecimals.
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ contract Yul {
}
```

> 🚨 Yul does not recognize global variables, it only recognized local variables within functions, function parameters and named `return` variables.
> 🚨 Yul does not recognize Solidity global or state variables, it only recognized local variables within functions, function parameters and named `return` variables.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

---

Solidity stores variables declared globally in storage. The storage is made up of slots, as we've discussed earlier. In this section we will look at how different data types are stored in Solidity's storage. Some are packed and some are greedy enough to take up a full slot without sharing.
Solidity stores variables declared globally, otherwise known as state variables in storage. The storage is made up of slots, as we have discussed earlier. In this section we will look at how different data types are stored in Solidity's storage. Some are packed and some are greedy enough to take up a full slot without sharing.

You can head into the start of the section at [uint8, uint128, uint256](4-2-1-uint8-uint128-uint256.md).
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ In a function, to return a value loaded from the storage, without declaring a re

> `return(position, size)`
If we called the `getUint8` function to return a `uint8`, Solidity will handle the conversion for us and we will see `16` returned. However, we will be returning in bytes32 over the course of this book to understand the actual storage and memory layouts of the EVM.
If we called the `getUint8` function to return a `uint8`, Solidity will handle the conversion for us and we will see `16` returned. However, we will be returning in `bytes32` over the course of this book to understand the actual storage and memory layouts of the EVM.

Calling the `getUint8` function will return `0x0000000000000000000000000000000000000000000000000000000000000010`, which when converted to decimal, equals to `16`, the value we stored.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

---

While `uint[n]` types can only contain positive integers, the `int[n]` types can contain both positive and negative numbers. As you know, `int[n]` variables store numbers ranging from `-1 -> -(2 ^ (n-1))` on the negative side, and `0 -> (2^n) - 1` on the positive side. This means that for the three `int[n]` types specified above, this would be their minimum and maximum values.
While `uint[n]` types can only contain positive integers, the `int[n]` types can contain both positive and negative numbers. As you know, `int[n]` variables store numbers ranging from `-1 -> -(2 ^ (n-1))` on the negative side, and `0 -> ((2^n) - 1)` on the positive side. This means that for the three `int[n]` types specified above, this would be their minimum and maximum values.

| **`int[n]` type** | **Minimum Value** | **Maximum Value** |
|-------------------|-------------------|-------------------|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ This will return `0x00000000000000000000000000000000000000000000000000000000aabb

Setting a `bytes[n]` variable in a function will right-pad it to 32 bytes. Whereas, directly assigning the variable in a Yul block or in storage will handle it normally by left padding it.

To get a knowledge of which type of `bytes[n]` does what, refer to [this part of the book](../4-3-variable-storage-in-memory/4-3-3-bytes1-bytes16-bytes32.md#padding).

### bytes16
```solidity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ We're going to store a pretty long `bytes` value now.

```solidity
// SPDX-License-Identifier: GPL-3.0
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract MyContract {
Expand Down Expand Up @@ -180,7 +179,7 @@ the first 32 bytes of the value we stored, while, `getSecondBytesSection` would
it only contains values for the first 8 bytes. Using both data, we can see that our `bytes` value was spread out
across two storage slots. We can try to concatenate them and return all the bytes, but that would involve moving
them into memory, and then returning the proper ABI encoded memory data for the `bytes`. We would look at that when
we get to the [Variable Storage In Memory]() section of this book.
we get to the [Variable Storage In Memory](../4-3-variable-storage-in-memory/4-3-0-variable-storage-in-memory.md) section of this book.

> 💡 `bytes` and `string` share the same characteristics in storage and memory. The same way `bytes` are stored in
storage and memory, that is the same way `string` are stored. The only differences are that each `string` character is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

---

A `struct` is a group of data. The layout of a `struct` is identical to the layout of the data within a `struct`. The slots a `struct` would occupy is dependent on the types of variables within the struct. A struct with two uint256 types would occupy two slots.
A `struct` is a group of data. The layout of a `struct` is identical to the layout of the data within a `struct`. The slots a `struct` would occupy is dependent on the types of variables within the struct. A struct with two `uint256` types would occupy two slots.

```solidity
// SPDX-License-Identifier: GPL-3.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

---

`delegatecall(a, b, d, e, f, g)` functions exactly the way `delegatecall()` functions in Solidity. It takes the same arguments `call` takes except the `msg.value`.
`delegatecall(a, b, d, e, f, g)` functions exactly the way `staticcall()` functions in Solidity. It takes the same arguments `call` takes except the `msg.value`.

It is called exactly the same way [`staticcall`](4-4-17-staticcall.md) is called, with the same arguments, and returns the same value as well.

0 comments on commit 9466e20

Please sign in to comment.