A transaction carries a signed message describing the work to run. Its accounts, permissions, instructions and validity conditions determine what the runtime can execute. Read the execution result and resulting state to know what the approved request actually did.
The signature covers a constructed message
A wallet approval normally signs a transaction message. The message describes the relevant accounts, instructions and validity information under the chosen format. A transaction also carries the required signatures.
For ordinary recent-blockhash transactions, the builder obtains a recent blockhash and retains the associated validity-height information. The blockhash is part of the message. Replacing it after signing changes the bytes that the signatures authorised.
The transaction's first signature is commonly used as its transaction ID for lookup. An application can know that identity before execution. It should keep the signature with the intended action and construction metadata so it can recover from a lost send response.
Formats differ. Legacy and v0 organise account references and resources differently from v1. Learn the general roles here, then use the version guide when building or decoding a particular wire format.
An instruction identifies a program and its inputs
An instruction has a target program, a list of accounts and bytes interpreted by that program. For a simple SOL transfer, the target is the System Program and the operation data includes the transfer amount.
As an educational description, Alice asks for a 0.25 SOL payment to Bob. Alice is the payer and sender; Bob is the receiving account; the System Program executes the transfer rules. These named roles are a readable explanation, not a literal serialized JSON message.
A token transfer needs different records: source and destination token accounts, the applicable token program and the required authority. Checked transfer variants also verify mint-related information. A swap adds application-specific state and can invoke token instructions internally.
To interpret an unfamiliar instruction, identify the actual program ID and the program's documented data layout. The website label is not the instruction contract. A decoder can help, but its output must correspond to the program and version used.
Accounts have signer and access roles
The message's permissions tell the runtime which accounts can be written and which keys must authorise the transaction. Read-only access allows inspection; writable access permits changes only within the remaining runtime and program rules.
In the simple SOL transfer, Alice must sign and her balance changes. Bob's balance also changes, so the receiving account is writable, but Bob does not normally need to sign the incoming payment. The System Program is used as an executable program, not as a person authorising the transfer.
A different account can pay the network fee where the transaction's rules and signers support that arrangement. This separates who authorises an application action from who funds processing.
Signer status alone is insufficient for a business permission. An application must check that the supplied signer is the authority for the relevant account or position. The permission guide explains how this relates to program ownership.
A later failure rolls back earlier app transfers
Several actions can share one approval
A transaction can include multiple instructions in a defined order. For example, it can create a receiving token account, transfer tokens into it and perform another supported action. An outer application instruction can also call other programs through CPI.
This composition lets a user approve a complete operation rather than manually perform every setup step. It also means the transaction can do more than the website's main verb suggests. Account creation, approvals and cleanup should all be explained by the intended workflow.
Instructions share the transaction's resource and outcome context. A new action can increase required compute, account access or message size. Builders should simulate the complete final construction, including setup paths that only occur for a first-time user.
A simulation of an earlier construction is useful evidence about that construction. If the application later adds an instruction or changes accounts, it needs to reassess the final message rather than treating the old result as unchanged.
Work through a two-payment failure
Choose a teaching account with 1.5 SOL and two requested payments: 1 SOL to Bob, then 1 SOL to Carol. Assume the payer can cover the network fee but has no additional incoming funds in this transaction.
The first transfer could execute against the provisional state. The second then lacks sufficient funds. Because application changes are atomic, Bob does not keep a successful first payment from this failed transaction, and Carol receives neither.
The transaction can still pay its network fee. With a chosen 0.000005 SOL fee and no other retained effects, Alice ends at 1.499995 SOL. A log showing the first instruction ran is therefore different from evidence that Bob received a final transfer.
Durable nonce transactions have specific runtime handling: valid nonce advancement and fees can be retained even when later application execution fails. That is why the broad phrase nothing changes on failure is inaccurate. Inspect the actual mechanism involved.
Validity determines whether a request can still land
Ordinary requests use a recent blockhash whose usable lifetime is bounded. Builders should save the returned last-valid block height and compare it with block height, not slot or a guessed fixed number of seconds.
A wallet-signing delay consumes part of that lifetime. An endpoint with a different view can also fail to recognise a blockhash used by another service. A blockhash error needs construction context before it can be classified as true expiry.
A durable nonce uses an account-based validity mechanism with its own authority and advancement rules. It is useful in workflows where obtaining all signatures within the ordinary window is unsuitable.
After submission, expired validity does not establish that the original action never executed earlier. Keep observing the original signature and relevant state before rebuilding a one-time payment.
Read submission, execution and acceptance separately
Submission is the service receiving or forwarding the signed request. A successful API response can return its signature before successful network execution is known.
Execution is the program result. Read the error field, logs and resulting account changes. A transaction in accepted history can record an execution failure.
Acceptance and finality describe the network history under the current consensus model. Foundation migration guidance says confirmed and finalized now coincide on migrated clusters. Use current guidance when selecting commitment.
For an investigation, preserve the network and signature, decode the programs and instructions, read execution, reconcile the accounts and record costs. The explorer walkthrough puts these steps into a user-facing example.
Common questions
Can I change the recipient after signing?
That changes the signed message. Obtain the required signatures over the actual final message rather than reusing signatures for different bytes.
Does one approval mean one program call?
No. A transaction can contain multiple instructions and programs can make inner calls. Inspect the complete constructed operation.
Why did a first instruction appear in logs even though the transfer failed?
Logs record execution progress. A later failure rolls back the transaction’s application changes, so logs alone do not establish the final balances.
Sources and documentation
- Solana transactions
- Transaction structure
- Solana account model
- Solana transaction fees
- getLatestBlockhash
- sendTransaction
- getSignatureStatuses
- getTransaction
- simulateTransaction
- Durable nonce execution and failure handling
- Solana Foundation: Alpenglow status and migration
Found an error or an outdated detail? Send a correction.
