Live prices are currently unavailable — the exchange feed could not be reached and no recent cached reading is held.

Research · Solana

The account model: ownership, storage and PDAs

Solana stores all state in accounts, and every account has the same five fields regardless of what it holds. Programs are accounts too, and they hold no state of their own; they act on data accounts that they own. This page describes the account structure, the ownership rules that decide who may change what, the refundable storage deposit that replaced ongoing rent, and program derived addresses — the mechanism that lets a program control an address without holding a private key.

Last reviewed 2026-09-21Source: Solana account documentationMechanism described as deployed; limits quoted from the runtime constants.

Five fields, one shape

An account is Solana's fundamental unit of state. Every account, whether it holds a wallet balance, a token mint, a program's data or the program's own bytecode, has the same five fields. There is no separate object type for a token or a program; the difference is carried by the fields themselves, principally the owner and the executable flag.

The address is a 32-byte value, displayed as a base58 string. It is either an Ed25519 public key, which has a corresponding private key, or a program derived address, which does not. The distinction matters because it decides who can sign for the account, and it is the basis of the PDA mechanism described below.

The five fields every Solana account contains, with their types and the rules that govern each.
FieldTypeRole and rule
lamportsu64Balance in lamports. The owner may debit it; any program may credit it.
databyte vectorAccount state or program bytecode. Writable only by the owner.
ownerPubkeyThe program with write access. Reassignable only when the data is zeroed.
executableboolTrue for a program account, false for a data account.
rent_epochEpochDeprecated. Set to u64::MAX for accounts meeting the storage deposit.

Last reviewed 2026-09-21Source: Solana — Account Structure

Ownership decides who may change what

The owner field is the program that governs the account's state transitions. Only the owner may modify the account's data, and only the owner may deduct lamports from it. Any program may add lamports to any account, and any program may read any account. Those four rules are the whole of the permission model, and most of the account model's behaviour follows from them.

The asymmetry between crediting and debiting is deliberate. Because anyone can add lamports but only the owner can remove them, a program cannot drain an account it does not own, but it can always fund one. That makes it safe to send value to an address without the recipient having to cooperate, which is what allows a first transfer to a new address to create the account.

Ownership is assigned once. The System Program is the only program that can assign an account's owner, and it can only do so while the account's data is zeroed. A program that wants to take ownership of a new account does so by asking the System Program to create the account with that program as owner, then initialising the data itself. Once data has been written, the owner cannot be changed without first clearing it.

Program accounts are owned by their loader. When a program is deployed, the account holding its bytecode is owned by one of the loader programs rather than by the program itself, and the runtime checks that a program invoked by an instruction is owned by a valid loader before executing it. A program that is not owned by a loader cannot be executed.

The storage deposit, and why rent is a misnomer

Storing data on-chain costs the network something, and Solana makes the account holder pay for it. Every account must hold a minimum lamport balance proportional to the size of its data. The runtime and the RPC methods call this the rent-exempt minimum, but the name is a legacy: ongoing rent collection is disabled, and the balance is better understood as a refundable storage deposit.

The deposit is refundable because it is not spent. It sits in the account's lamport balance, and when the account is closed — its balance reduced to exactly zero — the full amount is recovered. What the holder gives up is the use of that capital while the account exists, not the capital itself. The formula the runtime uses is documented as a function of the account's size, and the constants behind it are published rather than hidden.

The rule is enforced on every balance reduction. A transaction that would leave an account below its minimum without closing it fails, and the only permitted way to go below the minimum is to go to exactly zero. That is why closing an account is a distinct operation rather than simply spending its balance down. Accounts that reach zero are removed from the network by garbage collection, though their transaction history remains visible.

The rent_epoch field is a remnant of the earlier design. It once tracked when an account would next have lamports deducted to pay for its storage. With ongoing collection disabled, it is set to the maximum value for accounts that meet the deposit, and it carries no operational meaning today.

Program derived addresses

A program often needs an address it controls without holding a private key — a per-user account, a vault, a mint authority. A program derived address is how it gets one. A PDA is derived deterministically from the program's own ID and a set of seeds, so the same program and the same seeds always produce the same address.

The derivation is designed to produce an address that is not a valid point on the Ed25519 curve. Because it is off-curve, no private key exists for it, and no external party can produce a signature for it. Only the program whose ID was used in the derivation can authorise operations on the PDA, and it does so through the runtime's invoke_signed mechanism during a cross-program invocation rather than by presenting a signature.

The derivation hashes the seeds, the program ID and a fixed string together, then checks whether the result lies on the curve. If it does, the derivation fails and a different bump seed is tried. The bump is a single byte appended as the final seed, and the canonical bump is the first value that produces an off-curve address. Programs are expected to use the canonical bump: using a non-canonical one creates a second valid address for the same seeds, which is a known source of vulnerabilities.

Deriving a PDA computes an address; it does not create an account. The account must be created separately, typically by a cross-program invocation to the System Program that allocates the space and assigns ownership. Until that happens, the address exists only as a derivation, not as on-chain state.

The limits and costs that govern program derived address derivation.
LimitValueConstant
Maximum seeds per derivation16MAX_SEEDS
Maximum length per seed32 bytesMAX_SEED_LEN
Bump range0–255 (one byte)Appended as the final seed
Maximum PDA signers per cross-program invocation16MAX_SIGNERS

Last reviewed 2026-09-21Source: Solana — Program Derived Addresses

What the model implies

The account model is the reason the Sealevel runtime can schedule transactions in parallel. Because every account has a single owner and a transaction declares which accounts it will write, the runtime can tell whether two transactions conflict without executing either. A model in which a contract held its own internal state would not expose that information at the transaction level.

It also explains why storage is priced the way it is. Because the deposit is proportional to data size and refundable on close, a program that stores a large amount of state imposes a real capital cost on whoever funds it. That cost is the reason state compression exists: it stores a hash of the data rather than the data itself, which reduces the deposit dramatically. The state compression page covers that trade-off.

Sources and references

The account structure, the ownership rules, the storage deposit and the PDA derivation are taken from the project's own documentation. The mechanism is presented as deployed; the limits quoted are the runtime constants named in the sources.

  • The account structure and its fields. Solana, Account Structure: defines the five fields, the ownership rules, the storage deposit and the deprecated rent epoch.
  • Account types and the System Program. Solana, Account Types: distinguishes program accounts, data accounts, system accounts and sysvars, and describes how a data account is created and initialised.
  • Program derived addresses. Solana, Program Derived Addresses: covers the derivation, the off-curve requirement, the canonical bump and the seed and signer limits.
  • Account loading and validation. Solana, Account Runtime: describes how accounts are loaded before execution and the validations the runtime performs on the fee payer and program accounts.