Workflows · Explanation
Transaction lifecycle
A returned signature means the node accepted signed bytes into its submission path. A successful receipt means the node records successful execution. Durable recovery and foreign-chain settlement are later, separate questions. Applications work reliably when they preserve that distinction and retain enough information to resolve an ambiguous response.
The running example is a single transaction containing two System transfers. Both instructions share one signed message and one outer execution outcome. The quickstart constructs and verifies that artifact offline; this chapter follows what happens when an application submits a real transaction to a healthy compatible node.
This is the causal explanation of each stage. If you already have a signature or an ambiguous timeout, follow Inspect a transaction for the bounded diagnostic procedure. Use RPC reference for complete request and error contracts.
1. Construct the intended operation
Choose the target network, package version and execution path before signing. Obtain a current blockhash from that network, declare the fee payer and instruction accounts, and encode amounts in integer base units. An account's signer and writable flags are capabilities that execution will check; they are not descriptive comments.
For the two-transfer example, the payer signs a message containing both destinations and amounts. Altering either instruction after signing invalidates the signature. A transaction with multiple instructions has one rollback boundary. Sending those instructions as two transactions creates two independent outcomes instead.
Solana legacy and version-0 wire messages remain the public signed formats. Address lookup tables let a version-0 message refer to additional accounts, but their contents are bank state: admission resolves them and execution resolves them again at the authoritative execution slot. The internal ETOV0TX1 representation is not a public submission format. Wire decoding.
Unsigned builders such as eto_buildWorkflow can help encode complex instructions. They return account requirements and instruction bytes, leaving the client responsible for reviewing and signing. A builder response does not establish that a target is deployed or that its application preconditions hold.
2. Check a prediction, then sign the real message
simulateTransaction uses a disposable execution context. Its result can contain logs, consumed units, return data and an execution error. It does not reserve the state it observed. Another transaction can change a balance or account before yours executes.
The sigVerify and replaceRecentBlockhash options default to false in this checkout. Replacing a blockhash is useful for a simulation, but the replacement is not a signature over the real transaction you later submit. Unsupported engine paths must fail without mutating canonical state. Simulation contract.
Keep the exact signed bytes and first signature in your application record before transmission. For a financial operation, also retain an application operation identifier and the expected effect. This is application design guidance: the transport cannot decide whether two differently signed transfers represent one intended purchase or two.
3. Admission checks the envelope
Use an explicit encoding to avoid ambiguity:
{"jsonrpc":"2.0","id":1,"method":"sendTransaction","params":["<base64 signed transaction>",{"encoding":"base64"}]}The placeholder must be replaced with the complete serialized transaction. The handler enforces decoded size, canonical parsing, required signature count, nonzero signatures, signature verification, and recent blockhash or valid durable nonce. It rejects an externally submitted transaction that names the built-in faucet as fee payer. Embedded EVM operations additionally check chain identity, recovered sender and nonce sequencing. Admission.
Successful forwarding requires an ingest HTTP 200 response whose decoded acknowledgement has accepted >= 1. An HTTP connection succeeding is not enough. Full preflight execution is not part of this handler, and client terminology such as skipPreflight does not disable these server checks. Forward acknowledgement.
The default decoded admission ceiling is 1 MiB, subject to a 4 MiB hard cap. The HTTP request-body limit is separately 2 MiB, and base64 expands the wire request. SDK packing and account-index limits can be smaller still. Use fees and limits rather than assuming one size constant governs every layer.
4. Consensus orders the payload; execution applies it
An admitted transaction waits for selection into a proposed payload. Selection is subject to capacity, compute budget and the node's ordering rules; an admission acknowledgement is not a reserved block position.
Finalized payloads reach the reporter's execution pipeline in height order. Decode and signature preparation may look ahead when they are pure functions of transaction bytes. State-dependent address-table resolution cannot read a future or unrelated bank snapshot merely to increase overlap.
The executor verifies, classifies dependencies and chooses execution lanes, then merges accepted effects in transaction order. A GPU completion cannot publish ahead of an earlier conflicting transaction. Native programs, SVM, EVM, WASM, Move, ZK and Bombil have distinct adapters and gates but feed the shared state model. Reporter entry and preparation, execution mechanisms.
The transaction journal owns speculative writes. If the second transfer fails, successful program writes from the first must not leak into canonical state. An executed failure can still retain a fee debit and, for a canonical EVM revert, the caller nonce. Those permitted failure effects are rebuilt from pre-transaction state. A zero-compute rejected path does not acquire an execution fee through this helper. Failure changeset.
Explore submission and observation.
5. Read the execution result
After submission, query the retained signature:
{"jsonrpc":"2.0","id":2,"method":"getSignatureStatuses","params":[["<transaction signature>"]]}| Observation | Interpretation |
|---|---|
JSON-RPC error | The request failed; inspect the code and message even when HTTP is 200 |
| A null status entry | This node has no receipt for that signature, or the entry was malformed |
A status with err:null | The receipt records successful execution |
A status with non-null err | The receipt records failed execution |
| A client deadline expires | The client stopped observing; the operation's outcome is not established |
The source handler labels every found receipt confirmationStatus:"finalized" and uses confirmations:null. It does not expose an incremental processed → confirmed → finalized progression. Use getTransaction or the relevant EVM receipt method for details, logs and fees. An EVM receipt's existence alone does not mean success; inspect its status. Receipt-backed status.
The public CLI's confirmation loop accepts confirmed/finalized status and checks the execution error. The inspected SDK helper has a broader non-null, error-free completion test. Pinning a client package therefore matters even when both call a method with the same name. Exact client behavior belongs in RPC and SDK contracts.
6. Reconcile notifications and retries
A signature WebSocket subscription is one-shot. Installation-time receipt lookup and lag reconciliation reduce the risk of missing its only completion event. Ordinary account/log broadcasts have a bounded channel and can lose events for slow subscribers. After disconnect, recreate subscriptions and reconcile against authoritative receipt or state reads. WebSocket recovery.
If submission times out, first query the original signature and expected application effect. An exact-byte retry preserves transaction identity and remains subject to replay protection and blockhash validity. Rebuilding with a new blockhash and signing again creates a new transaction identity; if the first operation already succeeded, a second valid transfer can execute too.
A null receipt does not prove the first transaction failed. Consider endpoint health, history retention, the blockhash validity window and application state before constructing a replacement. Durable nonce transactions have their own nonce-account lifecycle; an arbitrary long-lived blockhash is not a durable nonce.
7. Establish durability or settlement when the job needs it
Execution updates the live state view before the separate writer completes every storage barrier. The post-apply finalize lane consumes height-ordered results, evaluates the drain gate and publishes replication and interop material under its own rules. A receipt label is not itself proof that all validators have fsynced the result. Finalize lane.
For restart guarantees, follow durability and recovery. For a cross-chain operation, inspect the HILSA outbox, certificate, destination verification and actual destination receipt as separate steps. A successful local withdrawal request is not evidence that the recipient has received foreign assets; the settlement workflow defines those boundaries.
This run verified transaction construction, signatures, serialization, round-trip decoding and tamper rejection offline. It did not submit a funded transaction: the earlier public health check reported a halted persistence drain, and the 8 September 01:44 UTC repeat returned an upstream HTTP 521 error. Use the availability record and repeat health/version checks before running a live example.