What is an Account?
An account is a container for data that has:- An address: Also known as its public key (or pubkey for short), this is a unique 32-byte identifier for the account.
- Metadata: Information about the account’s state and properties. Important metadata fields include the owner, which is the only account allowed to modify the account’s data, and the data size, which specifies how much storage it takes up.
- Data: The actual bytes stored in the account, which is allowed to be up to 16 MiB.
Accounts and Programs
Accounts are only useful to us if they can be read and manipulated. Programs, or smart contracts, allow accounts to be updated. The logic of how accounts should be updated is written in code. Programs are themselves accounts, and their compiled code is stored in their account data. When executing, they are allowed to read from any account, and can write to the accounts that they own. For more information, see Programs.Addresses
Every account is identified by a 32-byte address, which is a public key. There are two ways accounts get their addresses:- Keypair-derived accounts: You can think of these as being accounts that can be logged into. They are generated from a cryptographic keypair, which consists of a private and public key, where anyone with the private key can prove their identity, which can be verified with the public key.
- Program-derived addresses (PDAs): These are addresses derived from a program’s address and a seed. These accounts have no private key—only the program can sign for them.
Ownership
Every account is owned by exactly one program, which is the program that created it. The owning program has exclusive write access to the account’s data. Other programs can read the account, but only the owner can modify it. Note that for keypair-derived accounts, the owner of the account is the system program.Data
The data for an account is just a byte array. Programs interpret these bytes however they want; there is not an enforced schema. Common patterns include:- Fixed-size structs: Store a C struct directly in the account
- Variable-size data: Use a header that indicates data layout
- Nested accounts: Store references (addresses) to other accounts
user_profile struct above, you’d create an account with at least 72 bytes. Accounts can be resized later, but this requires the owning program’s permission.
Account Lifecycle
Creation
New accounts are created by programs using state proofs. A creation proof cryptographically demonstrates that an address is available—no account currently exists at that address.Modification
The owning program can modify an account’s data at any time. Before writing to an account, the program must mark it as writable within the current transaction:Compression
To save on-chain storage, accounts can be compressed. A compressed account’s data is removed from active validator storage and stored off-chain. The account still exists—its current state is committed to the blockchain through a Merkle tree—but it cannot be accessed until it’s decompressed. Compressing and decompressing accounts requires state proofs to maintain security guarantees.Deletion
Programs can delete accounts they own. This removes the account from the blockchain entirely and frees up its storage.Compressed vs. Uncompressed Accounts
The Thru network distinguishes between compressed and uncompressed accounts: Uncompressed accounts are active and stored in validator memory. They can be accessed and modified immediately by any transaction. Compressed accounts are archived off-chain. Their state is cryptographically committed to the blockchain via a Merkle tree, but validators don’t store the full data. To use a compressed account, you must first decompress it by providing a state proof. Compression dramatically reduces storage costs for accounts that are accessed infrequently. For example, a user might compress their account when they’re not actively using the network, then decompress it months later when they want to make a transaction. See Account Compression and State Proofs for technical details on how compression works.Accounts in Transactions
When you submit a transaction, you specify which accounts it will access. Each account is passed to the program by index:Working with Accounts in Programs
Here’s a simple example of creating and using an account in a program:count field, implementing a simple counter. For a more complete example, see Building a C Program.
Key Takeaways
- Accounts are containers for data identified by 32-byte addresses
- Programs own accounts and modify them
- Account data is unstructured — programs define their own data layouts
- Accounts can be compressed to reduce storage costs when not actively used
- Transactions specify which accounts they access and programs use indices to reference them
Next Steps
- Learn how to build a C program that creates and uses accounts
- Explore account compression for advanced state management
- Review the syscalls reference for account manipulation functions