Data availability
Data availability is a cornerstone of ZKsync's architecture, ensuring that the entire Layer 2 (L2) state can be reconstructed from the data submitted to Ethereum's Layer 1 (L1). This process not only secures the network but also optimizes cost-efficiency through innovative data management techniques.
State diffs: Optimizing storage slots
Instead of submitting detailed transaction data, ZKsync focuses on posting state diffs to L1. These diffs represent changes in the blockchain's state, enabling ZKsync to efficiently manage how data is stored and referenced:
- Efficient Use of Storage Slots: Changes to the same storage slots across multiple transactions can be grouped, reducing the amount of data that needs to be sent to L1 and thereby lowering gas costs.
- Compression Techniques: All data sent to L1, including state diffs, is compressed to further reduce costs. Read more about ZKsync's compression methods.
Additional data posted to L1
In addition to state diffs, ZKsync also posts other crucial information to ensure comprehensive data availability:
- L2 to L1 Logs and Messages: These ensure that communications and events are recorded and accessible.
- Published Bytecodes: The bytecodes of deployed smart contracts are made available, crucial for contract interaction and verification.
- Compressed State Diffs: Further optimizes data management by reducing the size of state changes posted to L1.
Validiums and zkPorter: Balancing Security and Efficiency
When a chain opts not to post its data on-chain, it operates under a model known as a validium. This approach significantly reduces costs by keeping data off-chain but introduces risks related to data accessibility and security:
- zkPorter: A hybrid model that combines features of rollups and validiums, zkPorter segments data responsibilities, allowing some storage slots to remain off-chain while critical data is posted to L1. Learn more about zkPorter.
Recreating L2 State From L1 Pubdata
ZKsync provides tools to validate and reconstruct the L2 state from data available on L1. Here's how this process is typically managed:
Basic Flow
- First, we need to filter all of the transactions to the L1 ZKsync contract for only the
commitBlocks
transactions where the proposed block has been referenced by a correspondingexecuteBlocks
call (the reason for this is that a committed or even proven block can be reverted but an executed one cannot). - Once we have all the committed blocks that have been executed, we then will pull the transaction input and the relevant fields.
The kinds of pubdata we’ll pull from transaction data:
- L2 to L1 Logs
- L2 to L1 Messages
- Published Bytecodes
- Compressed State Diffs
Key components for state reconstruction
State Diffs
State diffs are essential for understanding changes within the blockchain's state, represented as key-value pairs:
naive way: ( storage_slot, address, value )
actual: ( derived_key, value )
compressed: ( derived_key or enumeration index, compressed_value )
- Format: Typically presented as
(derived_key, value)
, wherederived_key
is a hash of the storage slot and address, andvalue
represents the storage value. - Compression and Enumeration: After the initial post,
derived_key
can be replaced with an enumeration index to optimize data size. The deeper meaning is that an enumeration key is the leaf index in our storage Merkle tree.
Contract Bytecodes
The handling of contract bytecodes involves:
- Compression and Indexing: Opcodes are chunked, indexed, and compressed by the server-side operator before being verified and sent to L1.
- Verification and Storage: A system contract ensures the accuracy of the compression before submission,
with uncompressed bytecode hashes stored in
AccountStorage
for reference.
This process is split into 2 different parts:
- the server side operator handling the compression
- the system contract verifying that the compression is correct before sending to L1.
The compressed bytecode makes it way up through factoryDeps
and the hash of uncompressed bytecode is stored on the AccountStorage
contract
so the hash of the uncompressed bytecode will be part of the state diffs