Glossary

Transaction Receipt

An EVM data structure returned after transaction execution containing the status, gas used, logs, and emitted events.

Key Takeaways

  • A transaction receipt is the output record that EVM-compatible blockchains produce after executing a transaction. It contains the execution outcome, gas consumed, and any events emitted by smart contracts.
  • Receipts are distinct from transaction objects: the transaction describes what the sender requested, while the receipt describes what the network did with that request, including whether it succeeded or failed.
  • Event logs stored in receipts are the primary mechanism dApps and indexers use to track on-chain activity, from token transfers to governance votes, making receipts essential infrastructure for the entire EVM ecosystem.

What Is a Transaction Receipt?

A transaction receipt is a data structure that Ethereum and other EVM-compatible blockchains generate after a transaction has been included in a block and executed. It serves as proof of execution: a permanent record of what happened when the network processed the transaction. Every mined transaction produces exactly one receipt, regardless of whether the transaction succeeded or reverted.

Think of a transaction as a request and the receipt as the response. When you submit a transaction, you specify the recipient, the value, the calldata, and the gas limit. The receipt tells you what the network did with those inputs: how much gas was actually consumed, whether the execution completed successfully, and what events the contract emitted along the way. The receipt only exists after the transaction is included in a block. Pending transactions have no receipt.

Receipts are stored in a dedicated Merkle Patricia trie whose root hash is committed to the block header. This means any light client can verify a receipt's authenticity using a Merkle proof without downloading the full block.

How It Works

When a validator or miner includes a transaction in a block, the EVM executes the transaction's bytecode and produces a receipt. The receipt is then stored alongside the block data and becomes queryable through the JSON-RPC API via the eth_getTransactionReceipt method.

Core Receipt Fields

A transaction receipt contains the following fields, as defined by the Ethereum protocol and returned by the standard JSON-RPC interface:

FieldTypeDescription
statusInteger1 for success, 0 for failure (revert). Added in the Byzantium hard fork (EIP-658).
transactionHashBytes32Hash of the transaction that produced this receipt.
transactionIndexIntegerPosition of the transaction within the block.
blockHashBytes32Hash of the block containing this transaction.
blockNumberIntegerBlock number where the transaction was included.
fromAddressSender address.
toAddressRecipient address. Null for contract creation transactions.
gasUsedIntegerAmount of gas consumed by this specific transaction.
cumulativeGasUsedIntegerTotal gas used in the block up to and including this transaction.
effectiveGasPriceIntegerActual price per unit of gas paid, accounting for EIP-1559 base fee and priority fee.
contractAddressAddressAddress of the newly created contract, if this was a deployment transaction. Null otherwise.
logsArrayArray of log objects emitted during execution (see below).
logsBloomBytes256A 2048-bit Bloom filter built from the log entries. Enables efficient filtering by light clients and indexers.
typeIntegerTransaction type (0 for legacy, 1 for EIP-2930 access list, 2 for EIP-1559, 3 for EIP-4844 blob transactions).

Event Logs

The logs array is the most important part of the receipt for application developers. Each log entry represents an event emitted by a smart contract during execution using Solidity's emit keyword. A single transaction can produce zero, one, or many log entries across multiple contracts.

Each log object contains:

  • address: the contract that emitted the event
  • topics: an array of up to 4 indexed values. The first topic is typically the keccak256 hash of the event signature (e.g., Transfer(address,address,uint256)). Remaining topics hold indexed parameters for efficient filtering.
  • data: ABI-encoded non-indexed parameters. These are cheaper to store than indexed topics but cannot be searched directly on-chain.
  • logIndex: position of this log within the block's full log list

Querying Receipts

Applications retrieve receipts through the eth_getTransactionReceipt JSON-RPC method. The method accepts a transaction hash and returns the full receipt object, or null if the transaction is still pending or unknown:

// Request
{
  "jsonrpc": "2.0",
  "method": "eth_getTransactionReceipt",
  "params": ["0xabc123..."],
  "id": 1
}

// Response (simplified)
{
  "status": "0x1",
  "gasUsed": "0x5208",
  "cumulativeGasUsed": "0x33bc",
  "logs": [],
  "contractAddress": null,
  "transactionHash": "0xabc123...",
  "blockNumber": "0x10a2b3c"
}

A null response means the transaction has not been mined yet. Applications typically poll this endpoint or use WebSocket subscriptions to detect when a pending transaction gets included. The presence of a receipt confirms inclusion, but the status field must still be checked to determine success or failure.

Transaction Object vs. Transaction Receipt

A common source of confusion is the difference between the transaction object (returned by eth_getTransactionByHash) and the transaction receipt. They represent two sides of the same coin:

