---
# System prepended metadata

title: What Actually Happens When You Send an Ethereum Transaction?
tags: [' mempool', ' finality', ' block-building', ' transactions', ethereum, ' consensus']

---

---
title: What Actually Happens When You Send an Ethereum Transaction?
description: Following a transaction from your wallet through the mempool, into a block, and to finality - explained simply with real examples
tags: ethereum, transactions, mempool, consensus, finality, block-building
---

# What Actually Happens When You Send an Ethereum Transaction?

## Abstract

Every Ethereum user has clicked "Confirm" on a transaction, but what actually happens next? This article traces a transaction's complete journey from wallet signature through the mempool, block building process, execution layer consensus, beacon chain finality, and eventual immutability. We'll explore how transactions get propagated, selected, ordered, executed, and finalized, connecting user-facing actions to deep protocol internals. Using real examples from Uniswap, Flashbots, exchanges, and block explorers, this guide makes the complex transaction lifecycle accessible to everyone. Whether you're a developer debugging failed transactions or a curious user wondering why your swap is "pending," this article demystifies what happens under the hood.

:::info
**What you'll learn:**
- The complete transaction lifecycle (7 stages!)
- How the mempool actually works
- Why some transactions get included faster
- What "pending" really means
- How finality is achieved
- Real examples from Uniswap, Flashbots, and exchanges
- Why transactions sometimes fail
:::

---

## Introduction: The Mystery of "Pending..."

You know that moment when you’re trying to buy an NFT and the screen just says “Transaction Pending…”?

And you're sitting there thinking:
- *Is it working?*
- *Did I lose my money?*
- *Why is this taking so long?*
- *What is even happening right now?!*

Most people assume “pending” simply means the blockchain is busy.
But there’s so much more going on behind the scenes.

Last month, while swapping tokens on Uniswap, I clicked Confirm…
MetaMask said “Pending.”
I waited. And waited.

10 minutes later....still pending.

I checked Etherscan: "Transaction not found."

*Wait, what?!*

A lot of users experience this exact moment… but very few understand why it happens.

So I went down the rabbit hole. I read the specs. I talked to node operators. I studied how Flashbots works. I watched AllCoreDevs calls.

Turns out, there's a **LOT** happening between "Confirm" and "Success."

Let me show you what I learned.

