WETH
Giáo trìnhResearch

EIP-4844

EIP-4844 (Proto-Danksharding) - giao dịch blob trong Ethereum

EIP-4844

Overview

L2 Rollups must allow the permissionless reconstruction of the L2 state. To achieve this, they must ensure Data Availability, which refers to the global ordering of inputs for transactions that have altered the state. Before 4844 was live on mainnet, rollups have been storing data only via a section of the transaction known as calldata.

EIP-4844 introduces "Blobs", which modifies the current transaction and block structure defined in the execution-specs and consensus-specs respectively.

EIP-4844 introduces a new transaction type, the blob-carrying transaction.

Quoted from proto-danksharding-faq(aka EIP-4844):

The main feature introduced by proto-danksharding is new transaction type, which we call a blob-carrying transaction. A blob-carrying transaction is like a regular transaction, except it also carries an extra piece of data called a blob. Blobs are extremely large (~125 kB), and can be much cheaper than similar amounts of calldata. However, blob data is not accessible to EVM execution; the EVM can only view a commitment to the blob.

This page outlines the EIP, providing code references to understand the changes brought by this hard fork. It targets aspiring Ethereum core developers interested in comprehending Ethereum's code post-update.

Core changes

New Gas Handling

calldata has represented a primary bottleneck for scaling Ethereum, as storing data in calldata is costly, with plans to make it even more so.

EIP-4844 introduces "Blobs" a new way to store data within a transaction that will be significantly cheaper than using calldata. This is because Blobs will utilize a new type of gas, independent from the conventional gas, and follow their own pricing rules.

EIP-4844 marks the initial step towards achieving more efficient gas usage.

The aim of these EIPs is to achieve a smaller and less variable block size. This goal is beneficial for two main reasons: it offers protection for solo stakers and creates additional capacity for future Blob storage.

But how can we achieve a smaller and less variable block size? One method is by increasing the cost of non-zero calldata bytes as proposed in EIP-7623. Raising the calldata cost reduces the maximum possible block size (assuming the gas limit remains at 30,000,000 and the gas cost for each calldata byte increases, resulting in fewer bytes fitting inside a block). Moreover, the increased calldata costs further encourage the use of Blobs for data availability.

The exploration of new, efficient ways to manage gas and the block gas limit remains a subject of active discussion.

Changes on the Consensus Specs

The upgrade which will introduce EIP-4844 into the Consensus Layer has been labeled Deneb.

1. Beacon Block Data Structure changes

The BeaconBlockBody (the data structure representing a block of transactions in the Consensus Layer) is updated to include 2 new more fields: blob_kzg_commitments and an updated version of the execution_payload field.

See here.

Is important to note that Blobs will not be added to the block to which they belong to. They will instead referenced in the block by using the blob_kzg_commitments. Blobs are propagated separately to the network via "sidecars".

KZG commitments are a type of cryptographic commitment particularly useful for their efficiency in creating and verifying proofs of data availability and correctness.

KZG commitments provide the ability to prove that specific pieces of data are included in the set without revealing the entire dataset. This is particularly useful for scalability solutions because it does not require for every node to store the whole blockchain to prove transactions correctness.

Check the following links to learn more:

2. Blob Sidecars

As stated in the EIP-4844 blobs are referenced but not fully encoded inside the beacon block body. Instead of embedding the full contents in the body, the blobs are propagated separately, as "sidecars".

For the sidecar data structure, see here

Before propagating the blob sidecars to the p2p network, nodes must verify the Blobs are valid (see here).

When a node requests a blob to the network the network responds with a BlobSidecar data structure. The node receiving the sidecar should verify that blob sidecar is well-formatted, has valid inclusion proof, and is correct w.r.t. the expected KZG commitments before reading the data in a blob.

This "sidecars" design provides forward compatibility for further data increases by black-boxing is_data_available, which means that in future upgrades is_data_available() implementation may change, for example to include data-availability-sampling (DAS), and the system interacting with this function is not required to understand the inner implementation of the function (in programming terms, is_data_available() can be considered as an interface method where the implementation may change over time).

3. Inclusion of KZG Commitment versioned hashes

The Consensus Layer (CL, also called Beacon chain) calls the process_execution_payload function when a new block payload is submitted to the chain. This function is responsible to perform some validity checks on the block's payload and then invoke the Execution Layer (EL) via the verify_and_notify_new_payload function.

Once invoked, the EL will:

  • validate the block payload
  • execute transactions inside the block payload
  • update the state, which is the result of executing transactions

With EIP-4844, the process_execution_payload adds the parameter versioned_hashes to be passed to the verify_and_notify_new_payload function.

versioned_hashes is an array of hashes for each blob of KZG Commitment.

