What’s a transaction?
Solana’s docs give the following definitions for a transaction and an instruction:
Transaction: One or more instructions signed by a client using one or more keypairs and executed atomically with only two possible outcomes: success or failure.
Instruction: The smallest contiguous unit of execution logic in a program. An instruction specifies which program it is calling, which accounts it wants to read or modify, and additional data that serves as auxiliary input to the program. A client can include one or multiple instructions in a transaction. An instruction may contain one or more cross-program invocations.
So basically, a transaction contains multiple instructions. And each instruction specifies some code to be run.
That’s the simplistic definition. If we look elsewhere in the Solana docs, we get a more detailed picture.
The diagram below summarizes things better than I could put into words. In short, a transaction consists of an array of signatures and a message. A message consists of a header, an array of addresses, a blockhash, and an array of instructions. Here are a few important things to note.
- Instructions are executed in order and atomically.
- Some account addresses don’t require signatures. For example, a program might enforce that only a certain account can increment a counter, in which case the account’s address would require a signature. On the other hand, a program could let anyone read/write anything, in which case no signature would be required. For more on this, see the Anchor docs.
- A “program id” is the public key of the account containing a program. Basically, it specifies what code should be run.
- Accounts serve as both “the inputs and outputs of a program.” In other words, on-chain state is represented by accounts. If a program wants to modify on-chain state, it modifies an account (or multiple accounts).