A transaction in Solana is “An atomic bundle of instructions that declares all state it will touch, executed deterministically by the runtime”
There are four important requirements of a Transaction

  1. Accounts: For a transaction to happen we must reference all accounts involved
    • A transaction must list every account that any instruction will read or write
    • If an account is missing → program cannot access it → Transaction will not happen
    • This exists because:
      • Solana executes transactions in parallel
      • Runtime must know ahead of time:
        • Which accounts are read
        • Which accounts are written
  2. Composition: A Solana transaction is not a single function call. It is a sequence of instructions, Executed in order which All succeed or all fail. for example a transaction can go like
    1. Create account
    2. Initialize token account
    3. Transfer tokens
    • All three share the same account list and same atomic boundary
  3. Instructions: interface with Solana programs. for context, Transaction is like a container and Instruction is the actual program invocation
    • Each instruction Targets exactly one program and Passes Accounts and Instruction data
    • Programs are Stateless with Pure logic and Cannot access anything except passed accounts
  4. Atomicity: Fails entirely if any instruction fails
    • This is strict ACID-style atomicity
    • If instruction 3 fails:
      • Instruction 1 and 2 are rolled back
      • No partial state updates
      • Fees are still paid

A Transaction is represented as

{
  message: {
    instructions: Array<Instruction>,
    recent_blockhash: number,
    fee_payer: PublicKey,
  },
  signers: Array<Uint8Array>,
}
  • message: The message is the part that gets Serialized, Signed and Verified by validators
  • instructions: Each instruction contains program_id, accounts (AccountMeta list) and data (opaque bytes)
    • All instructions share the same account pool. And Internally:
      • Accounts are de-duplicated
      • Referred to by index
      • Marked read-only or writable
    • This is how Solana avoids repeated pubkeys, keeps transactions compact and Enables lock analysis
  • recent_blockhash:
    1. It prevents transaction replay
    2. Anchors transaction to recent ledger state
    3. Enables fast rejection of stale transactions
    4. Allows optimistic execution
    • Validators will Reject transactions with old blockhashes and Avoid re-executing ancient transactions
    • This is why Solana transactions Expire quickly but they’re fast
  • fee_payer: The account that pays transaction fees, must be a signer and should have enough lamports
    • Fee payer does not need to be writable
    • Fees are deducted before execution
    • Even if transaction fails fee payer still pays
  • signers: These are the cryptographic signatures over the message
    • Every account marked as isSigner must appear here
    • Order matters
    • Missing signature = transaction rejected
    • Authorization is account-based, not caller-based
    • Programs do NOT know, “Who submitted the transaction”. They only know “Which accounts signed”

Q How runtime actually processes this ?
A walk through what a validator does

  • Step 1: Deserialize transaction

    • Extract message
    • Extract account list
    • Extract instructions
  • Step 2: Verify signatures

    • All required signers present
    • Message hash matches signatures
  • Step 3: Account locking (THIS IS WHY EXPLICIT ACCOUNTS EXIST) From account metadata:

    • Writable → exclusive lock
    • Read-only → shared lock

    Runtime builds a dependency graph:

    Tx A: writes X
    Tx B: reads X
    Tx C: writes Y
    

    Execution plan: A & C → parallel and B → waits
    This is Sealevel, Solana’s parallel execution engine

  • Step 4: Instruction execution

    • Instructions run sequentially within a transaction
    • CPI allowed and it should must obey declared accounts
    • No instruction can:
      • Create hidden side effects
      • Access undeclared state
  • Step 5: Commit or rollback

    • Any failure → rollback everything
    • Success → commit state changes

Q Why Ethereum cannot do this ?
A

  • Ethereum contracts access global storage, so the state touched is dynamic which introduces conflicts discovered at runtime
  • In Solana, State is declared upfront, Conflicts known before execution and Parallelism is safe
  • This is why Ethereum scales via L2s and Solana scales via hardware

Q CPI can access other program’s accounts, right?
A Yes but:

  • Accounts must still be declared
  • CPI cannot magically escape the transaction boundary