Skip to content

Commit a4595ac

Browse files
authored
upgraded docs from zkEVM to zkVM (#547)
* upgraded docs from zkEVM to zkVM * fixed scroll x ethereum differences * fees and precompile updates * fixed enfoced transactions mentions
1 parent 178e27a commit a4595ac

File tree

26 files changed

+247
-592
lines changed

26 files changed

+247
-592
lines changed

package-lock.json

Lines changed: 73 additions & 233 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/config/sidebar.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,6 @@ export const getSidebar = () => {
212212
title: t("sidebar.technology.rollupNode"),
213213
url: "technology/sequencer/rollup-node",
214214
},
215-
{
216-
title: t("sidebar.technology.zkTrie"),
217-
url: "technology/sequencer/zktrie",
218-
},
219215
],
220216
},
221217
// {

src/content/docs/en/developers/ethereum-and-scroll-differences.mdx

Lines changed: 3 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ For open-source contributors and infrastructure builders, please contact our tea
2323

2424
| Opcode | Solidity equivalent | Scroll Behavior |
2525
| --------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------- |
26-
| `BLOCKHASH` | `block.blockhash` | Returns `keccak(chain_id \|\| block_number)` for the last 256 blocks. |
2726
| `COINBASE` | `block.coinbase` | Returns the pre-deployed fee vault contract address. See [Scroll Contracts](/developers/scroll-contracts). |
2827
| `DIFFICULTY` / `PREVRANDAO` | `block.difficulty` | Returns 0. |
2928
| `SELFDESTRUCT` | `selfdestruct` | Disabled. If the opcode is encountered, the transaction will be reverted.[^willadpot] |
@@ -38,60 +37,13 @@ We support the `cancun` EVM target and the latest Solidity version `0.8.26`.
3837

3938
## EVM Precompiles
4039

41-
The `RIPEMD-160` (address `0x3`) `blake2f` (address `0x9`), and `point evaluation` (address `0x0a`) precompiles are currently not supported. Calls to unsupported precompiled contracts will revert. We plan to enable these precompiles in future hard forks.
40+
The `RIPEMD-160` (address `0x3`), `blake2f` (address `0x9`), and `point evaluation` (address `0x0a`) precompiles are currently not supported. Calls to unsupported precompiled contracts will revert.
4241

