Ethereum Transaction Receipts Explained: Status, Gas, Logs, and Proofs
Learn how Ethereum transaction receipts record execution status, gas used, logs, contract creation, typed transactions, and receipt-root commitments.

You send a contract transaction, the wallet changes from “pending” to “confirmed,” and a block explorer displays a green check. What produced that verdict? The answer is an Ethereum transaction receipt: a compact execution record that connects blockchain basics to the status, fee, and event data shown after inclusion. It is useful evidence, but it is not a plain-language guarantee that a trade was fair or a token was genuine.
This guide explains what a receipt records, how eth_getTransactionReceipt exposes it, why gasUsed differs from cumulativeGasUsed, and what a receipt can—and cannot—prove.
What an Ethereum transaction receipt is
Think of a transaction as an order handed to a workshop and the receipt as the job sheet returned after the machines stop. The order says what was requested. The job sheet says whether the top-level job succeeded, how much work it consumed, and which notices the machinery emitted.
That distinction matters. The transaction object carries inputs such as sender, recipient, nonce, value, gas limits, fees, and calldata. The receipt is created only after execution and inclusion in a block. It records the outcome rather than the original intent.
At the protocol level, a legacy receipt contains four core items: status, cumulative gas used, a logs bloom, and logs. The JSON-RPC response adds convenient context such as the transaction hash, block identity, sender, recipient, per-transaction gas use, effective gas price, transaction type, and a created contract address when applicable.
Transaction input vs execution output
These two objects answer different questions:
| Question | Transaction object | Receipt |
|---|---|---|
| What was authorized? | Sender, signature, nonce, value, calldata | No |
| Was it included? | May have no block yet | Block hash and number after inclusion |
| Did top-level execution succeed? | Not known before execution | status |
| How much gas was actually used? | Gas limit and fee caps | gasUsed, effectiveGasPrice |
| What events survived? | No | logs and logsBloom |
| Did it deploy a contract? | to is empty for creation | contractAddress if creation succeeded |
Ethereum calldata tells you what function and arguments were submitted. A receipt tells you how that submitted transaction finished. Neither alone provides every internal call, state difference, or return value.
How to read eth_getTransactionReceipt
The standard JSON-RPC method accepts one transaction hash:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getTransactionReceipt",
"params": ["0xTransactionHash"]
}The result is either a receipt object or null. A null response does not prove permanent failure. The transaction may still be pending, the node may not know it, or the hash may be wrong. Check the network and query a reliable endpoint before drawing a conclusion.
Identity and inclusion fields
transactionHashidentifies the submitted transaction.transactionIndexgives its position inside the block.blockHashandblockNumberidentify the block that currently contains it.fromandtoshow the sender and destination. For contract creation,toisnull.typeidentifies the transaction envelope exposed by the RPC response.
Inclusion is not the same as finality. A recent block can be reorganized, so high-consequence systems should apply a confirmation or finality policy rather than treating the first receipt as irreversible. See blockchain finality for that boundary.
Status and contract creation
For post-Byzantium transactions, status is 0x1 for successful top-level execution and 0x0 for failure. EIP-658 introduced this status code because the REVERT opcode made “used all gas” an unreliable test for failure.
A success status means the top-level EVM execution did not revert. It does not mean every attempted low-level call succeeded: contract code can catch or ignore a failed subcall and still finish successfully. It also does not certify the destination’s identity, the economic value of an asset, or the fairness of a swap.
For a contract-creation transaction, contractAddress reports the created address; otherwise it is null. Verify that code exists at the address on the intended chain before interacting with it.
Gas fields and the actual execution cost
gasUsed is the gas consumed by this transaction after the protocol’s applicable accounting. cumulativeGasUsed is the total gas consumed in the block up to and including this transaction. It is not the cost of this transaction alone.
For ordinary execution gas, a practical fee calculation is:
execution fee paid = gasUsed × effectiveGasPriceeffectiveGasPrice is the actual per-gas price charged under the transaction’s fee rules. It is not necessarily the user’s maximum fee cap. Unused gas from the gas limit is not charged as if it had been consumed.
Blob transactions may also expose blobGasUsed and blobGasPrice. Those fields describe blob-data gas and should be accounted for separately from normal EVM execution gas. Do not estimate a blob transaction’s full cost from gasUsed × effectiveGasPrice alone.
The gas fees guide covers fee caps, base fees, priority fees, and refunds in more detail.
Logs, bloom filters, and what survived execution
The logs array contains event entries produced by execution that survived. Each log identifies an emitting address and includes indexed topics plus ABI-encoded data. If the top-level transaction reverts, its state changes and logs do not survive in the receipt.
logsBloom is a compact probabilistic filter used to skip blocks or receipts that definitely do not contain a requested address or topic. A match is only a candidate because bloom filters can produce false positives. Software must inspect the actual logs to confirm a result.
The existing guide to Ethereum event logs explains event signatures, topic positions, decoding, and reorganization-safe indexing.
Receipts, typed transactions, and the receipts root
Receipts are not merely explorer annotations. Ethereum commits them into a Merkle-Patricia receipts trie, and the block header carries its receipts_root. That commitment lets a verifier check that a particular encoded receipt belongs to a particular block when supplied with the correct trie proof and trusted block header.
EIP-2718 extended transactions and receipts with typed envelopes. A typed receipt begins with the matching transaction type followed by that type’s receipt payload; legacy receipts retain the legacy encoding. The RPC object is a developer-friendly representation, not necessarily the exact byte sequence inserted into the trie.
This difference is important when building proofs. You need the consensus encoding, the transaction’s index in the block, and the trie path—not a JSON object serialized in arbitrary key order. The guide to the Ethereum Merkle Patricia Trie explains how roots and inclusion proofs connect.
What a receipt does not prove
It does not expose a complete execution trace
A receipt does not list every internal call, opcode, storage write, or revert reason. Debug tracing and state-difference tools can reveal more, but their RPC interfaces and availability may vary by client or provider.
Success does not mean the intended business outcome occurred
A contract can return success while producing an unfavorable swap, transferring a malicious look-alike token, or handling a failed subcall according to its own logic. Confirm expected balances, ownership, allowances, and protocol state.
A receipt does not make a block final
Its block hash describes current inclusion. Applications must handle reorganizations and decide how much confirmation is appropriate for the consequence.
Explorer decoding can be wrong
Human-readable labels depend on contract metadata and ABIs. Verify the chain, address, source, and raw fields when the result matters.
Warning
A green receipt status is an execution result, not an endorsement. Never approve another transaction, release goods, or credit funds solely because an explorer displays “Success.”
Practical verification checklist
- Confirm the chain ID and transaction hash
- Check that the receipt is non-null and record its block hash
- Read
statusbefore interpreting logs - Distinguish
gasUsedfromcumulativeGasUsed - Include blob gas when applicable
- Verify emitting and created contract addresses
- Decode logs with the correct ABI and network
- Compare the expected outcome with current contract state or balances
- Apply an explicit confirmation or finality policy
- Use consensus encoding—not arbitrary JSON—when constructing a receipt proof
FAQ
Why is my transaction receipt null?
The transaction may be pending, unknown to that node, submitted on another chain, dropped from a node’s pool, or referenced by an incorrect hash. Verify the network and transaction hash, then check another reliable RPC endpoint if needed.
Can status be successful while a token transfer failed?
Yes. A top-level contract can handle a failed internal call without reverting, or the transaction may execute logic different from what the user expected. Inspect logs and resulting state, not status alone.
Is cumulativeGasUsed my fee?
No. It includes gas used by earlier transactions in the same block. Use this transaction’s gasUsed and effectiveGasPrice, plus blob-gas fields where applicable.
Can I prove a receipt was in a block?
Yes, with the correctly encoded receipt, its trie key based on transaction index, a receipts-trie proof, and a trusted block header containing the matching receipt root. A block explorer’s JSON display alone is not that proof.
Primary sources
- Ethereum Execution APIs: eth_getTransactionReceipt
- Ethereum.org: Transactions
- Ethereum.org: Blocks and the receipts root
- EIP-658: Embedding transaction status code in receipts
- EIP-2718: Typed Transaction Envelope
- Ethereum Execution Specifications: Receipt data structure and encoding
Read the outcome, then verify the consequence
An Ethereum transaction receipt is the network’s compact record of execution outcome: status, gas accounting, logs, and the context needed to locate the result in a block. Read it alongside the original transaction, current state, and finality requirements. This article is educational, not financial advice. Onchain systems and assets can fail or lose value; test cautiously, use only funds you can afford to lose, and do your own research (DYOR).
Keep learning
Ethereum Event Logs Explained: Topics, Data, and eth_getLogs
Learn how Ethereum event logs work, how indexed topics differ from data, how to query eth_getLogs, and what reorgs and decoding can break.

Ethereum Calldata Explained: How to Decode Transaction Input Data
Learn how Ethereum calldata encodes function selectors and arguments, how explorers decode it, and what to verify before signing a contract transaction.

Ethereum Merkle Patricia Trie: How the State Root Proves the Network
Ethereum uses Merkle Patricia tries to commit accounts, contract storage, transactions, and receipts to compact roots. Learn how the structure works.
Explore related topics

Ethereum Glamsterdam Upgrade: ePBS, BALs, and What Is Actually Planned
Ethereum Glamsterdam is expected in Q4 2026. Learn its frozen scope, Sepolia milestone, ePBS, block-level access lists, and remaining uncertainties.
Crypto Address Poisoning: How to Verify Wallet Addresses Before You Send
Crypto address poisoning plants a lookalike address in your transaction history. Learn how it works and follow a safer verification checklist.