4. Execution Payload and Execution Payload Header

The Execution Payload which is the payload sent from the Consensus Layer to the State Transition Function on the Execution Layer is extended with two new 64-bit unsigned integer fields, blob_gas_used and excess_blob_gas. Blob transactions have their own gas targeting rules (as described in the above section) and nodes must take into account gas spent to store data in blobs in addition to the normal gas fees spent to execute transaction (see below in Changes on the Execution Specs).

  • See 1 and 2

5. New Block Header checks

See go-ethereum file "consensus.go" for checks added to the block header:

Changes on the Execution Specs

The upgrade which will introduce EIP-4844 into the Execution Layer has been labeled Cancun.

1. Add checks inside the State Transition Function

The EL now must check that the blob specific fields are valid for each transaction that is going to be executed in the State Transition Function (STF).

The checks include (For the specs code, see here):

  • check that the signer has enough balance to cover the cost of both transaction gas fee and blob gas fees
# modify the check for sufficient balance
max_total_fee = tx.gas * tx.max_fee_per_gas
if get_tx_type(tx) == BLOB_TX_TYPE:
    max_total_fee += get_total_blob_gas(tx) * tx.max_fee_per_blob_gas
assert signer(tx).balance >= max_total_fee
  • check that the blob transaction contains at least 1 valid blob_versioned_hash (see CL changes) and that they are formatted correctly
assert len(tx.blob_versioned_hashes) > 0
  • check that the user is willing to pay at least the current blob base fee
assert tx.max_fee_per_blob_gas >= get_blob_base_fee(block.header)

Finally, the EL STF must keep track of the gas being gas used for blob transactions (same as it already happens for EIP1559 transactions).

blob_gas_used += get_total_blob_gas(tx)

2. New Transaction Data Structure (BLOB_TX_TYPE)

Before EIP-4844, the Transaction data structure was the following (ethereum execution-specs repository):

@slotted_freezable
@dataclass
class LegacyTransaction:
  nonce: U256
  gas_price: Uint
  gas: Uint
  to: Union[Bytes0, Address]
  value: U256
  data: Bytes
  v: U256
  r: U256
  s: U256

@slotted_freezable
@dataclass
class AccessListTransaction:
  chain_id: U64
  nonce: U256
  gas_price: Uint
  gas: Uint
  to: Union[Bytes0, Address]
  value: U256
  data: Bytes
  access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...]
  y_parity: U256
  r: U256
  s: U256

@slotted_freezable
@dataclass
class FeeMarketTransaction:
  chain_id: U64
  nonce: U256
  max_priority_fee_per_gas: Uint
  max_fee_per_gas: Uint
  gas: Uint
  to: Union[Bytes0, Address]
  value: U256
  data: Bytes
  access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...]
  y_parity: U256
  r: U256
  s: U256

Transaction = Union[
  LegacyTransaction, AccessListTransaction, FeeMarketTransaction
]

The calldata is encoded inside the data field of the Transaction class. The calldata is accessible by the EVM, and the format to encode and decode it is specified in the Contract ABI.

EIP-4844 will introduce two more fields in the Transaction class, which are max_fee_per_blob_gas and blob_versioned_hashes. EIP-4844 introduced a new transaction type where TransactionType == BLOB_TX_TYPE and the TransactionPayload is the rlp encoding of the class below.

With the EIP-4844, the new Transaction data structure will be the following:

@slotted_freezable
@dataclass
class BlobTransaction: # the class name may change
  chain_id: U64
  nonce: U256
  max_priority_fee_per_gas: Uint
  max_fee_per_gas: Uint
  gas: Uint
  to: Union[Bytes0, Address]
  value: U256
  data: Bytes
  access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...]
  max_fee_per_blob_gas: U256
  blob_versioned_hashes: VersionedHash
  y_parity: U256
  r: U256
  s: U256

New Parameters

New Type Aliases

New Cryptographic Helpers

New Opcodes

A note about previous attempts/research to improve scalability for rollups

To enhance scalability, two Ethereum Improvement Proposals (EIPs) were proposed: EIP-4488 and EIP-4490.

At their core, both EIPs aim to reduce the gas cost associated with transaction calldata. EIP-4490 suggests lowering the calldata cost from 16 to 6 gas per byte. This change, while straightforward to implement, could potentially increase the maximum block size to 5MB. Conversely, EIP-4488 proposes a more significant reduction, from 16 to 3 gas per byte, but introduces a cap on the amount of CALLDATA permitted in each block to limit block size effectively.

For a more detailed discussion on these two proposals, consider checking this tweet by Tim Beiko.

Please note that the aforementioned EIPs, EIP-4488 and EIP-4490, are now deprecated in favor of the introduction of Blobs.

Further Reading

On this page