Solana Foundations In Depth
Solana development stops feeling like a list of unrelated APIs once you see accounts, programs, transactions, currency, keys, clusters, and confirmation as one closed system.
Search across all documentation pages
Solana development stops feeling like a list of unrelated APIs once you see accounts, programs, transactions, currency, keys, clusters, and confirmation as one closed system.
Every other page in this section - basics, units, keypairs, clusters, transaction flow, and the EVM contrast - is a zoom into one face of that system, not a separate technology.
This page is the umbrella: how those pieces fit together so you can reason about a wallet transfer, a program deploy, or a failed RPC call with the same underlying picture.
processed as final - that vanish once the pieces share one model.The root abstraction is the account.
Every on-chain entity is one: a wallet balance, a deployed program's bytecode, a token mint, a user's profile struct, or a system-owned temporary holding all share the same structural fields - lamports, a data byte buffer, an owner program id, an executable flag, and a legacy rent epoch.
Nothing "else" lives on-chain outside that shape.
A program is an account whose executable flag is true and whose data holds BPF/SBF bytecode the runtime can load.
Programs are stateless in the application sense: they do not keep user balances or mappings inside their own account after deployment the way many EVM contracts keep storage slots.
Mutable application state lives in separate accounts owned by that program (or by the System Program until ownership is assigned).
Only the owner program may write an account's data; lamport transfers and a few system-level rules are the main exceptions you design around.
That separation is why you design account layouts instead of "contract storage," and why The Solana Mental Model vs. EVM exists as a focused contrast later in this section.
Native currency is SOL, but every on-chain amount is an integer number of lamports, where 1 SOL = 1_000_000_000 lamports.
Clients and programs treat balances, fees, and rent deposits as u64 / bigint integers - never as floating-point SOL at the protocol boundary.
Identity is Ed25519: a keypair is a 32-byte public key (the address) plus a secret key used to sign.
Program Derived Addresses (PDAs) are valid 32-byte addresses that intentionally sit off the Ed25519 curve so no private key exists; programs "sign" for them with seeds via invoke_signed, which is how program-owned vaults and deterministic per-user accounts work.
A cluster (mainnet-beta, devnet, testnet, or your localnet) is a fully separate chain with its own genesis, validators, and account set.
An address that holds SOL on devnet does not hold that balance on mainnet-beta; RPC URL, wallet network, and explorer must agree.
Commitment - processed, confirmed, finalized - is how far a transaction has progressed through leader execution and validator voting before your client treats it as good enough.
None of these topics is optional background; they are the same machine viewed at different scales.
Work enters the network as a transaction: an atomic bundle of one or more instructions, each naming a program id and the accounts that instruction may touch.
Each account entry carries account metas - whether the account is writable and whether it must sign - so the runtime can lock accounts and enforce authorization before bytecode runs.
If any instruction fails, the whole transaction fails; partial success is not a Solana transaction outcome.
Sealevel, the parallel runtime on Agave 4.1.1 validators, uses those declared account lists to schedule non-overlapping transactions concurrently and to serialize transactions that share a writable account.
You buy throughput by partitioning state across accounts so unrelated users do not contend on one hot account.
A durable data account must hold at least the rent-exempt minimum lamports for its data size (queried via getMinimumBalanceForRentExemption); underfunded accounts are not a sustainable design for long-lived state.
Fees are paid in lamports by a designated fee payer; priority is expressed with compute unit limits and price, layered on top of signature-based base fees.
The path from client to confirmation is one pipeline, not separate "send" and "wait" products:
Client (wallet / kit / CLI)
| build instructions + account metas
| sign with Ed25519 keypair(s)
v
RPC node ---- sendTransaction ---->
|
| Gulf Stream forwards to upcoming leader
v
Leader (current slot)
| order via PoH, execute via Sealevel
| each instruction: load accounts -> run program -> write
v
Block propagation (Turbine) + validator votes
|
| commitment ladder:
| processed -> confirmed -> finalized
v
Client polls or subscribes until chosen commitmentReading that flow with the foundations in mind: the client is assembling which accounts a stateless program may touch, funding any new accounts with lamports, signing with keypairs, targeting one cluster's RPC, and waiting for a commitment that matches the risk of the UX.
How a Transaction Flows deepens each hop; this page only needs you to see that hops are not a second architecture.
Cross-program work still sits inside one transaction: a program may CPI into another program, but every account the callee needs must already appear in the transaction's account list with correct metas.
Composability is explicit wiring, not ambient call context.
Once the core loop is clear, design choices follow from it rather than from framework folklore.
Partition state so Sealevel can run independent users in parallel; a single global account that every user must write becomes a throughput ceiling and a rent/size problem.
Prefer PDAs for program-controlled vaults and deterministic "one account per user/entity" layouts; prefer ordinary keypairs for human authorities and fee payers.
Match commitment to consequence: dashboards often use confirmed; irreversible off-chain side effects and high-value settlements usually wait for finalized.
Keep environments strict: a dev keypair, a mainnet keypair, and a local validator keypair are different identities on different chains, even when base58 strings look similar across clusters only by coincidence of generation, not by shared state.
When porting from EVM, do not look for "storage inside the program"; look for "which accounts does this instruction declare, who owns them, and who signs?"
The table below compresses the two account models without replacing the dedicated EVM page.
| Aspect | EVM-style contracts | Solana accounts model |
|---|---|---|
| Where code lives | Contract bytecode at an address | Executable program account (program id) |
| Where state lives | Storage slots inside the contract | Separate data accounts owned by a program |
| How callers are identified | Implicit msg.sender | Explicit signer accounts in the instruction |
| How mappings work | mapping in contract storage | Many accounts, often PDAs seeded by key material |
| Parallelism | Limited by shared contract storage | Sealevel parallelizes non-overlapping account locks |
| Storage economics | Gas for SSTORE-style updates | Rent-exempt lamport deposit sized to account bytes |
| Atomic multi-step work | One transaction, sequential calls | One transaction, explicit multi-instruction + CPI |
Commitment levels are another operational table you should internalize early.
| Commitment | Rough meaning | Typical use |
|---|---|---|
processed | Leader executed; not yet heavily voted | Optimistic UI, speculative reads |
confirmed | Supermajority has voted on the block | Default for many app actions |
finalized | Rooted / practically irreversible under normal conditions | Settlements, withdrawals, cross-system callbacks |
Clusters form a third axis of the same model: localnet for fast CI, devnet for public sandbox SOL and shared testing, testnet for validator-facing experiments, mainnet-beta for real value.
Clusters & Networks and SOL, Lamports & Units flesh out operations and precision; here the advanced point is simply that amount math, key management, and confirmation policy only make sense after you fix which chain you are on.
bigint math, not IEEE floats, for anything that will be signed or stored.sendTransaction returns a signature, the transfer is final." A signature means the node accepted the submission path; durability depends on the commitment level you wait for afterward.Everything is an account; programs execute against accounts named in atomic transactions, funded in lamports, authorized by signatures or PDAs, on one cluster, until your chosen commitment says you can trust the result.
It unifies wallets, programs, mints, and data under one load/store and ownership model, so fees, rent, locks, and RPC reads all use the same vocabulary.
A program account is marked executable and holds bytecode the loader runs; a data account holds application bytes interpreted by its owner program and is not executed as code.
Only the program that owns the account may modify its data (subject to runtime rules); other programs need CPI into the owner or must hold lamports/signers for operations the system allows.
All of its instructions succeed or none of their effects commit; there is no partial application of a failed transaction's instruction list.
The runtime uses the list for locking, signature checks, and Sealevel scheduling; undeclared accounts cannot be loaded mid-flight the way some VMs allow implicit storage access.
Transactions that do not share conflicting account locks - especially overlapping writable accounts - can execute concurrently; conflicting ones are ordered so writes stay consistent.
A lamport is the base integer unit (1 SOL = 1e9 lamports); the chain and APIs speak integers so amounts never depend on floating-point rounding.
A data-size-based minimum lamport balance that keeps an account alive without ongoing rent collection under current economics - fund it at creation via the rent-exempt minimum.
Keypairs prove human or server authority with Ed25519 signatures; PDAs are program-controlled addresses without secrets, authorized only when the owning program supplies the correct seeds at CPI time.
Almost always a cluster mismatch - CLI on devnet, explorer on mainnet-beta, or an RPC URL pointing at a different network than the wallet.
Many product actions use confirmed for responsive UX; use finalized before irreversible external effects, and treat processed as optimistic only.
This page is the full builder model (accounts through confirmation); the EVM page is a focused porting contrast for engineers who already think in contracts-with-storage.
No - Anchor 0.32.1 and @solana/kit 7.0.0 are ergonomic layers over the same accounts, instructions, metas, and RPC/commitment surfaces described here.
Skim Solana Basics for concrete examples, then deepen currency, keys, clusters, and transaction flow via the Related links below as you build.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.
Reviewed by Chris St. John·Last updated Jul 19, 2026