43-
The `modexp` precompile is supported but only supports inputs of size less than or equal to 32 bytes (i.e. `u256`).
44-
45-
The `ecPairing` precompile is supported, but the number of points(sets, pairs) is limited to 4, instead of 6.
46-
47-
The other EVM precompiles are all supported: `ecRecover`, `identity`, `ecAdd`, `ecMul`.
48-
49-
### Precompile Limits
50-
51-
Because of a bounded size of the zkEVM circuits, there is an upper limit on the number of calls that can be made for some precompiles. These transactions will not revert, but simply be skipped by the sequencer if they cannot fit into the space of the circuit. Read more about the [Circuit Capacity Checker](/en/technology/sequencer/execution-node#circuit-capacity-checker).
52-
53-
| Precompile / Opcode | Limit |
54-
| ------------------- | ----- |
55-
| `keccak256` | 3157 |
56-
| `ecRecover` | 119 |
57-
| `modexp` | 23 |
58-
| `ecAdd` | 50 |
59-
| `ecMul` | 50 |
60-
| `ecPairing` | 2 |
61-
{/* TODO: Add SHA256 after upgrade */}
62-
63-
64-
## State Account
65-
66-
### **Additional Fields**
67-
68-
We added two fields in the current `StateAccount` object: `PoseidonCodehash` and `CodeSize`.
69-
70-
```go
71-
type StateAccount struct {
72-
Nonce uint64
73-
Balance *big.Int
74-
Root common.Hash // merkle root of the storage trie
75-
KeccakCodeHash []byte // still the Keccak codehash
76-
// added fields
77-
PoseidonCodeHash []byte // the Poseidon codehash
78-
CodeSize uint64
79-
}
80-
```
81-
82-
### **CodeHash**
83-
84-
Related to this, we maintain two types of codehash for each contract bytecode: Keccak hash and Poseidon hash.
85-
86-
`KeccakCodeHash` is kept to maintain compatibility for `EXTCODEHASH`. `PoseidonCodeHash` is used for verifying the correctness of bytecodes loaded in the zkEVM, where Poseidon hashing is far more efficient.
87-
88-
### CodeSize
89-
90-
When verifying `EXTCODESIZE`, it is expensive to load the whole contract data into the zkEVM. Instead, we store the contract size in storage during contract creation. This way, we do not need to load the code — a storage proof is sufficient to verify this opcode.
42+
All other EVM precompiles are fully supported and behave the same as Ethereum.
9143

9244
## Block Time
9345

94-
To improve the throughput of the Scroll chain, we introduced a dynamic block time in our [Curie upgrade](/technology/overview/scroll-upgrades#curie-upgrade). During the congestion period, a block will be sealed once the transactions in the block reach the circuit limit instead of waiting for the 3-second interval. During normal hours, blocks will still be sealed at 3-second interval to ensure a consistent user experience.
46+
Scroll uses a dynamic block time to optimize throughput. During congestion periods, blocks are sealed as soon as they are full instead of waiting for the 3-second interval. During normal hours, blocks are sealed at 3-second intervals to ensure a consistent user experience.
9547

9648
## Transaction Ordering
9749

src/content/docs/en/developers/l1-and-l2-bridging/eth-and-erc20-token-bridge.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ When bridging ERC20 tokens, you don’t have to worry about selecting the right
2828
All Gateway contracts will form the message and send it to the `L1ScrollMessenger` which can send arbitrary messages to L2. The `L1ScrollMessenger` passes the message to the `L1MessageQueue`. Any user can send messages directly to the Messenger to execute arbitrary data on L2. This means they can execute any function on L2 from a transaction made on L1 via the bridge. Although an application could directly pass messages to existing token contracts, the Gateway abstracts the specifics and simplifies making transfers and calls.
2929

3030
<Aside type="tip" title="">
31-
In future upgrades, users will be able to bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue`. If a message is sent
32-
via the `L1MessageQueue`, the transaction's sender will be the address of the user sending the transaction, not the
33-
address of the `L1ScrollMessenger`.
31+
Users can bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue` using the `EnforcedTxGateway` contract. When a message is sent this way, the transaction's sender on L2 will be the address of the user, not the address of the `L1ScrollMessenger`.
3432
</Aside>
3533

3634
When a new block gets created on L1, the Watcher will detect the message on the `L1MessageQueue` and will pass it to the Relayer service, which will submit the transaction to the L2 via the l2geth node. Finally, the l2geth node will pass the transaction to the `L2ScrollMessenger` contract for execution on L2.

src/content/docs/en/developers/transaction-fees-on-scroll.mdx

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,29 @@ when the sequencer commits the data to L1.
8181

8282
As mentioned, the `L1GasPriceOracle` is used to estimate the L1 gas fee given raw transaction data. This is a **push oracle**, updated by a relayer run by Scroll.
8383

84-
The data fee is based on multiple factors:
84+
<Aside type="note" title="Fee Calculation Changes">
85+
The L1 data fee calculation has evolved through several network upgrades:
86+
- **Pre-Curie**: Based on calldata gas costs
87+
- **Curie**: Introduced blob-based data availability with `commitScalar` and `blobScalar`
88+
- **Feynman**: Added compression penalty factor
89+
- **Galileo**: Updated penalty calculation formula
90+
</Aside>
91+
92+
#### Post-Curie Fee Calculation (Current)
8593

86-
- The bytes which are `zeros` and `nonzeros` of an RLP-encoded transaction with Signature
87-
- `l1BaseFee` - Current base fee on the L1
88-
- `overhead` - Additional gas overhead of a data commitment transaction
89-
- `scalingFactor` - A scaling factor used to account for price spikes
90-
- `PRECISION` - A constant used to scale the final fee
94+
Since the [Curie upgrade](/technology/overview/scroll-upgrades/curie-upgrade), transaction data is stored in blobs, and the fee is calculated as:
9195

92-
The following steps are taken to calculate the L1 data fee:
96+
```javascript
97+
l1Fee = (commitScalar * l1BaseFee + blobScalar * txDataLength * l1BlobBaseFee) / PRECISION
98+
```
9399

94-
1. Read three fields `l1BaseFee`, `overhead`, `scalar` from the `L1GasPriceOracle` contract. The slots for these fields in the contract are:
100+
Where `PRECISION = 1e9`.
95101

96-
| Field | Slot |
97-
| --------- | ---- |
98-
| l1BaseFee | 1 |
99-
| overhead | 2 |
100-
| scalar | 3 |
102+
#### Pre-Curie Fee Calculation (Legacy)
103+
104+
Before Curie, the fee was based on calldata gas costs:
105+
106+
1. Read three fields `l1BaseFee`, `overhead`, `scalar` from the `L1GasPriceOracle` contract.
101107

102108
2. Count the number of zero bytes and non-zero bytes from the transaction.
103109
3. Calculate the L1 data fee, given `TX_DATA_ZERO_GAS = 4` and `TX_DATA_NON_ZERO_GAS = 16`[^eip-2028] and `PRECISION = 1e9`:
@@ -119,31 +125,63 @@ The following steps are taken to calculate the L1 data fee:
119125
function overhead() external view returns (uint256);
120126
```
121127

122-
Returns the current L1 fee overhead
128+
Returns the current L1 fee overhead (used in pre-Curie fee calculation).
123129

124130
#### scalar
125131

126132
```solidity
127133
function scalar() external view returns (uint256);
128134
```
129135

130-
Returns the current l1 fee scalar
136+
Returns the current L1 fee scalar (used in pre-Curie fee calculation).
131137

132138
#### l1BaseFee
133139

134140
```solidity
135141
function l1BaseFee() external view returns (uint256);
136142
```
137143

138-
Returns the latest known l1 base fee
144+
Returns the latest known L1 base fee.
145+
146+
#### l1BlobBaseFee
147+
148+
```solidity
149+
function l1BlobBaseFee() external view returns (uint256);
150+
```
151+
152+
Returns the latest known L1 blob base fee (introduced in Curie upgrade).
153+
154+
#### commitScalar
155+
156+
```solidity
157+
function commitScalar() external view returns (uint256);
158+
```
159+
160+
Returns the current L1 commit fee scalar (introduced in Curie upgrade).
161+
162+
#### blobScalar
163+
164+
```solidity
165+
function blobScalar() external view returns (uint256);
166+
```
167+
168+
Returns the current L1 blob fee scalar (introduced in Curie upgrade).
169+
170+
#### penaltyFactor
171+
172+
```solidity
173+
function penaltyFactor() external view returns (uint256);
174+
```
175+
176+
Returns the current compression penalty factor (introduced in Feynman upgrade).
139177

140178
#### getL1Fee
141179

142180
```solidity
143181
function getL1Fee(bytes memory data) external view returns (uint256);
144182
```
145183

146-
Computes the L1 portion of the fee based on the size of the RLP encoded input transaction, the current L1 base fee, and the various dynamic parameters.
184+
Computes the L1 portion of the fee based on the size of the RLP encoded input transaction, the current L1 base fee, and the various dynamic parameters. The calculation method depends on the current network fork (pre-Curie, Curie, Feynman, or Galileo).
147185

148186
**Returns:** L1 fee that should be paid for the transaction
149187

@@ -157,9 +195,9 @@ Computes the L1 portion of the fee based on the size of the RLP encoded input tr
157195
function getL1GasUsed(bytes memory data) external view returns (uint256);
158196
```
159197

160-
Computes the amount of L1 gas used for a transaction. Adds the overhead which represents the per-transaction gas overhead of posting the transaction and state roots to L1. Adds 74 bytes of padding to account for the fact that the input does not have a signature.
198+
Computes the amount of L1 gas used for a transaction. After the Curie upgrade, this returns 0 since all transaction data is stored in blobs.
161199

162-
**Returns:** Amount of L1 gas used to publish the transaction.
200+
**Returns:** Amount of L1 gas used to publish the transaction (0 post-Curie).
163201

164202
| Parameter | Description |
165203
| --------- | ----------------------------------------------------------- |

src/content/docs/en/technology/bridge/cross-domain-messaging.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ Scroll has an arbitrary message passing bridge that enables token transfers and
2323

2424
There are two primary approaches to sending a message from L1 to L2: sending arbitrary messages via `L1ScrollMessenger` and sending enforced transactions via `EnforcedTxGateway`. Both approaches allow users to initiate a L2 transaction on L1 and call arbitrary contracts on L2. For arbitrary messages, the sender of the L2 transactions is the aliased `L1ScrollMessenger` address. For enforced transactions, the L2 sender is an externally-owned account (EOA). In addition, we provide several standard token gateways to make it easier for users to deposit ETH and other standard tokens including ERC-20, ERC-677, ERC-721, and ERC-1155. In essence, these gateways encode token deposits into a message and send it to their counterparts on L2 through the `L1ScrollMessenger` contract. You can find more details about the L1 token gateways in the [Deposit Gateways](/technology/bridge/deposit-gateways).
2525

26-
<Aside type="danger" title="">
27-
Enforced Transactions are not yet enabled on Scroll. In future upgrades, users will be able to use this functionality to bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue`.
26+
<Aside type="tip" title="">
27+
Enforced Transactions allow users to bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue`. This provides a censorship-resistance mechanism, ensuring users can always force transaction inclusion on L2.
2828
</Aside>
2929

3030
As depicted in Figure 1, both arbitrary messages and enforced transactions are appended to the message queue stored in the `L1MessageQueue` contract. The `L1MessageQueue` contract provides two functions `appendCrossDomainMessage` and `appendEnforcedTransaction` for appending arbitrary messages and enforced transactions respectively.
@@ -117,8 +117,8 @@ The deposited ETH of `value` amount is locked in the `L1ScrollMessenger` contrac
117117
118118
### Sending Enforced Transactions
119119
120-
<Aside type="danger" title="">
121-
Enforced Transactions are not yet enabled on Scroll. In future upgrades, users will be able to use this functionality to bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue`.
120+
<Aside type="tip" title="">
121+
Enforced Transactions allow users to bypass the `L1ScrollMessenger` and send messages directly to the `L1MessageQueue`. This provides a censorship-resistance mechanism, ensuring users can always force transaction inclusion on L2.
122122
</Aside>
123123
124124
The `EnforcedTxGateway` contract provides two `sendTransaction` functions to send an enforced transaction. In the first function, the sender of the generated `L1MessageTx` transaction is the transaction sender. On the other hand, the second function uses the passed `sender` address as the sender of the `L1MessageTx` transaction. This allows a third party to send an enforced transaction on behalf of the user and pay the relay fee. Note that the second function requires providing a valid signature of the generated `L1MessageTx` transaction that matches the `sender` address. Both `sendTransaction` functions enforce the sender to be an EOA account.

src/content/docs/en/technology/chain/accounts.mdx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,15 @@ whatsnext: { "Transactions": "/en/technology/chain/transactions/" }
1111

1212
Same as Ethereum, Scroll has two account types: Externally-owned account (EOA) and contract account that holds the smart contract and additional storage.
1313

14-
Scroll stores additional information of the contract bytecode in the account to facilitate the zkEVM circuit to prove the state transition more efficiently.
15-
16-
The account in Scroll contains the following fields:
14+
The account structure in Scroll follows the standard Ethereum format:
1715

1816
- `nonce`: A counter that indicates the number of transactions sent by the sender.
1917
- `balance`: The balance of `ETH` token in the account (unit in wei).
20-
- `storageRoot`: The root hash of the storage trie. Since Scroll uses the [zkTrie](/technology/sequencer/zktrie) for the storage trie, the `storageRoot` stores the Poseidon hash digest in a 256-bit integer.
18+
- `storageRoot`: The root hash of the storage trie.
2119
- `codeHash`: The Keccak hash digest of the contract bytecode.
22-
- `PoseidonCodeHash` (**new field**): The Poseidon hash digest of the contract bytecode in a 256-bit integer.
23-
- `CodeSize` (**new field**): The size of the contract bytecode in bytes.
2420

2521
## State
2622

2723
The state of a blockchain is a collection of account data. The _state trie_ encodes account data and their corresponding addresses to a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) data structure. The root of tree, or the state of the blockchain, is a cryptographic digest of all the account data contained in the tree.
2824

29-
Ethereum uses a data structure called [Patricia Merkle Trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) for both the state trie and the storage trie that stores the key-value entries stored in a smart contract. In Scroll, we replace the Patricia Merkle Trie with a more zk-friendly data structure, called zkTrie, for both state trie and storage trie. At a high level, the zkTrie data structure is a sparse binary Merkle tree with the [Poseidon hash](https://eprint.iacr.org/2019/458.pdf), a zk-friendly hash function. The [zkTrie](/technology/sequencer/zktrie) document describes more details about this data structure.
25+
Scroll uses Ethereum's [Merkle-Patricia Trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) (MPT) for both the state trie and the storage trie that stores the key-value entries in smart contracts. This ensures full compatibility with Ethereum's state proof format and tooling.

src/content/docs/en/technology/chain/blocks.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The block header in Scroll mirrors the structure of Ethereum's. However, certain
3030
| `extraData` | Signature by the block's signer, followed by arbitrary additional data. |
3131
| `mixHash` | Always 0. |
3232
| `nonce` | Always 0. |
33-
| `baseFee` | Currently empty in Scroll because we haven't enabled the EIP-1559. |
33+
| `baseFee` | The base fee for this block. Since the [Curie upgrade](/technology/overview/scroll-upgrades/curie-upgrade), Scroll uses EIP-1559 with the base fee set by the sequencer. |
3434

3535
## Block Time
3636

src/content/docs/en/technology/chain/differences.mdx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,19 @@ import Aside from "../../../../../components/Aside.astro"
1313

1414
| Opcode | Scroll Behavior |
1515
| --------------------------- | ---------------------------------------------------------------------------------------------------------------- |
16-
| `BLOCKHASH` | Returns `keccak(chain_id \|\| block_number)` for the last 256 blocks. |
1716
| `COINBASE` | Returns the fee vault address (predeployed contract `0x5300000000000000000000000000000000000005`). |
1817
| `DIFFICULTY` / `PREVRANDAO` | Always return 0. |
1918
| `SELFDESTRUCT` | Disabled. If the opcode is encountered, the transaction will be reverted. |
2019

2120
## Precompiled Contracts
2221

23-
| Address | Name | Scroll behavior |
24-
| ------- | ------------ | ----------------------------------------------------------------------------------------------- |
25-
| `0x03` | `RIPEMD-160` | Currently not supported. |
26-
| `0x05` | `modexp` | Restrict the input values `B, E, M` to unsigned integers less than $2^{256}$. |
27-
| `0x08` | `ecPairing` | The inputs are still multiple of 6 32-byte values, but limit the number of tuples to at most 4. |
28-
| `0x09` | `blake2f` | Currently not supported. |
29-
| `0x0a` | `point evaluation` | Currently not supported. |
22+
| Address | Name | Scroll behavior |
23+
| ------- | ------------------ | ----------------- |
24+
| `0x03` | `RIPEMD-160` | Not supported. |
25+
| `0x09` | `blake2f` | Not supported. |
26+
| `0x0a` | `point evaluation` | Not supported as a precompile. Blob verification is done in ZK circuits. |
3027

31-
The remaining precompiled contracts have the same behavior as Ethereum. However, their maximum usage within a block is constrained by a limit tied to the zkEVM circuit capacity.
28+
The remaining precompiled contracts have the same behavior as Ethereum.
3229

3330
## EIPs
3431

0 commit comments

Comments
 (0)