A transaction at the system level is a signed proposal to modify the blockchain’s state, expressed as a precise set of fields a node can verify and execute. It is the protocol’s unit of requested change, not the human action that triggered it. When a wallet shows a “Send” button, it hides this distinction and makes it easy to assume that clicking the button directly changes the chain. In reality, the protocol only ever sees and processes data objects, and it applies deterministic rules to decide whether to accept, ignore, or revert each proposal.
The Confusion: User Actions vs System Objects
Most users experience transactions through a wallet interface, so the mental model becomes “I clicked send, therefore the transfer happened.” The interface event, confirmation popups, and progress spinners all occur off-chain and are not visible to the protocol.
From the system’s perspective, there is only a stream of data objects arriving from the network. Each object must be parsed, checked, and possibly discarded according to protocol rules. Visibility in a wallet or explorer does not automatically mean the proposal has been accepted into the canonical state.
- A wallet button click is not a transaction; it is a user interface event that may lead to creating one or more transactions.
- A signed and broadcast transaction is not a guaranteed state change; it is only a proposal that nodes may or may not include in blocks.
- Being visible in a mempool is not being in the blockchain; mempools are local queues, not the canonical ledger.
- A transaction hash on a block explorer is not a final outcome; it is a reference to a proposal that might later fail or be reorged away.
- A successful wallet pop-up is not protocol-level confirmation; it reflects what the wallet believes happened, not a system guarantee.

Intent vs Transaction: Where the Boundary Lies
User intent is a human-level goal such as “send 1 coin to this friend” or “call this contract function once.” It is vague, context-rich, and not directly understood by nodes.
A transaction is the concrete data structure that encodes a specific proposed state change derived from that intent. It contains fixed fields like sender, recipient, value, nonce, fee parameters, and optional call data, which together define exactly what state transition is being requested under protocol rules.
- Intent contains a subjective goal (for example, “pay Alice back”), while a transaction contains an objective recipient address field.
- Intent may include fuzzy timing like “soon” or “when it’s cheap,” while a transaction encodes specific fee and gas parameters at a single moment.
- Intent can involve conditions in natural language, but a transaction only carries machine-readable call data and fixed rules for success or revert.
- Intent can change in the user’s mind after clicking, while a transaction, once signed and broadcast, is a fixed proposal from a specific account.
- Intent is not visible to the network at all, whereas the transaction is the only artifact that nodes receive, verify, and possibly execute.

Transactions as Untrusted Proposals
At the protocol level, a transaction is treated as an untrusted proposal to change state. Any node can receive arbitrary bytes from its peers, so it must assume nothing about correctness, honesty, or usefulness.
Each full node independently parses the transaction, checks that it follows format rules, verifies the signature, inspects balances and nonces, and simulates its effects under the protocol’s execution rules. Only if all checks pass and local policies like fee thresholds are satisfied can the transaction even be considered for mempool storage or block inclusion.
- Verify that the data has a valid transaction format and all required fields are present.
- Check that the signature matches the claimed sender account and the exact transaction contents.
- Compare the transaction nonce with the sender’s current nonce in state or local view for consistency.
- Ensure the sender’s balance can cover the value being sent plus the maximum possible fee under the provided gas and price parameters.
- Confirm that the requested operation is allowed by protocol rules, such as gas limits, size limits, and any current upgrade constraints.
Authorization: What a Signature Actually Represents
A transaction signature is a cryptographic proof that whoever controls a private key authorized this exact proposal. Conceptually, it binds a specific account to a specific set of transaction fields so that nodes can attribute the requested state change to that account.
The signature lets a node check “does this account authorize spending from itself in this way,” but it does not say anything about whether the action is sensible, profitable, or aligned with the user’s real-world intent. It also does not force any node to include the transaction; it only proves that the account cannot later deny having proposed it under the protocol’s assumptions.
- A valid signature does not guarantee execution or inclusion; it only authorizes the attempt.
- A signature does not check whether the action is wise or safe; it merely proves control of the account key.
- A signature does not freeze or reserve funds; balances can change before the transaction is executed.
- A signature does not make a transaction immune to protocol rules; invalid nonce, insufficient gas, or rule changes can still cause rejection.

