Compressed Account Model
Overview to the Compressed Account Model, State Merkle trees, and Validity Proofs.
Regular versus Compressed Accounts
ZK compressed state is stored in compressed accounts. Compressed accounts are similar to regular Solana accounts but with four main differences:
Each compressed account can be identified by its hash
Each write to a compressed account changes its hash
An
address
can optionally be set as a permanent unique ID of the compressed accountAll compressed accounts are stored in sparse state trees. Only the tree's state root (i.e., a small fingerprint of all compressed accounts) is stored in the on-chain account space
These differences allow the protocol to store states as calldata in the less expensive Solana ledger space instead of costly on-chain account space
To understand the similarities and differences between Solana's regular account model and compressed accounts, let's first look at compressed accounts with Program-Derived Addresses (PDAs)
If you don't know what PDAs are, read this explainer first
Compressed PDA Accounts
Like regular accounts, each compressed PDA account can be identified by its unique persistent address, represented as 32 bytes in the format of a PublicKey
. Like PDAs, compressed account addresses don't belong to a private key; rather, they're derived from the program that owns them

The compressed PDA account layout is similar to Solana's regular PDA account layout — it has the Data, Lamports, Owner, and Address fields. The Data field stores the program state. Notice the enshrined AccountData structure: Discriminator, Data, DataHash:

The Anchor framework reserves the first 8 bytes of a regular account's data field for the discriminator. This helps programs distinguish between different program-owned accounts. The default compressed account layout is opinionated in this regard and enforces a discriminator in the Data field. You can ignore the DataHash field for now; we cover its importance for ZK Compression later.
Address & Hash
The address
field is optional for compressed accounts because ensuring that the address of a new account is unique incurs additional computational overhead, and not all use cases need the uniqueness property of addresses.
Instead, each compressed account can be identified by its hash, regardless of whether it has an address.
By definition, whenever the data of a compressed account changes, its hash changes. This impacts how developers interact with fungible state. Check out the examples section to see what using hashes instead of addresses looks like in practice.
In the next section we will explain why using the account's hash as its ID makes sense for the compression protocol.
State Merkle trees
Compressed accounts are stored as hashes in state Merkle trees.
A State tree is a binary Merkle tree that stores data of millions of compressed Solana accounts in leaves for efficient cryptographic verification the integrity of all leaves in a tree.

State trees are fungible and provided by the protocol. Developers don’t need to maintain or initialize State trees themselves.
Leaf Hash Structure: Compressed Account Hashes
For compressed Solana accounts, the 32 byte leaf hashes effectively mirror the regular Solana account layout: {DataHash, StateHash; Owner, Lamports
.
The data_hash
represents the fingerprint of the actual account data.
The state_hash
ensures that each account hash is globally unique. It includes
the public key of the state tree's respective on-chain account (i.e.,
state_tree_hash
) andthe compressed account's position in the tree (i.e.,
leafIndex
).
Lastly, owner_hashed
determines which program owns this account and lamports
show the account balance.

Validity Proofs
prove the existence of compressed accounts as leaves within state trees with a constant 128-byte size. These proofs are generated off-chain and verified on-chain. ZK Compression uses Groth16, a well-known pairing-based zk-SNARK, for its proof system.
Developers don’t need to generate validity proofs or learn about ZK to use ZK Compression.

For those interested in learning more about the fundamentals of ZK and its applications on Solana, we recommend reading the following:
Next Steps
Now that you understand the core concepts of ZK Compression, here's the lifecycle of a transaction.
Lifecycle of a TransactionLast updated
Was this helpful?