On Solana there is just... accounts. One model. Everything is an account — your wallet, a deployed program, a token mint, a user's token balance. All of them live in the same flat key-value store where the key is a 32-byte address and the value is the account data.
It sounds simple. It's actually a pretty elegant design decision with a lot of implications.
The Filesystem Analogy #
Here's the mental model that clicked for me: think of Solana like a filesystem.
Every account is a file. Each account (file) has:
-
metadata:
-
owner
-
permissions
-
size
-
contents:
-
the actual data
Program accounts are executable files. Data accounts are the documents those programs read from and write to. And the System Program? That's the OS kernel — it handles creating new files and transferring ownership.
The Five Fields Every Account Has #
No matter what an account represents, it always has the same five fields:
— the SOL balance. 1 SOL = 1,000,000,000 lamports.lamports
— a raw byte array. This is where all state lives.data
— the program that controls this account and can modify its data.owner
— a boolean. Ifexecutable
true
, this account contains a deployed program. -
— deprecated. You'll see it set torent_epoch
u64::MAX
on all modern accounts.
The ownership rule is the key security primitive: only the owner program can modify an account's data or debit its lamports. Anyone can credit lamports to any writable account. Simple, but powerful.
Programs Don't Store Their Own State #
This is the one that surprises every Web2 developer: Solana programs are stateless.
A program's executable bytecode lives in one account. Any data that program needs lives in entirely separate accounts. The program just reads and writes those accounts at runtime. It's the difference between a web server (the program) and a database (the data accounts) — they're separate things.
Reading a Real Account On-Chain #
To make this concrete, I fetched the Wrapped SOL mint account — one of the most fundamental accounts on Solana mainnet. Here's how I pulled the raw data using @solana/kit
:
import { createSolanaRpc, address, getBase64Encoder, getBase16Decoder } from "@solana/kit";
import { getMintDecoder } from "@solana-program/token";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const mintAddress = address("So11111111111111111111111111111111111111112");
const { value: accountInfo } = await rpc
.getAccountInfo(mintAddress, { encoding: "base64" })
.send();
const dataBytes = getBase64Encoder().encode(accountInfo.data[0]);
The account data comes back as base64. Once decoded into raw bytes, I ran it through two decode paths — the Token Program codec, and a manual byte-level read using DataView
:
// Codec approach
const mint = getMintDecoder().decode(dataBytes);
// Manual byte-level approach
const view = new DataView(dataBytes.buffer, dataBytes.byteOffset, dataBytes.byteLength);
const supply = view.getBigUint64(36, true); // bytes 36–43, little-endian
const decimals = view.getUint8(44); // byte 44
Both approaches confirmed the same thing — here's what the terminal showed:
Supply is 0 (wSOL is minted on demand), decimals is 9, and both mint and freeze authorities are null
— meaning no one can mint more or freeze transfers. The account is fully decentralized.
Rent Exemption #
One last thing: every account must hold a minimum lamport balance proportional to its data size. This keeps the validator state from bloating with abandoned accounts. For a zero-data account it's roughly 0.00089 SOL. Using the Solana CLI You can calculate exact amounts with:
solana rent <data-size-in-bytes>
If an account drops below this threshold, it gets purged. So whenever you create an account in a program, you're responsible for funding it past the rent-exempt minimum.
Key Takeaway #
Solana's account model is the foundation for everything else — PDAs, token accounts, program-derived state. Once you internalize that all state lives in accounts, programs are stateless, and ownership = write permission, the rest of the ecosystem starts to make a lot more sense.
This post is part of my 100 Days of Solana series. Follow along as I go from zero to deployed program. Github Repo