Ordering and Uniqueness: The Role of Nonces
A nonce is a per-account counter that gives each transaction a unique position in that account’s sequence of proposals. For simple account models, the on-chain state stores the next expected nonce for each account, typically starting from zero and increasing by one for each accepted transaction.
When a node sees a new transaction, it compares the transaction’s nonce with its current view of the sender’s nonce. This comparison lets the node reject exact replays (too low), detect gaps (too high), and enforce that accepted transactions from the same account form a linear, ordered history without duplicates.
- Read the sender’s current nonce from local state or the best-known chain view (the expected next value).
- If the transaction nonce is lower than expected, treat it as a replay or already-consumed slot and reject it.
- If the transaction nonce equals the expected value, mark it as immediately executable, subject to other validity checks.
- If the transaction nonce is higher than expected, recognize a gap and optionally queue it in the mempool until earlier nonces are filled.
- Update the sender’s nonce in state only when a transaction with the expected nonce is actually executed in a block.

Fees as Signals, Not Payments
Transaction fees exist because block space and validator computation are scarce resources. Each block can only contain a limited amount of data and execution, so transactions compete for inclusion based on the fees they offer.
By attaching a fee rate or gas price, a transaction expresses how much the sender is willing to pay per unit of resource. Nodes that build blocks typically prefer higher-fee transactions because they increase revenue, subject to protocol rules. This makes fees a priority signal in a market for limited capacity, not a prepayment for a guaranteed result.
- Fees express the sender’s desired priority relative to other transactions competing for the same block space.
- Fees compensate validators for computation, storage, and bandwidth used when attempting to execute the transaction.
- Fees do not force inclusion in any particular block; block builders can ignore low-fee transactions indefinitely.
- Fees do not guarantee that contract logic will succeed; they pay for attempted execution, even if it reverts.
- Fees do not lock in a fixed waiting time; changing network conditions can make a once-competitive fee uncompetitive later.
Story: A Stuck Transaction and Competing Proposals
Consider an account that sends a transaction T1 with nonce 15 and a relatively low fee during a quiet period. The wallet broadcasts T1, nodes verify its format, signature, nonce, and balance, and many mempools store it as a valid but low-priority proposal.
Later, network demand spikes and blocks fill with higher-fee transactions. T1 remains in mempools but is consistently outcompeted for block space. The user, seeing no effect, sends a replacement transaction T2 with the same nonce 15 but a much higher fee and slightly different parameters.
Nodes that accept T2 now treat it as the current proposal for nonce 15 and may evict T1 from their mempools. When a block builder finally includes nonce 15 from this account, it is T2 that gets executed, and T1 can never be accepted because its nonce slot is already consumed. From the user’s viewpoint, the first transaction looked “stuck,” but from the system’s viewpoint, it was simply a low-fee proposal superseded by a higher-fee proposal for the same nonce.
Validity Does Not Imply Execution
A transaction can be valid according to protocol rules yet never be executed in any block. Validity means that, given the node’s current view of state, the transaction has correct format, a good signature, a consistent nonce, and sufficient balance to cover its declared maximum cost.
Execution requires an additional step: some block builder must choose to include the transaction in a block. That choice is influenced by fees, local policies, mempool content, and timing. A valid but low-fee transaction can sit in mempools, be evicted when space is needed, or become irrelevant if later state changes make its assumptions obsolete, all without ever being written to the chain.
- Its fee is consistently too low relative to competing transactions, so block builders never select it.
- A replacement transaction with the same nonce but higher fee is accepted instead, making the original unexecutable.
- There is a nonce gap for the sender, and earlier nonces are never filled, so later-nonce transactions remain perpetually queued.
- Nodes drop the transaction from mempools after time or size limits, and it is no longer propagated to new block builders.
- A protocol change or application-level upgrade makes the originally valid call data or target behavior obsolete before inclusion.
Why Transactions Can Fail Without Being "Wrong"
Even when a transaction is valid and selected for a block, its execution can still end in failure or revert according to deterministic rules. The protocol executes the transaction step by step, consuming gas and evaluating contract conditions, and it may reach a state where it must halt without applying the intended changes.
Common examples include running out of gas before completing the requested logic, hitting a programmed require/assert condition that fails, or encountering updated state that no longer satisfies assumptions encoded in the contract. In these cases, the transaction still consumes resources and usually pays fees, but the persistent state is rolled back to the pre-transaction snapshot for that account or contract scope.
- The transaction exhausts its gas limit before completing, causing an out-of-gas halt and revert of state changes.
- A contract require/assert or similar condition evaluates to false, triggering a revert according to its logic.
- The sender’s balance becomes insufficient during execution due to intermediate transfers or fee deductions, preventing a final transfer.
- Dependent state, such as a contract’s internal variables, has changed due to earlier transactions in the same block, invalidating assumptions.
- The transaction calls into another contract that itself fails or reverts, propagating the failure back to the original call.
What Transactions Guarantee vs What They Don’t
Key facts
Guarantee: Authorization Check
Nodes will verify that each transaction is authorized by the controlling key for the sender account before accepting it as valid.
Guarantee: Deterministic Execution Rules
Given the same transaction and pre-state, all honest nodes will compute the same execution result and state changes or revert.
Guarantee: Per-Account Nonce Sequencing
Accepted transactions from a given account will consume nonce values in order, preventing duplicates and simple replays.
Guarantee: Resource Accounting via Gas/Fees
Execution will be bounded by declared gas limits and associated fees, ensuring that resource usage is paid for and cannot be infinite.
Non-guarantee: Inclusion in Any Specific Block
The protocol does not require block builders to include any particular valid transaction, regardless of its fee.
Non-guarantee: Maximum Waiting Time
There is no protocol-level promise that a valid transaction will be included within a certain number of blocks or seconds.
Non-guarantee: Desired Business Outcome
The system does not evaluate whether the transaction achieves the user’s real-world goal; it only applies programmed logic.
Non-guarantee: Permanent Mempool Presence
Nodes can drop transactions from mempools at any time due to size limits, policy changes, or restarts, without recording them on-chain.
Where Transactions Fit in the Larger System Lifecycle
The lifecycle of a transaction starts when a wallet converts user intent into a concrete data structure with fields like sender, recipient, value, nonce, and fee parameters, then signs it. This signed object is broadcast to one or more nodes, which propagate it across the network if it passes basic validity checks.
Valid transactions typically enter node mempools, where they wait and compete for block space based on fees and local policies. When a block builder constructs a new block, it selects some mempool transactions, executes them in a defined order, and applies resulting state changes or reverts. Only transactions that end up in blocks that remain part of the canonical chain affect long-term state; others may remain in mempools for a while and eventually be dropped.
- User intent is formed as a human goal, such as transferring value or invoking contract logic.
- A wallet or tool encodes this intent into a specific transaction structure and signs it with the sender’s key.
- The signed transaction is broadcast to nodes, which verify it and, if valid, store it in their mempools.
- Transactions in mempools compete for selection based on fees, size, and node or protocol policies.
- A block builder chooses a subset of transactions, orders them, and executes them as part of a new block.
- Executed transactions either update state or revert, and only those in blocks that remain on the canonical chain persist in the global state.

The Transaction Mental Model
A useful way to think about a transaction is as a signed, ordered, fee-bearing proposal that competes for execution under fixed rules. It is derived from user intent but is not identical to that intent and carries no promise about outcomes.
Nodes treat each transaction as untrusted input, verifying authorization, nonce sequencing, and resource payment before even considering it for inclusion. Validity means the proposal fits the rules; execution and success depend on selection, current state, and deterministic contract logic. This separation explains why clicking send, seeing a hash, or paying a fee are not the same as achieving a guaranteed state change.
- A transaction is a proposal, not a promise, to change the blockchain’s state.
- My signature authorizes the proposal from my account, but does not guarantee it will be executed or succeed.
- The nonce defines my account’s transaction sequence and prevents simple replays or duplicates.
- Fees express my willingness to pay for scarce resources and priority, not a right to inclusion.
- Validity is separate from execution; a valid transaction may never be included in a block.
- Execution is separate from success; an included transaction can still revert without achieving my intended effect.