Guide
Solana account model explained
Ethereum developers think in contracts with internal storage. Solana flips the model: everything on-chain is an account — your wallet, every token balance, every NFT metadata record, and every deployed program. There is no shared global state inside a program; programs read and write accounts they are allowed to touch. Once you internalize that, wallet clutter, rent deposits, and "why does this dApp need seven signatures?" all start to make sense.
What an account actually is
A Solana account is a row in the ledger keyed by a 32-byte public key (the address you see in explorers). Each account has four fields that matter day to day:
- Lamports — the SOL balance held inside this account (1 SOL = 1,000,000,000 lamports). This is not just "your wallet" — token accounts and data accounts hold lamports too.
- Data — a byte array, up to 10 MB per account. Wallet addresses usually have empty data; token accounts store mint + owner; programs store executable BPF bytecode.
- Owner — the program ID allowed to modify this account's data and debit its lamports (with exceptions for the system program transferring SOL).
- Executable flag — if true, the account is a deployed program; validators run its bytecode when invoked.
Transactions are lists of instructions. Each instruction names a program plus a set of accounts with metadata (signer? writable?). The runtime loads those accounts, checks owners and signatures, and runs the program. If you have used transaction simulation, you have already seen programs fail when an account's owner or balance is wrong.
Account types you will meet
System-owned wallet accounts
A standard user wallet (Phantom, Solflare, Backpack) is a keypair whose public key is
an account owned by the System Program (11111111111111111111111111111111).
Data is empty; lamports are spendable SOL. When you "send SOL," the system program
debits one account and credits another — no smart contract logic required.
SPL token accounts
Tokens do not live inside your wallet account. Each token mint you hold needs a separate token account owned by the SPL Token program, storing which mint and which owner wallet controls the balance. That is why a busy wallet shows dozens of addresses on Solscan. Our SPL token accounts guide walks through associated token accounts (ATAs) and the ~0.002 SOL rent deposit each one carries.
Program accounts
Deployed programs are accounts with executable = true and bytecode in the
data field. They are owned by the BPF Loader. Upgrading a program changes the data
bytes while keeping the same program ID — see
how program deployment works
for upgrade authority and loader details.
Data accounts (program state)
DeFi pools, game scores, NFT metadata, order books — all live in non-executable
accounts whose owner is the program that defines the layout. Only that
program's instructions can resize or rewrite the bytes. This is Solana's substitute for
contract storage variables: instead of mapping(address => uint) inside
one contract, you create one account per user or per pool.
Owners: who can change what
The owner field is Solana's permission system. The Token program owns your USDC balance account; only Token program instructions (transfer, burn, close) can move those tokens. Your wallet must sign as the token account's authority, but the runtime enforces owner checks before any instruction runs.
Common owners you will see on explorers:
- System Program — plain SOL wallets.
- SPL Token / Token-2022 — fungible and NFT token accounts.
- Metaplex, Mango, Jupiter routers, etc. — app-specific state accounts.
- BPF Loader — on-chain program bytecode.
A frequent bug in custom programs is passing an account with the wrong owner; simulation
returns InvalidAccountOwner or similar. Wallets surface that as a generic
failure — knowing to check the owner on Solscan saves hours.
Rent and rent-exempt accounts
Storing data on-chain has a cost. Solana charges rent proportional to account size (lamports per byte per epoch). In practice almost every account you create today is rent-exempt: you deposit enough lamports upfront that the account never needs periodic rent payments. Close the account later and those lamports return to your wallet.
Rules of thumb for users:
- Empty token accounts after airdrops still locked ~0.002 SOL each — close them to recover rent.
- Your main wallet needs slightly more SOL than the payment amount because fees and occasional new account creation deduct lamports.
- NFTs and positions you actively hold should stay open; closing a token account with a non-zero balance requires burning or transferring first.
Step-by-step recovery is in our rent reclaim guide. Developers sizing accounts should allocate only the bytes they need — larger data means a higher rent-exempt minimum.
Program-derived addresses (PDAs)
Some accounts have no private key. A program-derived address (PDA) is
a public key found by hashing seeds plus a program ID off the Ed25519 curve, so no
signer exists. Programs "sign" for PDAs with invoke_signed during CPI
(cross-program invocation).
PDAs are how programs custody tokens (vaults), store per-user state deterministically
(["user", wallet_pubkey]), and enforce that only the program can debit a
pool. When a dApp says "initialize account," it often means create a PDA owned by the
program with a rent deposit paid by your wallet.
You cannot export a PDA to a hardware wallet — there is no seed phrase. Explorers still show the address like any other account; the difference is who can authorize writes.
How this differs from Ethereum
On Ethereum, contract code and storage live at one address; users send transactions to the contract. On Solana, users send transactions that list many accounts; programs are stateless entry points. Composition happens by passing accounts from one instruction to the next inside a single transaction (atomic swaps, settle-and-close patterns).
Trade-offs:
- Pros — parallel execution (non-overlapping account sets run concurrently), predictable per-account costs, explicit permission model.
- Cons — more addresses to track, rent for every piece of state, steeper learning curve for developers wiring account metas correctly.
Wallets abstract most of this for simple SOL sends. DeFi, gaming, and NFT mints expose the account model through longer confirmation popups listing every writable account.
Practical checklist
For wallet users
- Expect multiple on-chain addresses per wallet — normal, not a hack.
- Keep a small SOL buffer for fees and new token accounts (~0.01 SOL is comfortable for micropayments).
- Periodically close empty spam token accounts to recover rent.
- Read wallet transaction previews; unknown writable accounts are a phishing red flag — see wallet security.
For developers
- Design state as accounts early — one account per user/item beats one giant account (contention kills parallelism).
- Mark accounts signer / writable correctly in instruction builders; tests on devnet first.
- Fetch account info with the right
commitmentlevel before acting on balances — see confirmation times. - Simulate before send to catch owner and rent errors cheaply.