What’s an account?
Solana’s docs give the following definition for an account:
Account
A record in the Solana ledger that either holds data or is an executable program.
Like an account at a traditional bank, a Solana account may hold funds called lamports. Like a file in Linux, it is addressable by a key, often referred to as a public key or pubkey.
The key may be one of:
- an ed25519 public key
- a program-derived account address (32-byte value forced off the ed25519 curve)
- a hash of an ed25519 public key with a 32 character string
Each account has an owner:
Account owner
The address of the program that owns the account. Only the owning program is capable of modifying the account.
To summarize, an account either holds data or is an executable program. Each account has an address (usually a public key). Each account also has an owner, which is the address of a program account. Only an account’s owner can modify its state.
There’s a notable difference between the way state is handled in Ethereum and in Solana. In Ethereum, contract accounts store code, but they also store state (which the code can read/write). In Solana, a program account ONLY stores code, and its state is stored in one or more data accounts. In other words, if you are a Solana smart contract developer and you want to store some data, you first need to deploy the program account, and then create one or more data accounts to store data associated with the program.
the entire set of accounts owned by a given program can be regarded as a key-value store where a key is the account address and value is program-specific arbitrary binary data. A program author can decide how to manage the program’s whole state as possibly many accounts. (source)
What does an account store?
I’m ripping this straight from this great article.
Note that program/executable accounts are immutable—their data cannot be modified or deleted. This means you can’t add lamports to executable accounts.
How is an account created?
If a client wants to create an account, they must follow these two steps:
- Generate a keypair (public and private key)
- Call some Rust code that calls
SystemProgram::CreateAccount
. When calling this, the public key and the storage size of the account must be specified. The maximum size of an account’s data is currently 10 megabytes.
When an account is created, its data is zeroed out. Also, note that an account’s storage size cannot be increased.
See here for some example client code.
How does ownership work?
Each newly created account is owned, by default, by a built-in program called the “System Program.”
Only the owner of an account may change the account’s owner. Usually, after the System Program creates an account, it will change its owner to a different program. I’m not exactly sure how this works. For example, in Anchor’s tutorial, ownership is changed from the System Program to the current program.
Further, accounts may only be assigned a new owner if their data is zeroed out. This guarantees that a program modifying some account is either starting from a blank slate, or starting with the state they previously read/modified.
If an account is not owned by some program, that program is only permitted to read its data and credit the account (any program can add lamports to a data account, but only the owner of an account may subtract its lamports).
How does rent work?
Each account needs to pay rent in order not to be deleted. Why? 👇
Keeping accounts alive on Solana incurs a storage cost called rent because the blockchain cluster must actively maintain the data to process any future transactions.
Rent is debited from an account (in lamports) every epoch. The amount of rent is based on how much data is stored in the account.
An account be made exempt from rent collection by depositing at least 2 years worth of rent.
Open questions
Question 1: Where are accounts stored? On-chain or off-chain? Based on the quote below, I think it’s stored off-chain?
The set of accounts represent the current computed state of all the transactions that have been processed by a validator. Each validator needs to maintain this entire set. Each block that is proposed by the network represents a change to this set, and since each block is a potential rollback point, the changes need to be reversible.
Based on this quote, it sounds like the blockchain only stores transactions (which is consistent with the glossary), and the nodes store account state in memory.
Question 2: This seems wrong to me? (source) Storing accounts on Ethereum increases the amount of data each node in the network has to store, it’s not like it’s free.
Keeping accounts alive on Solana incurs a storage cost called rent because the blockchain cluster must actively maintain the data to process any future transactions. This is different from Bitcoin and Ethereum, where storing accounts doesn’t incur any costs.