Summary
Accounts have 5 fields: lamports, data, owner, executable, and rent_epoch. Each account is identified by a unique 32-byte address. Accounts must hold a minimum lamport balance proportional to their data size to stay on-chain.
Account address
Every account address is a 32-byte value, displayed as a base58-encoded string. An address can be one of two types:
- Public key: corresponds to an Ed25519 keypair (has a private key)
- Program derived address (PDA): deterministically derived from a program ID and seeds (no private key)
An account with its base58 encoded public key address
Public key
A Keypair consists of a public key (used as the account address) and a private
key (used to sign transactions). The following example generates a keypair using
the Solana SDK.
import { generateKeyPairSigner } from "@solana/kit";// Kit does not enable extractable private keysconst keypairSigner = await generateKeyPairSigner();console.log(keypairSigner);
Program derived address
A program derived address (PDA) is deterministically derived from a program ID and one or more optional seeds. PDAs do not have a corresponding private key. The following example derives a PDA using the Solana SDK.
import { Address, getProgramDerivedAddress } from "@solana/kit";const programAddress = "11111111111111111111111111111111" as Address;const seeds = ["helloWorld"];const [pda, bump] = await getProgramDerivedAddress({programAddress,seeds});console.log(`PDA: ${pda}`);console.log(`Bump: ${bump}`);
Account fields
Every
Account
has a maximum size of
MAX_ACCOUNT_DATA_LEN
(10 MiB, equivalent to MAX_PERMITTED_DATA_LENGTH) and contains five fields:
| Field | Type | Description |
|---|---|---|
lamports | u64 | Balance in lamports. Owner can debit; any program can credit. |
data | Vec<u8> | Account state or program bytecode. Max 10 MiB. Owner-writable only. |
owner | Pubkey | Program with write access. Reassignable only when data is zeroed. |
executable | bool | True = program account. |
rent_epoch | Epoch | Deprecated. Set to u64::MAX for rent-exempt accounts. |
pub struct Account {/// lamports in the accountpub lamports: u64,/// data held in this account#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]pub data: Vec<u8>,/// the program that owns this account. If executable, the program that loads this account.pub owner: Pubkey,/// if true, this account's data contains a program (and is now read-only)pub executable: bool,/// deprecatedpub rent_epoch: Epoch,}
Lamports
The lamports field holds the account's balance in
lamports (1 SOL = 1,000,000,000
lamports).
Every account must maintain a minimum lamport balance, known as the rent-exempt balance, to keep its data stored on-chain. This balance is proportional to the account's data size.
Although often called "rent," the rent-exempt balance functions as a refundable deposit, the full balance is recovered when the account is closed.
See
minimum_balance()
and the rent
constants.
Data
The data field stores an arbitrary byte array. Its contents depend on the
account type:
- Program accounts: Contains executable bytecode or the address of a program data account that stores the bytecode.
- Data accounts: Contains program-defined state data. The owning program defines the serialization format.
Reading account data requires two steps:
- Fetch the account by its address.
- Deserialize the
datafield from raw bytes into the program-defined data structure.
Owner
The owner field contains the program ID (public key) of the program that owns
this account.
The owner program is the only program that can:
- Modify the account's
datafield - Deduct lamports from the account's
lamportsfield
Any program can add lamports to another account, but only the owner can deduct lamports from it.
For program accounts, the owner is the account's loader program.
Executable
The executable field is a boolean that determines whether the account is a
program account or a
data account:
true= program account (contains executable code)false= data account (stores state)
Rent epoch
The rent_epoch field is deprecated.
Previously tracked when an account would automatically have lamports deducted to
pay for maintaining its data on-chain. Since rent collection is deprecated,
rent_epoch is set to u64::MAX for all new rent-exempt accounts.
Is this page helpful?