JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

What's really inside a transaction

Open one transaction and lay every field on the table — recipient, amount, the nonce that orders it, the fee that buys it a slot, and the signature that proves you authorized it — and see why the sender is never even written down.

A signed instruction, not a request

When you tap "send" in a banking app, you are asking the bank to move money. A clerk — or a server the bank fully controls — checks who you are, checks your balance, and updates a private database it owns. A blockchain has no clerk and no one to phone. So a transaction cannot be a polite request to a trusted middleman; it has to be a self-contained, signed instruction that carries everything a complete stranger needs in order to check it — who pays, who is paid, how much, in what order — together with a mathematical proof that the rightful owner authorized it.

In the previous guide you saw the block from the outside: a sealed box of transactions chained to the past. This guide opens one of those transactions and lays every field on the table. By the end you will read a raw transaction the way a node does, and know exactly why each field has to be there.

Opening the envelope: every field at once

Here is a simple transaction — 0.05 ETH moving from one account to another — shown the way a wallet or node would hand it to you. The values are in hexadecimal, the chain's native form; the comments translate them back into plain numbers.

{
  "type": "0x2",                          // EIP-1559 (type-2) transaction
  "chainId": "0x1",                       // 1 = Ethereum mainnet
  "nonce": "0x2a",                        // 42 -> this account's 43rd transaction
  "to": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
  "value": "0xb1a2bc2ec50000",           // 0.05 ETH = 50,000,000,000,000,000 wei
  "maxPriorityFeePerGas": "0x77359400",   // 2 gwei  -> tip to the block proposer
  "maxFeePerGas": "0x6fc23ac00",          // 30 gwei -> the most you'll pay per gas
  "gas": "0x5208",                        // gas limit 21000 (a plain transfer)
  "input": "0x",                          // empty calldata: this moves value, it doesn't call code
  "yParity": "0x1",                       // \
  "r": "0x4f6c4a...e2b7",                 //  > the ECDSA signature (secp256k1), abbreviated
  "s": "0x18a90c...b3d1"                  // /
}
A type-2 (EIP-1559) Ethereum transfer, field by field.

Notice what is there — and what is missing. There is no `from` field. The sender is never written down; it is recovered from the signature, a trick we will get to at the end. Everything else falls into just four jobs: who and how much (`to`, `value`, `input`), ordering (`nonce`), paying the network (the three gas fields), and authorization (`yParity`, `r`, `s`). Let's take them one job at a time.

Who, how much — and the empty data field

`to` is the recipient's 20-byte address — a fingerprint of their public key, from the cryptography rung. `value` is the amount, denominated in wei, the smallest indivisible unit (1 ETH = 10^18 wei). Writing money in whole wei is deliberate: integers have no fractions to round and no floating-point error, so 0.05 ETH is exactly 50,000,000,000,000,000 wei — the integer `0xb1a2bc2ec50000`, no more and no less.

`input` (often called calldata) is `0x` — empty — because this is a plain payment. Had we been calling a smart contract, this field would carry the function selector and its arguments, and the very same transaction shape would do something instead of merely moving something. In fact one format covers three uses, told apart only by `to` and `input`: a `to` with empty data is a transfer; a `to` with data is a function call; a null `to` with data deploys a brand-new contract.

The nonce: order out of chaos (and no replays)

The nonce (here `0x2a` = 42) is a per-account counter: it starts at 0 and increases by exactly one with every transaction the account sends. It looks like a humble bookkeeping number, but it quietly solves two hard problems at once.

  1. Ordering. Thousands of nodes hear about your transactions in different orders over the network. The nonce removes the ambiguity: an account's transaction with nonce 42 may be processed only after 41 and before 43. Broadcast nonce 43 first and it simply waits — the chain refuses to run it out of sequence.
  2. No replays. Once nonce 42 is included, that number is spent forever. A copycat who grabs your exact signed bytes and rebroadcasts them gains nothing: the chain has already consumed nonce 42 for your account and rejects the duplicate. Without a nonce, anyone could replay one of your past payments again and again.

This is also why a transaction can get stuck. If you broadcast nonce 43 but nonce 42 never lands — say you set its fee too low — then 43 sits in limbo behind the gap, valid but unprocessable. Wallets fix this by "speeding up" (re-sending nonce 42 with a higher fee) or "cancelling" (sending a 0-ETH self-transfer at that nonce to fill the slot). Doing this safely is a real discipline of its own: nonce management.

The fee: buying a slot in the next block