By the end of this article, you'll understand:
- Where transactions go after you send them
- Why some get included immediately and others wait
- What the mempool actually is (it's weirder than you think)
- How validators pick which transactions to include
- When a transaction is *truly* final
- Why transactions fail (and how to avoid it)

Let's dive in! 

---

## The Transaction Lifecycle (Bird's Eye View)

```mermaid
graph TD
    A[Click Confirm in MetaMask] --> B[Wallet signs transaction];
    B --> C[Transaction sent to RPC node];
    C --> D[Transaction enters mempool];
    D --> E[Block builder selects transaction];
    E --> F[Validator proposes block];
    F --> G[Transaction executed];
    G --> H[Block finalized];
    H --> I[NFT appears in your wallet];
```

Looks simple, right? **Each step is actually complex!**

Let's break it down step by step.

---

## Stage 1: Wallet Signs Transaction

**What happens:**
You click "Confirm" in MetaMask (or whatever wallet you use).

**Behind the scenes:**
```javascript
// What your wallet actually does:

const transaction = {
  to: '0x...receiver...',           // Who gets it
  value: '1000000000000000000',     // 1 ETH in wei
  data: '0x...',                     // Function call data
  nonce: 42,                         // Your transaction #42
  gasLimit: 21000,                   // Max gas allowed
  maxFeePerGas: '30000000000',      // 30 gwei
  maxPriorityFeePerGas: '2000000000' // 2 gwei tip
};

// Your wallet signs it with your private key
const signature = wallet.signTransaction(transaction);

// Creates a signed transaction package
const signedTx = {
  ...transaction,
  v: signature.v,  // Recovery ID
  r: signature.r,  // Signature part 1
  s: signature.s   // Signature part 2
};

// This all happens LOCALLY on your computer!
// Your private key never leaves your device!
```

**The Restaurant Analogy:**

You write your order on a piece of paper....“One burger, medium rare, with fries”, and then you sign it so they know it’s really from you. After that, you seal it in an envelope. Now it’s ready to be sent to the kitchen. The moment the envelope leaves your table, the process begins.

**Key Points:**
```yaml
Where this happens:
  Location: Your computer/phone
  Privacy: Your private key stays local
  Time: Instant (milliseconds)

What's created:
  - Signed transaction (can't be modified!)
  - Transaction hash (unique ID)
  - Ready to broadcast

Can you cancel?
  Before broadcast: Yes! Just don't send it
  After broadcast: Too late! It's out there
```

---

## Stage 2: Sent to RPC Node 

**What happens:**
Your wallet sends the signed transaction to an RPC node.

**Behind the scenes:**
```javascript
// Your wallet calls:
await provider.sendTransaction(signedTx);

// This sends it to an RPC endpoint like:
// - Infura: https://mainnet.infura.io/v3/YOUR-KEY
// - Alchemy: https://eth-mainnet.g.alchemy.com/v2/YOUR-KEY
// - Your own node: http://localhost:8545

// The RPC node receives it and responds:
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0xabc123...def" // Transaction hash!
}

// Your wallet shows: "Transaction Pending"
```
**What the RPC node does:**

- Receives your transaction
- Validates basic stuff:
   - Signature correct? ✓
   - Nonce makes sense? ✓
   - Gas fee reasonable? ✓
   - Format valid? ✓
- If valid - Accepts it
   If invalid - Rejects immediately
- Returns transaction hash to you
- Adds it to its local mempool
- Starts gossiping to peers

**The Post Office Analogy:**

You hand your sealed letter to the post office. They quickly check a few things, whether there’s a stamp, whether the address is valid, and whether the envelope is properly sealed. If everything looks good, they give you a tracking number, accept the letter, and start processing it for delivery. But if something is wrong, they hand it back and say, “Sorry, this needs more postage,” and nothing moves forward.


**Real Example: MetaMask's Flow**
```yaml
What MetaMask does:

1. You click "Confirm"
   → Signs transaction locally

2. Sends to Infura/Alchemy
   → Default RPC provider

3. Gets transaction hash back
   → 0xabc123...def

4. Shows "Pending" in UI
   → With Etherscan link

5. Polls for confirmation
   → Checks every few seconds
   → Updates when included in block

At this point:
  - Transaction is "in flight"
  - Visible on Etherscan (pending)
  - But NOT in a block yet!
  - NOT executed yet!
```

---

## Stage 3: The Mempool (The Waiting Room)

**What is the mempool?**

This is where it gets weird... **The mempool isn't a thing. It's thousands of things!**

Most people imagine the mempool as one big public waiting room where all pending transactions line up. But that’s not how it works at all. Every single node on the network keeps its own mempool, its own local list of transactions it has seen. Nodes talk to each other and gossip transactions around, but they don’t all receive the same ones at the same time. So two nodes might share many transactions, but their mempools will never be perfectly identical.

This is why your transaction might show up on one block explorer but not another, they’re looking at different nodes with different mempools.

```
Common misconception:
"There's ONE mempool where all transactions wait"

Reality:
Every node has its OWN mempool!

Node 1's mempool: [tx1, tx2, tx5, tx9]
Node 2's mempool: [tx1, tx3, tx5, tx8]
Node 3's mempool: [tx2, tx4, tx5, tx9]

Different nodes see different transactions!
```

**How transactions spread (gossip protocol):**
```
You send tx to RPC node:
[RPC Node] receives your tx

RPC node gossips to its peers:
[RPC Node] → [Node A]
           → [Node B]  
           → [Node C]

Those nodes gossip to THEIR peers:
[Node A] → [Node D], [Node E]
[Node B] → [Node F], [Node G]
[Node C] → [Node H], [Node I]

Eventually, most nodes have your tx!

This takes ~1-3 seconds for full propagation
```
**The School Gossip Analogy:**

Imagine you tell a secret to three friends. Each of those friends shares it with three of their friends, and those friends pass it along to even more people. Soon, the whole school knows the secret, but not perfectly. Some people hear it late, some hear a slightly different version, and some hear it from multiple sources at once. It takes time for the information to spread everywhere. 

The mempool works the same way: every node hears about transactions at different times, from different peers, and sometimes not at all. It’s a gossip network, not a single global inbox.


**Real Example: Etherscan's Pending Transactions**

When you look at [Etherscan's pending transactions page](https://etherscan.io/txsPending), you're seeing:
```yaml
What Etherscan shows:
  - Transactions in THEIR node's mempool
  - NOT all transactions on the network
  - Just what they've heard about

Why your tx might not appear:
  - Their node hasn't received it yet
  - Gas price too low (they filter it out)
  - Network propagation delay
  - RPC node issues

If it's there:
  - Status: "Pending"
  - Shows gas price, nonce, from/to
  - Updates when included in block
```

**What lives in the mempool:**

```javascript
// Thousands of transactions, waiting:

Mempool contains:
- Your swap: 0xabc...
- Someone's NFT mint: 0xdef...
- A bot's arbitrage: 0x123...
- DeFi liquidation: 0x456...
- Hundreds of other txs...
- All competing to get included!

Sorted by:
- Gas price (higher = more attractive)
- Nonce (must be in order per account)
- Time received (sometimes)
```

**Mempool Rules:**

Transactions can be:

1. Accepted:
   - Valid signature 
   - Sufficient gas 
   - Nonce correct
   - Not a duplicate

2. Rejected:
   - Gas price too low (below minimum)
   - Nonce wrong (already used or too far ahead)
   - Invalid signature
   - Insufficient balance for gas

3. Replaced:
   - You send NEW tx with same nonce
   - But higher gas price
   - Old tx gets dropped, new one replaces it
   - This is how "speed up" works!

4. Dropped:
   - In mempool too long (hours/days)
   - Gas price way too low
   - Mempool full, lower priority txs get kicked

**Real Example: MetaMask's "Speed Up" Feature**

How "Speed Up" works:

-  Your transaction is pending (low gas)
   Nonce: 42
   Gas: 20 gwei
- You click "Speed Up (fast)" in MetaMask
- MetaMask creates NEW transaction:
   Same nonce: 42 (replaces old one!)
   Higher gas: 40 gwei
   Everything else same
- Sends to network
-  Nodes see:
   "Oh, new tx with nonce 42 and higher gas"
   "Drop the old one, keep this new one"
- New tx more likely to be picked!

Result: Old tx disappears, new one included

---

## Stage 4: Block Builder Selection

**What happens:**
Block builders pick transactions from their mempool to build a block.

**Who are block builders?**

Post-PBS (Proposer-Builder Separation), professional entities build blocks:

- Major block builders:
  - Flashbots (~40% of blocks)
  - Titan Builder (~15%)
  - Beaverbuild (~10%)
  - rsync Builder (~8%)
  - Others (~27%)

- What they do:
  - Monitor mempool constantly
  - Select profitable transactions
  - Order them optimally (MEV!)
  - Build complete blocks
  - Submit to relays

**How they select transactions:**
```javascript
// Simplified builder logic:

function buildBlock(mempool, gasLimit = 30_000_000) {
  let block = [];
  let gasUsed = 0;
  
  // Sort by effective gas price (descending)
  let sorted = mempool.sort((a, b) => 
    b.effectiveGasPrice - a.effectiveGasPrice
  );
  
  for (let tx of sorted) {
    // Can it fit?
    if (gasUsed + tx.gasLimit > gasLimit) continue;
    
    // Is nonce correct?
    if (!isNonceValid(tx)) continue;
    
    // Will it revert? (simulate first!)
    if (willRevert(tx)) continue;
    
    // Add to block!
    block.push(tx);
    gasUsed += tx.gasLimit;
    
    // Block full?
    if (gasUsed >= gasLimit * 0.95) break;
  }
  
  return block;
}
```

**The Restaurant Kitchen Analogy:**

Think of the mempool as a pile of order tickets in a busy restaurant. The head chef, acting like a block builder, goes through the tickets carefully. First, they sort the orders by tip size: “$20 tip! Priority!”, “$5 tip, okay…”, “No tip? Maybe later…”. 

Next, they check whether the order makes sense: “Burger with no bun? Skip it, it would fail.” Then they consider the kitchen’s capacity: “We can handle 50 dishes this round, so pick the most profitable ones!” After that, the chef builds the batch, taking the highest-paying orders that fit the available slots to maximize profit. 

Finally, the completed batch is sent to the dining room, just like a block being proposed to the network.

**MEV and Transaction Ordering:**

This is where it gets spicy!

Builders don't just pick randomly:

They look for MEV opportunities:
  - Sandwich attacks (front-run + back-run user swaps)
  - Arbitrage (price differences across DEXs)
  - Liquidations (DeFi positions to close)

Your transaction might be:
  - Included normally (if no MEV)
  - Sandwiched (if it's a big swap!)
  - Front-run (if it's profitable to copy)
  - Back-run (if it creates an opportunity)

Real example: check this block [#20123456](https://etherscan.io/block/20123456)

Block #20123456 had:
- Tx 1: Bot front-run (buys token)
- Tx 2: User swap (drives price up)
- Tx 3: Bot back-run (sells token)
- Bot made $2,000, user paid more!

This is why Flashbots Protect exists!

**Real Example: Flashbots Protect**

[Flashbots Protect](https://protect.flashbots.net/) helps you avoid MEV: How Flashbots Protect works: 

```yaml
Normal route:
You → RPC Node → Public Mempool → MEV bots see it! → Sandwiched

Flashbots Protect route:
You → Flashbots RPC → Private pool → Directly to builder → Safe!

Benefits:
  1. Your tx NOT in public mempool
  2. Bots can't see it
  3. Can't be front-run
  4. If tx would revert, you pay NO gas!

Trade-off:
  1. Slightly slower (might take extra block)
  2. But safer and potentially cheaper

Use it for:
  1. Large swaps
  2. NFT mints (competitive)
  3. Any tx you want private
```

**Simulation Before Inclusion:**
```javascript
// Builders simulate transactions first:

const result = simulateTransaction(tx);

if (result.success) {
  // Will execute successfully!
  block.add(tx);
} else {
  // Would revert! Don't include.
  // (Reverting txs still cost gas!)
  skip(tx);
}
```

This is why some txs sit "pending" forever:
- They would revert
- Builders skip them
- They never get included
- Eventually drop from mempool

Common revert reasons:
- Slippage too high (price moved)
- Insufficient allowance
- Token balance changed
- Deadline passed

---

## Stage 5: Validator Proposes Block

**What happens:**
A validator receives the built block and proposes it to the network.

**How PBS works:** You can check [my article](https://hackmd.io/@dicethedev/r1PS8W2ebx) where I explain how PBS works better.

Block Builder:
1. Builds block with selected txs
2. Submits to relay (Flashbots, etc.)
3. Offers payment to validator

Validator:
1. Picks highest-paying block
2. Signs and proposes it
3. Broadcasts to network
4. Collects payment from builder

Validator doesn't see transaction contents! They just pick the block that pays them most. It happens every 12 seconds!

**The Concert Analogy:**

Think of the block builder as a band and the validator as the venue owner. The band prepares the concert, they select the songs (transactions), order the setlist to optimize the experience, and offer payment to the venue. The venue owner then looks at offers from multiple bands, chooses the one paying the most, hosts the concert, and collects the payment. 

The venue doesn’t care about which songs are played; it only cares about maximizing profit. Similarly, block builders arrange transactions to maximize fees, while validators choose the most profitable blocks to include.

**Real Example: MEV-Boost**

[MEV-Boost](https://boost.flashbots.net/) is the software validators use: How MEV-Boost works:

1. Validator runs MEV-Boost client
   Connects to multiple relays:
   - Flashbots relay
   - bloXroute relay
   - Other relays

2. Each relay submits blocks from builders:
   "I have a block worth 0.05 ETH"
   "I have a block worth 0.08 ETH"
   "I have a block worth 0.12 ETH"

3. MEV-Boost picks highest bid:
   0.12 ETH block wins!

4. Validator signs and proposes it
   Gets 0.12 ETH payment

5. Block broadcast to network


Stats:
  - ~90% of validators use MEV-Boost
  - Increases validator rewards by 30-60%
  - Makes staking more profitable

**Attestations and Consensus:**

After validator proposes:

Other validators (attesters) check:
1. Did validator propose in their assigned slot?
2. Is the block valid (gas limit, signatures, etc.)?
3. Does it build on correct parent block?

If 2/3+ validators attest "yes":
→ Block is accepted!
→ Added to canonical chain
→ Your transaction is now "confirmed"

If not enough attestations:
→ Block orphaned (discarded)
→ Your tx back to mempool
→ Try again next slot

This happens every 12 seconds!

---

## Stage 6: Transaction Execution

**What happens:**
The EVM (Ethereum Virtual Machine) executes your transaction and updates state.

**Execution Process:**
```javascript
// What the EVM does with your transaction:

1. Load your account state:
   balance = getBalance(yourAddress);
   nonce = getNonce(yourAddress);

2. Validate:
   - Is balance >= (value + gasLimit * gasPrice)? ✓
   - Is nonce correct? ✓
   - Is signature valid? ✓

3. Deduct max gas fee upfront:
   balance -= (gasLimit * maxFeePerGas);

4. Execute transaction:
   if (tx.to.isContract()) {
     // Call contract code
     result = executeContract(tx.data);
   } else {
     // Simple transfer
     result = transfer(tx.value);
   }

5. Calculate actual gas used:
   gasUsed = computeGasUsed(result);
   
6. Refund unused gas:
   refund = (gasLimit - gasUsed) * maxFeePerGas;
   balance += refund;

7. Pay validator (priority fee):
   validatorPayment = gasUsed * maxPriorityFeePerGas;
   
8. Burn base fee:
   burned = gasUsed * baseFeePerGas;
   // This ETH is destroyed! 

9. Update state:
   setBalance(yourAddress, newBalance);
   setNonce(yourAddress, nonce + 1);
   // ... other state changes ...

10. Generate receipt:
    {
      status: 1, // Success!
      gasUsed: 150000,
      logs: [...],
      // ... more data ...
    }
```

**The Vending Machine Analogy:**

Imagine putting $2 into a vending machine and selecting chips that cost $1.50. The machine first checks that you have enough money, then processes your selection and dispenses the chips. It refunds the $0.50 you didn’t need, keeps $0.30 for the owner as a priority fee, and burns $1.20 as the base fee. Just like that, your chips appear and the transaction is complete! 
This is a simple way to understand how gas fees, refunds, and base fees work in a blockchain transaction.

**Real Example: Uniswap Swap Transaction**

Let's look at a real Uniswap swap on Etherscan: Check block [#21045123](https://etherscan.io/block/21045123) 

```yaml
Transaction: 0xabc123... (this not real address)
Block: 21045123
Position in block: 42

From: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
To: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D (Uniswap V2 Router)
Value: 0 ETH
Function: swapExactTokensForTokens(...)
  
Gas limit: 180,000
Gas used: 156,234 (87% of limit)
Gas price: 27 gwei (25 base + 2 priority)
  
Cost breakdown:
- Maximum cost: 180,000 × 27 = 4,860,000 gwei = 0.00486 ETH
- Actual cost: 156,234 × 27 = 4,218,318 gwei = 0.00421 ETH
- Refunded: (180,000 - 156,234) × 27 = 641,682 gwei
  
- Base fee burned: 156,234 × 25 = 3,905,850 gwei
- Priority fee to validator: 156,234 × 2 = 312,468 gwei
  
Result:
- Status: Success ✓
- Swapped 1,000 USDC → 0.4156 ETH
- 3 events emitted (Transfer, Sync, Swap)
- State updated (balances changed)
```

**Success vs Failure:**

- Success (status: 1):
  - Your transaction executed completely
  - State updated (balances changed, etc.)
  - Receipt generated with logs
  - You get your tokens/NFT/whatever
  - Gas was consumed

- Failure (status: 0):
  - Transaction reverted (something went wrong)
  - State NOT changed (rolled back!)
  - But gas still consumed!
  - Reason in receipt (if provided)
  
- Common failure reasons:
  - "Slippage exceeded" (price moved too much)
  - "Insufficient allowance" (forgot to approve)
  - "Transfer amount exceeds balance"
  - Custom error from contract

---

## Stage 7: Finality (The Point of No Return)

**What is finality?** 

Finality means that a transaction can never be reverted. It’s not enough for it to be “confirmed” or just included in a block, once it reaches finality, it’s impossible to undo. 

On most blockchains, reaching this level of certainty takes about 12–15 minutes.

**How Ethereum achieves finality:**

Ethereum uses Casper FFG (Finality Gadget):

- Every 32 slots = 1 epoch (~6.4 minutes)

- Epoch structure:
  - Slot 0 → Block proposed
  - Slot 1 → Block proposed
  - …
  - Slot 31 → Block proposed
- After 2 epochs:
  - Source epoch (older)
  - Target epoch (newer)
- Validator voting:
  - If 2/3+ of validators vote for both epochs:
    - Source epoch = FINALIZED
    - All blocks in that epoch become immutable
    - Economic guarantee: reverting them would cost billions

**The Checkpoint System:**

- Think of epochs as checkpoints:
  - Epoch 100 (32 blocks)
  - Epoch 101 (32 blocks) ← currently building
  - Epoch 102 (started)

- Validators vote:
  - "I attest that epoch 100 is correct"
  - "I attest that it builds on epoch 99"

- When 2/3+ agree:
  - Epoch 100 = FINALIZED
  - Can never be changed
  - Even if ALL validators collude!
- Why it’s secure:
  - Changing finalized blocks requires burning 1/3 of all staked ETH
  - That’s around $40 BILLION at current prices
  - Practically, nobody would attempt that

**The Concrete Analogy:**

When a block is first proposed, think of it like wet concrete, it’s still malleable and could be changed. After one epoch (about 6.4 minutes), the concrete starts hardening; it’s becoming more difficult to change, though technically possible. 

After two epochs (roughly 12.8 minutes), the concrete is fully hardened, changing it would be nearly impossible, like trying to break it with a jackhammer. At this point, your transaction is truly set in stone.

**Real Example: Coinbase Deposit Confirmations**

When you deposit ETH to Coinbase:
```yaml
Coinbase's confirmation policy:

Deposit initiated:
  Status: "Pending"
  Confirmations: 0
  Can withdraw: No

After 12 confirmations (~2.4 minutes):
  Status: "Confirming..."
  Confirmations: 12
  Can withdraw: No

After 35 confirmations (~7 minutes):
  Status: "Complete"
  Confirmations: 35+
  Can withdraw: Yes!

Why 35?
  - Safely past one epoch
  - Low reorg risk
  - Balance between speed and security
  
For large amounts (>$10k):
  - Some exchanges wait 64 confirmations
  - Full finality guarantee
  - ~12-15 minutes
```

**Confirmation Levels:**
```yaml
0 confirmations:
  Status: In mempool
  Safety: Can be replaced or dropped
  Time: Variable (seconds to hours)

1 confirmation:
  Status: In latest block
  Safety: Likely safe, small reorg risk
  Time: ~12 seconds

6 confirmations:
  Status: In block, 5 more built on top
  Safety: Very safe, reorg unlikely
  Time: ~72 seconds (6 × 12)

32 confirmations (1 epoch):
  Status: One epoch deep
  Safety: Extremely safe
  Time: ~6.4 minutes

64 confirmations (2 epochs):
  Status: FINALIZED
  Safety: Cryptoeconomically guaranteed
  Time: ~12.8 minutes
  
Final: IRREVERSIBLE!
```

**Real Example: Bridge Security**

[Arbitrum Bridge](https://bridge.arbitrum.io/) waits for finality:

How Arbitrum handles L1 → L2 deposits:
```yaml
1. You deposit ETH on Ethereum L1
   Block: 21045123
   
2. Bridge detects transaction
   Status: "Pending confirmation"
   
3. Waits for finality (64+ confirmations)
   Time: ~12-15 minutes
   Why: Prevent reorg attacks
   
4. After finality reached:
   Status: "Processing"
   Bridge mints ETH on Arbitrum L2
   
5. ETH appears in your Arbitrum wallet!
   Total time: ~15-20 minutes

Why wait so long?
  - If L1 reorged before finality
  - Your deposit could vanish!
  - But L2 already credited you
  - Bridge would lose money
  
Solution: Wait for finality
  - Guaranteed L1 won't reorg
  - Safe to credit on L2
```

**Why Finality Matters:**

- Without finality:
  - Exchanges need to wait longer
  - Double-spend attacks possible
  - No settlement guarantee
  - Reorgs can undo transactions

- With finality:
  - Exchanges can credit funds safely
  - No double-spend risk
  - Settlement guaranteed
  - Reorg impossible
  
- Real-world impact:
  - CEXs typically wait 6-35 confirmations
  - DeFi protocols treat 1 confirmation as "done"
  - Bridges wait for finality (12-15 min)
  - Payment processors wait 6+ confirmations

---

## Why Transactions Fail (And How to Avoid It) 

Let me share the most common failure reasons and how projects handle them:

### Failure Reason #1: Slippage Too High

What happened:
```yaml
  You tried to swap 1000 USDC → ETH
  Expected: 0.42 ETH
  Actual: 0.38 ETH (price moved!)
  Slippage: 9.5% (you set 5% max)
  Result: Transaction reverted
```
Why:
  - Price moved between signing and execution
  - Someone else's trade moved the pool
  - Your slippage tolerance was too tight

How Uniswap handles this:
  - Default slippage: 0.5% (very tight)
  - Warns you if setting too high
  - Shows price impact before confirming
  - Auto-adjusts for volatile pairs

Fix:
  - Increase slippage tolerance (1-3% for stablecoins, 5-15% for volatile)
  - Use limit orders (Uniswap X, CoW Swap)
  - Split large trades
  - Trade during low activity times

### Failure Reason #2: Insufficient Allowance

What happened:
```yaml
  You tried to swap tokens on Uniswap
  But forgot to approve first!
  ```
  
Error: "ERC20: transfer amount exceeds allowance"

Why:
  - Contracts need approval to spend your tokens
  - First time using a token? Must approve

How dApps handle this:
  - Modern dApps (1inch, Uniswap): Show approve button first
  - Some show gas estimate for approve + swap
  - Permit2 (newer): Approve once, works everywhere!
  
Fix:
  - Always check for approve step
  - Approve "infinite" to avoid re-approving
  - Or use exact amounts for security

### Failure Reason #3: Gas Limit Too Low

What happened:

```yaml
  You set gas limit: 50,000
  Actual needed: 75,000
  Result: Out of gas!
```

Why:
  - You manually set gas too low
  - Or used old estimate
  - Or contract logic changed

How wallets handle this:
  - MetaMask: Auto-estimates gas
  - Rainbow: Adds 20% buffer automatically
  - Rabby: Shows "suggested" vs "custom"
  
Fix:
  - Use wallet's estimate
  - Don't manually lower gas limit
  - If you must: add 30% buffer minimum

### Failure Reason #4: Nonce Issues

What happened:

```yaml
  Transaction stuck with nonce 42
  You sent new tx with nonce 43
  Nonce 43 won't execute until 42 does!
```

Why:
  - Transactions must execute in order
  - Can't skip nonces

How wallets help:
  - MetaMask "Speed Up": Replaces stuck tx
  - "Cancel": Sends 0 ETH to yourself with same nonce
  - Shows pending tx count
  
Fix:
  - Speed up stuck tx (higher gas, same nonce)
  - Or wait for it to drop from mempool
  - Then resend with correct nonce

### Failure Reason #5: Deadline Passed

What happened:

```yaml
  You signed transaction at 10:00 AM
  Set deadline: 10:05 AM
  Transaction executed at 10:06 AM
  Result: Reverted (deadline exceeded!)
```
Why:
  - Common in DEX transactions
  - Protects you from stale prices
  - But can cause failures if pending too long

How Uniswap handles this:
  - Default deadline: 30 minutes
  - Customizable in settings
  - Shown as "Transaction deadline"
  
Fix:
  - Set longer deadlines (30-60 minutes)
  - Or use higher gas to get included faster
  - Check settings in your DEX

---

## Real-World Tools That Use This Knowledge

### 1. **Etherscan**

What Etherscan shows:

Pending Transactions:
  - Transactions in their node's mempool
  - Gas price, nonce, from/to
  - Age (how long pending)
  
Confirmed Transactions:
  - Block number
  - Position in block
  - Gas used vs limit
  - Success/failure status
  - State changes (token transfers)
  
Block Details:
  - All transactions in block
  - Builder info
  - Gas usage
  - Base fee + priority fees
  
How they get this data:
  - Run full Ethereum node
  - Monitor mempool
  - Index all blocks
  - Parse transaction receipts

### 2. **MetaMask Activity Tab**

What MetaMask shows:

Transaction States:
  - "Pending" → In mempool or waiting
  - "Confirmed" → In block (1+ confirmations)
  - "Failed" → Reverted (with error if available)
  - "Dropped" → Removed from mempool
  
Actions Available:
  - "Speed Up" → Replace with higher gas
  - "Cancel" → Send 0 ETH to self (same nonce)
  - "View on Etherscan" → See full details
  
Gas Tracking:
  - Shows max fee you set
  - Updates with actual cost once confirmed
  - Refunds unused gas automatically

### 3. **1inch Fusion Mode**

How 1inch handles transactions:

Normal Mode:
  - You sign transaction
  - Send to mempool
  - Can be sandwich attacked
  
Fusion Mode (MEV protection):
  - You sign an "order" (not transaction!)
  - 1inch "resolvers" compete for your order
  - They submit transaction on your behalf
  - You're protected from MEV
  - If order fails, you pay NOTHING!
  
Benefits:
  - No gas if it fails
  - MEV protection
  - Better prices
  
Trade-off:
  - Slightly slower (by ~12-24 seconds)

### 4. **Gnosis Safe (Multisig)**

How Gnosis Safe handles transactions:

Multi-step process:
- Someone proposes transaction
   → Creates proposal (not submitted yet)
- Other signers approve
   → Sign off-chain (no gas!) 
- Once threshold reached:
   → Last signer submits to chain
   → Pays gas for everyone
- Safe contract executes:
   → Verifies all signatures
   → Executes transaction
   → All or nothing!

Why this matters:
  - Only ONE on-chain transaction
  - Other approvals free (signatures only)
  - Transaction can batch multiple operations
  - Nonce managed by Safe contract


### 5. **CoW Swap (Batch Auctions)**

How CoW Swap works differently:

Traditional DEX:
  Each swap = separate transaction
  Goes to mempool individually
  Can be front-run
  
CoW Swap:
  - You sign an "intent" (not transaction)
  - Intent sits off-chain
  - Solver batches many intents together
  - Finds optimal execution
  - Submits ONE transaction for all
  
Benefits:
  - Better prices (CoW = Coincidence of Wants)
  - MEV protection (off-chain intents)
  - Gas savings (one tx for many swaps)
  
Example batch:
  Alice: swap USDC → ETH
  Bob: swap ETH → USDC
  → Match directly! No DEX needed!
  → Save on gas and slippage
  
  ---
  
## Key Takeaways

Let me summarize the complete transaction lifecycle:

### The 7 Stages

1. Wallet Signs (Instant):
   - Happens locally
   - Private key never leaves device
   - Creates transaction hash

2. Sent to RPC (1 second):
   - Infura, Alchemy, etc.
   - Validated and accepted
   - Returned transaction hash

3. Mempool (1-3 seconds):
   - Gossip across network
   - Every node has own mempool
   - Competitive environment

4. Builder Selection (0-12 seconds):
   - Professional builders scan mempool
   - Select profitable transactions
   - Order for MEV extraction
   - Simulate before inclusion

5. Validator Proposes (12 seconds):
   - Pick highest-paying block
   - Sign and broadcast
   - Network validates

6. Execution (Instant):
   - EVM processes transaction
   - State updates
   - Gas consumed
   - Receipt generated

7. Finality (12-15 minutes):
   - 2 epochs pass
   - 2/3+ validators attest
   - Cryptoeconomically guaranteed
   - Irreversible!

### Time Expectations

Optimistic timeline:
  - Mempool → Block: 12 seconds
  - 1 confirmation: 12 seconds
  - Safe (6 confirmations): 72 seconds
  - Finalized: 12-15 minutes

Realistic timeline:
  - Low gas: Minutes to hours
  - Normal gas: 12-60 seconds
  - High gas: 12-24 seconds
  - Finality: Always 12-15 minutes

Worst case:
  - Transaction dropped
  - Never included
  - Must resend with higher gas

### Cost Breakdown

Where your gas fee goes:

**Total Fee = Base Fee + Priority Fee**

Base Fee (majority):
  - Algorithmically determined
  - Based on network congestion
  - BURNED (destroyed forever!)
  - Benefits all ETH holders

Priority Fee (tip):
  - You choose amount
  - Goes to validator
  - Incentivizes inclusion

```yaml
Example (156,234 gas used):
  Base: 25 gwei → 3.9 million gwei → 0.0039 ETH → BURNED
  Priority: 2 gwei → 312k gwei → 0.000312 ETH → To validator
  Total: 0.004212 ETH (~$10 at $2400/ETH)
```

### When Is It "Final"?

Different standards:

DeFi protocols:
  - Usually treat 1 confirmation as final
  - High risk, high speed
  - Can handle occasional reorgs

DEXs (Uniswap, etc.):
  - Instant after 1 confirmation
  - Your tokens appear immediately
  - Trust the economic security

CEXs (Coinbase, Binance):
  - Wait 6-35 confirmations
  - Balance speed vs security
  - Large amounts: more confirmations

Bridges (Arbitrum, Optimism):
  - Wait for full finality (64 confirmations)
  - Can't risk reorgs
  - Security critical

True finality:
  - 64+ confirmations
  - 2 epochs complete
  - Cryptoeconomically guaranteed
  - Impossible to undo


---

## Conclusion: You Now Understand Transactions!

Remember that swap that got stuck "pending" for 10 minutes?

Now you know what was happening:
- Your transaction was gossiping through mempools
- Your gas price was too low to compete
- Builders were skipping it for higher-paying transactions
- Eventually it got included when congestion cleared
- Then took 12-15 minutes to finalize

**The next time you see "Pending":**
- Don't panic!
- Check Etherscan (is it in their mempool?)
- Compare your gas to current prices
- Use "Speed Up" if needed
- Understand it's not broken - it's just waiting its turn

**When building dApps:**
- Estimate gas properly (add 20-30% buffer)
- Set reasonable deadlines (30+ minutes for DEXs)
- Simulate transactions before sending
- Consider using Flashbots Protect for MEV protection
- Handle all transaction states (pending, success, failed)

**When debugging:**
- Check nonce ordering
- Verify slippage settings
- Confirm token allowances
- Look at gas limits
- Read the revert reason

The Ethereum transaction lifecycle is complex, but it's also **incredibly well-designed**.

Every step has a purpose:
- Signing keeps your keys safe
- Mempool enables competition and decentralization
- PBS separates concerns and maximizes validator rewards
- Execution ensures deterministic state changes
- Finality provides irreversible settlement

It's not perfect. Gas can be expensive. Transactions can fail. MEV exists.

But **it works**. At scale. Globally. 24/7. Without central control.

That's pretty amazing.

**Want to learn more?**

Check out:
- [Etherscan](https://etherscan.io) - Watch transactions live
- [Flashbots Docs](https://docs.flashbots.net) - Learn about MEV and PBS
- [Ethereum.org](https://ethereum.org/en/developers/docs/transactions/) - Official transaction docs
- [Beaconcha.in](https://beaconcha.in) - Monitor validators and finality
- [MEV-Boost Dashboard](https://boost.flashbots.net) - See block building stats

**Next time you click "Confirm":**

You'll know exactly what happens. From your wallet through the mempool, into a block, executed by the EVM, and finalized by the beacon chain.

**You're no longer in the dark.**

Welcome to understanding Ethereum!

---

###### tags: `ethereum` `transactions` `mempool` `finality` `consensus` `block-building` `evm` `gas`