Overview
This guide assumes that you’re familiar with Solana’s account model.
- Each compressed account can be identified by its hash
- Each write to a compressed account changes its hash
- An
addresscan optionally be set as a permanent unique ID of the compressed account. - All 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.
In a Nutshell
Transactions can use compressed account data inside Solana’s virtual machine as if it were stored on-chain by combining state compression and zero-knowledge proofs:- Millions of compressed accounts are stored as hashes in Merkle tree leaves
- All accounts stored in a Merkle tree are compressed into a single root hash
- The root hash is stored in one Solana account for cryptographic verification
- Compressed account state is recorded on the Solana ledger
- The latest compressed account state is fetched from your RPC provider
- Compressed account state is verified against the on-chain root hash with a validity proof
- Merkle trees are provided by the protocol and Indexers generate validity proofs.
- Developers don’t configure state Merkle trees or generate validity proofs.
Compressed Account Structure
Compressed accounts include the core Solana account fields (owner, lamports, data) plus additional fields to index and store compressed state.Find the source code here.
Solana Account Structure
Solana Account Structure
Find the source code here: agave/sdk/account/src/lib.rs:48-60
Address and Hash
Each compressed account can be identified by its hash, regardless of whether it has an address. By definition, whenever any data of a compressed account changes, its hash changes. An address can serve as optional and additional persistent identifier.- It’s represented as 32 bytes in the format of a
PublicKey. - Addresses are optional, since ensuring that the address of a new account is unique incurs additional computational overhead.
- Use the address field wherever the state must be unique (such as for NFTs or certain PDAs) and requires a persistent identifier.
- You don’t need the address for any fungible state (e.g., fungible tokens)
- Like PDAs, compressed account addresses don’t belong to a private key; rather, they’re derived from the program that owns them.
- The key difference to regular PDAs is that compressed accounts require an address tree parameter.
- Address Merkle tree’s store addresses of compressed accounts and ensure its uniqueness.
- TypeScript
- Rust
Learn more about address derivation for a Typescript Client here.
Solana PDA Derivation
Solana PDA Derivation
derive-pda.ts
derive-pda.rs
Data Field
Thedata field contains the compressed account’s program state:
discriminator: Identifies the data type for programs to correctly deserialize account data. Similar to Anchor’s 8-byte account discriminator.data: Stores the account’s current state as arbitrary bytes (e.g., serialized user data, balances, metadata).- Compressed accounts have no fixed maximum size to store data like Solana’s 10 MB.
- Still, Solana’s 1,232-byte transaction limit constrains practical data size to roughly 1 KB per account.
data_hash: Hash of thedatafield (32 bytes).- When computing the compressed account hash for the state tree, the protocol uses this fixed-size hash instead of the variable-length data bytes.