5. Transactions and runtime
You now know that accounts hold state. A transaction is the envelope that asks programs to change that state. This chapter opens the envelope and follows it through the runtime.
Instruction first, transaction second
Section titled “Instruction first, transaction second”An instruction describes one program call:
program idaccount list with signer/writable metadatainstruction data bytesA transaction contains one or more instructions plus a message and signatures.
Transaction├── signatures└── message ├── account addresses and permissions ├── recent blockhash └── compiled instructionsThe message, not an informal description in the UI, is what gets signed.
Why multiple instructions share one transaction
Section titled “Why multiple instructions share one transaction”Suppose Alice needs to create a profile account and initialize it. The transaction can include:
- a System Program instruction to create and fund the account;
- a Profile Program instruction to initialize its data.
The transaction is atomic. If initialization fails, state changes from the create step are rolled back with the transaction. A processed failure can still incur a fee.
Freshness prevents indefinite replay
Section titled “Freshness prevents indefinite replay”A recent blockhash limits the validity window of an ordinary transaction.
fetch blockhash ↓build exact message ↓collect signatures ↓submit and confirm before expiryIf the blockhash expires, the transaction must be rebuilt and signed again. Changing only the blockhash still changes the signed message.
Account metadata is both permission and schedule
Section titled “Account metadata is both permission and schedule”Each instruction marks accounts as signer or non-signer, and writable or read-only. These flags let the runtime enforce privileges and detect conflicts.
Tx A writes Market XTx B reads Market X=> conflict
Tx A writes User ATx B writes User B=> no direct account conflictPrograms cannot promote an account to privileges the transaction did not provide. CPI also cannot invent signer or writable authority.
The execution pipeline
Section titled “The execution pipeline”A simplified pipeline is:
- deserialize and sanitize the transaction;
- verify signatures and freshness;
- load and lock accounts;
- charge applicable fees;
- execute instructions in order;
- meter compute and enforce runtime limits;
- commit changes only if the transaction succeeds;
- record status and logs for observation.
The runtime enforces protocol rules. The program enforces business rules. The runtime can know that Alice signed; only the program can know whether Alice is the authority allowed to update this particular profile.
Fees and compute units
Section titled “Fees and compute units”Do not translate Ethereum gas too literally. Solana separates several ideas:
- a base transaction fee associated with signatures;
- an optional prioritization fee;
- compute-unit limits that bound execution work;
- account storage balances for persistent state.
A client can add Compute Budget instructions to request a limit and set a compute-unit price. A practical production process is:
- simulate the final instruction set;
- observe compute consumption;
- add a measured safety margin;
- select a priority price appropriate to current conditions;
- rebuild and sign the final message.
Check current official formulae and limits before production. Hard-coded protocol constants age badly.
Cross-Program Invocation
Section titled “Cross-Program Invocation”A program can invoke another program inside the same transaction.
User transaction ↓Swap Program ├── CPI to Token Program: debit input vault └── CPI to Token Program: credit output accountThis is composability. The calling program passes accounts and privileges to the callee. For a PDA authority, the controlling program supplies the correct seeds and bump through runtime-supported signing.
A program should verify the target program ID instead of accepting an arbitrary executable account. It should also verify resulting balances or state when business logic depends on them.
Simulation is a rehearsal
Section titled “Simulation is a rehearsal”Simulation can expose logs, custom errors, account-loading problems, and compute use before submission. It is not a settlement guarantee. State can change between simulation and execution.
Use simulation to answer “would this likely execute against this snapshot?”, not “has this transaction happened?”
Versioned messages and address lookup tables
Section titled “Versioned messages and address lookup tables”Complex transactions may need many account addresses. Versioned transactions can reference Address Lookup Tables to encode addresses more compactly.
Lookup tables help message capacity. They do not remove account locks, compute limits, or the requirement to validate every account.
Build a confirmation state machine
Section titled “Build a confirmation state machine”A backend should model transaction progress explicitly:
CREATED -> SIGNED -> SUBMITTED -> CONFIRMED -> FINALIZED | | v v EXPIRED FAILEDStore:
- transaction signature;
- blockhash validity context;
- business operation ID;
- cluster and RPC provider;
- observed error and logs;
- latest commitment status.
Idempotency prevents duplicate callbacks or retries from releasing goods twice.
Diagnose failures by layer
Section titled “Diagnose failures by layer”- Signature error: wrong signer or mutated message.
- Blockhash error: transaction expired or context mismatched.
- Account in use: writable-state contention.
- Compute exceeded: inefficient program or insufficient limit.
- Invalid owner/PDA: incorrect or substituted account.
- Custom program error: inspect program-specific logs and mapping.
- Insufficient funds: distinguish fee, transfer value, and storage funding.
- Message too large: reduce accounts/instructions or evaluate versioned messages.
Check your understanding
Section titled “Check your understanding”Describe the difference between these four objects:
instruction datatransaction messagetransaction signaturetransaction statusThen explain why a successful simulation does not prove confirmation.
Next, turn this execution model into application code in Programs, SVM, and development.