Block space is scarce, and asking every node on earth to re-run your transaction and update shared state costs real work. So a transaction must pay to be included. Ethereum meters that work in gas and prices it through three fields. Since EIP-1559, a simple transfer like ours uses them like this:

  1. `gas` (the gas limit, 21000). The maximum units of work you authorize. A plain ETH transfer always costs exactly 21000 gas; a contract call needs more, and each step is metered by gas metering so the work can't run away with your money.
  2. `maxPriorityFeePerGas` (the tip, 2 gwei). A bonus per gas paid straight to the block proposer to make your transaction worth picking — your priority fee.
  3. `maxFeePerGas` (the ceiling, 30 gwei). The most you are ever willing to pay per gas. The network's own base fee floats up and down with demand; you pay `base fee + tip`, capped at this ceiling, and anything below the cap is refunded.
gas used  (a plain ETH transfer)      = 21,000
base fee  (set by the network)        = 18 gwei   -> burned
priority fee / tip (you choose)       =  2 gwei   -> to the block proposer
effective gas price = base + tip      = 20 gwei   (<= maxFeePerGas of 30, so OK)

total fee = 21,000 x 20 gwei = 420,000 gwei = 0.00042 ETH
   of which  burned = 21,000 x 18 = 378,000 gwei = 0.000378 ETH
   and the   tip    = 21,000 x  2 =  42,000 gwei = 0.000042 ETH
Working the fee when the base fee is 18 gwei.

So this transfer costs about 0.00042 ETH. Crucially, the base-fee portion is burned (destroyed, removing ETH from supply) while only the small tip goes to the proposer. Because a block can hold only so much gas (its gas limit), the fee is really an auction: when blocks fill up, proposers rank the waiting transactions by tip, and the cheap ones wait. Bitcoin charges by transaction size in bytes rather than gas, but the principle is identical — you are bidding for scarce space.

The signature: proof that never reveals the secret

The last fields — `yParity`, `r`, `s` — are the digital signature, and they are the heart of the whole thing. From the cryptography rung, recall that an ECDSA signature over the secp256k1 curve lets whoever holds a private key sign a message so that anyone with the matching public key can verify it — while the secret key itself never appears anywhere.

But the wallet does not sign the readable transaction directly. It signs a Keccak-256 hash of all the other fields. That single hash commits to every value at once: change the recipient, the amount, the nonce, or the fee by a single bit and the hash changes, the signature stops verifying, and every honest node throws the transaction away. The signature is precisely what makes a transaction tamper-evident on its long road to a block — no one can alter it in flight without invalidating it.

# 1. Serialize every field EXCEPT the signature (RLP), prefixed by the type byte
payload = 0x02 || rlp([ chainId, nonce, maxPriorityFeePerGas, maxFeePerGas,
                        gas, to, value, input, accessList ])

# 2. Hash that payload down to 32 bytes
sigHash = keccak256(payload)

# 3. Sign the hash with the private key (ECDSA over secp256k1)
(r, s, yParity) = ecdsa_sign(sigHash, privateKey)

# 4. The transaction's id is the hash of the FULL signed transaction
txHash = keccak256(0x02 || rlp([ ...fields, yParity, r, s ]))

# The sender is NEVER written down -- anyone can recover it from the signature:
publicKey = ecrecover(sigHash, yParity, r, s)
from      = address(keccak256(publicKey)[12:])   # last 20 bytes of the key's hash
Sign the hash of the fields, then recover the sender from the signature.

Here is the elegant part that finally explains the missing `from`. Given `(r, s, yParity)` and the signed hash, anyone can run `ecrecover` to recover the public key that produced the signature — and the address is just a hash of that key. So the sender is not stated and trusted; it is derived and proven. There is no identity field to forge and no registry to look anyone up in. The mathematics alone answers the only question that matters: who authorized this? That single guarantee is what lets a transaction travel through a network of strangers and still arrive trustworthy.

After you hit send: into the mempool

A complete, signed transaction is not on the chain yet — it is just a valid message sitting on your device. Your wallet (a non-custodial wallet, if you hold your own keys) broadcasts it to a handful of peers, who relay it to theirs, and theirs again — a gossip flood called transaction propagation — until it reaches the mempool, the waiting room of pending transactions that every node keeps in memory.

There the transaction sits, pending, until a block producer reaches in and picks it — favoring the higher tips, as we saw — and writes it into a block. Only then is it included; what makes an included transaction truly irreversible (*finality*) is a story for a later rung. The full journey — broadcast, the economics of the mempool, and the confirmations that pile up behind a transaction — is the very last guide of this rung.