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:
- KZG Ceremony
- Arithmetic hash based alternatives to KZG for proto-danksharding (EIP-4844)
- Sharding multi-party computation ceremony
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).
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: U256New Parameters
- BLOB_TX_TYPE
- BYTES_PER_FIELD_ELEMENT
- FIELD_ELEMENTS_PER_BLOB
- BLS_MODULUS
- VERSIONED_HASH_VERSION_KZG
- MAX_BLOB_GAS_PER_BLOCK
- GAS_PER_BLOB
- MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS
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.