AspectTransaction ObjectTransaction Receipt
RepresentsThe input: what the sender requestedThe output: what the EVM produced
Available whenAs soon as the transaction is broadcast (even while pending)Only after the transaction is mined into a block
Gas infogasLimit: maximum gas the sender is willing to paygasUsed: actual gas consumed during execution
Success/failureNot availablestatus: 1 for success, 0 for revert
EventsNot availablelogs: all events emitted during execution
Contract addressNot availableIncluded for contract creation transactions

A failed (reverted) transaction still produces a receipt. The receipt's status will be 0x0, and the gasUsed field will reflect the gas consumed before the revert. The sender still pays for that gas. This is why transaction simulation is valuable: it catches reverts before you pay for them.

Use Cases

Confirming Transaction Success

The most basic use of a receipt is confirming that a transaction completed successfully. Wallets and dApps check the status field after submission. A status of 0x1 means the transaction executed without reverting. A status of 0x0 means the EVM encountered a revert opcode, and any state changes were rolled back (though gas was still consumed).

Blockchain Indexing

Indexing services like The Graph scan transaction receipts to build queryable databases of on-chain activity. They define handlers that fire whenever specific events appear in receipt logs. For example, an ERC-20 indexer watches for Transfer events to track token movements across accounts:

// Subgraph event handler (AssemblyScript)
export function handleTransfer(event: TransferEvent): void {
  let transfer = new Transfer(
    event.transaction.hash.toHex()
    + "-"
    + event.logIndex.toString()
  );
  transfer.from = event.params.from;
  transfer.to = event.params.to;
  transfer.value = event.params.value;
  transfer.save();
}

Each transfer entity uses the transaction hash combined with the log index as a unique identifier, ensuring every event within a transaction is captured individually. Block explorer APIs rely on similar indexing to display transaction histories, token balances, and contract interactions.

Smart Contract Deployment Verification

When a contract creation transaction is mined, the receipt's contractAddress field contains the address of the newly deployed contract. Deployment scripts use this field to verify the contract was created at the expected address and to proceed with initialization steps like setting permissions or registering the contract with other protocols.

dApp UI Updates

Frontend applications use receipt data to update their interfaces after user actions. When a user swaps tokens on a DEX, the dApp parses the Swap event from the receipt logs to display the exact amounts exchanged and the effective price. Without receipts, the UI would have no reliable way to confirm what happened on-chain.

Gas Cost Analysis

The gasUsed and effectiveGasPrice fields let developers and users calculate the exact cost of a transaction after the fact. This is particularly useful for gas optimization: comparing receipts across different contract implementations reveals which approach consumes less gas.

Comparison with Bitcoin

Bitcoin does not have transaction receipts in the EVM sense. Bitcoin uses the UTXO model, where a transaction consumes existing unspent outputs and creates new ones. There is no concept of "execution status" because Bitcoin Script either validates or it doesn't: invalid transactions are simply rejected by nodes and never included in a block. There is no "failed but included" state.

Bitcoin also lacks event logs. Smart contract platforms on Bitcoin like RGB and Stacks use different mechanisms for tracking contract state changes. On Spark, Bitcoin's Layer 2, transaction confirmation works differently from both the UTXO model and the EVM receipt model, offering instant finality without the complexity of gas accounting.

Network-Specific Extensions

While the core receipt fields are standardized across EVM chains, Layer 2 networks and alternative EVM chains sometimes add extra fields:

  • L2 rollups may include fields like l1Fee and l1GasUsed to report the portion of the transaction cost attributable to posting data on the L1 settlement layer
  • EIP-4844 blob transactions add blobGasUsed and blobGasPrice fields to the receipt
  • Some chains include additional fields for deposit-type transactions or cross-chain messages

These extensions are backward-compatible: applications that only read the standard fields will still work correctly. For a deeper look at how different chains handle transaction processing, see the research on payment finality across blockchains.

Risks and Considerations

Receipt Does Not Mean Finality

A receipt confirms inclusion in a block, not finality. On chains with probabilistic finality (like Ethereum pre-merge), the block containing a transaction could theoretically be reorganized out of the canonical chain. Most applications wait for a certain number of block confirmations before treating a receipt as authoritative.

Failed Transactions Still Cost Gas

A receipt with status: 0x0 means the transaction reverted, but the sender still paid for the gas consumed up to the point of failure. This is by design: validators expend computational resources executing the transaction, and that work must be compensated. Use transaction simulation to estimate whether a transaction will succeed before submitting it on-chain.

Log Data Is Not Contract State

Event logs in receipts are append-only records. They capture what happened during execution, but they are not the same as the contract's current state. A Transfer event tells you a transfer occurred, but to know a wallet's current balance, you need to read the contract's storage directly or aggregate all relevant events.

Node Sync and Indexing Delays

Nodes that are still syncing or indexing may return errors when queried for receipts. A common JSON-RPC error code (-32000) indicates that transaction indexing is still in progress. Applications should handle this gracefully and retry rather than treating it as a permanent failure.

This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.