Bootloader

Learn about Bootloader, the entrypoint of the system

The bootloader is the component responsible for implementing the general blockchain protocol. Roughly, this means:

  1. Initializing the system.
  2. Reading the block context from the oracle.
  3. Reading and parsing the first transaction.
  4. Validating the transaction.
  5. Executing the transaction.
  6. Saving the transaction result.
  7. Repeat from 3 until there are no more transactions.
  8. Finalizing the block.

This component is, as the name suggest, the entrypoint of the system. The function  run_prepared implements this top-level main loop.

Configuration

The bootloader can be configured with the following parameters (found in the BasicBootloaderExecutionConfig struct):

  • ONLY_SIMULATE: skips the validation step when processing a transaction. Used for call simulation in the node.
  • IS_PROVING_ENVIRONMENT: to skip some checks during sequencing.
  • SPECIAL_ADDRESS_SPACE_BOUND: the range of address (starting from 0) where system contracts can be deployed.
  • AA_ENABLED: whether native account abstraction is enabled.

In addition, the basic_bootloader crate has the following compilation flags:

  • code_in_kernel_space: to enable normal contract execution for addresses in the range [0, SPECIAL_ADDRESS_SPACE_BOUND].
  • transfers_to_kernel_space: to enable token transfers to addresses in the range [0, SPECIAL_ADDRESS_SPACE_BOUND]. Note: the bootloader itself has a special formal address (0x8001) that is always allowed to receive token transfers. This is used to collect fees.
  • charge_priority_fee: to enable charging for the EIP-1559 tip (priority fee) on top of the base fee.
  • evm-compatibility: enables all the previous flags, needed for the EVM test suite.

Code Execution

For transaction execution, the bootloader has to execute some contract code. This contract code corresponds to one of the supported VMs, and is executed through the Execution Environment (EE) module.

A contract call is executed through an interplay between the bootloader and (potentially different) execution environments. Indeed, a contract executing in a given EE can call to contracts that run on a different EE or to a System Hook. This interplay is described under Runner Flow.

Block Header

At the end of the execution the bootloader outputs the block header.

For the block header, the Ethereum format will be used. However, some of the fields will be set differently in the first version for simplification.

The block header should determine the block fully, i.e. include all the inputs needed to execute the block.

Ethereum
Field Name
Ethereum valueZKsync OS valueComments
parent_hashprevious block hashprevious block hash
owners_hash0x1dcc4de8dec75d7aab85b567
b6ccd41ad312451b948a7413f
0a142fd40d49347 (post merge)
0x1dcc4de8dec75d7aab
85b567b6ccd41ad312451b
948a7413f0a142fd40d49347
hash of empty RLP list
beneficiaryblock proposerOperator (fee) address
state_rootstate commitment0
transactions_roottransactions trie (Patricia Merkle tree) roottransactions rolling hash
receipts_rootreceipts trie (Patricia Merkle tree) root0
logs_bloom2048-bit bloom filter over logs’ addresses and topics0
difficulty0 (post merge)0
numberblock numberblock number
gas_limitblock gas limitconstant, not defined yet, 10–15 M most likely
gas_usedblock gas usedblock gas usedTBD — with or without pubdata
timestampblock timestampblock timestamp
extra_dataany extra data included by proposerTBD, possibly gas_per_pubdata
mix_hashbeacon-chain-provided random, (post merge)0after consensus will be provided random
nonce0 (post merge)0
base_fee_per_gasbase_fee_per_gasbase_fee_per_gas

Made with ❤️ by the ZKsync Community