eth_getTransactionByHash: Look Up a Transaction

eth_getTransactionByHashRead methodEthereum JSON-RPC

eth_getTransactionByHash returns the transaction a hash refers to, whether it is sitting in the node's mempool or already mined. It tells you what was submitted (sender, recipient, value, calldata, nonce, fee caps) but nothing about what happened when it ran; the outcome lives in eth_getTransactionReceipt.

1 credit
per call on BLAZED.sh
Read
call type
1
parameter
All clients
client support

Try eth_getTransactionByHash

Request as curl
curl -s https://ethereum-rpc.publicnode.com \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getTransactionByHash",
  "params": [
    "0x1433cd18789195b1f14d55426174f0981ae3ee4256e30804a6d7e1fd286fe840"
  ]
}'

Runs the example straight from your browser against the endpoint above. The prefilled URL is a third-party public endpoint, not run by BLAZED.sh.

What eth_getTransactionByHash does

The node looks the hash up in two places: its transaction index for mined transactions, and its mempool for pending ones. A mined transaction comes back with blockHash, blockNumber and transactionIndex populated; a pending one has all three set to null, which is the canonical way to test whether something has landed.

The shape depends on the transaction type. Legacy (type 0x0) transactions carry a single gasPrice. EIP-1559 (0x2) transactions carry maxFeePerGas and maxPriorityFeePerGas; EIP-2930 (0x1) and 1559 both carry an accessList; EIP-4844 (0x3) blob transactions add maxFeePerBlobGas and blobVersionedHashes; EIP-7702 (0x4) transactions add an authorizationList. Signature fields come back as r, s and, for typed transactions, yParity.

One field surprises people: on a mined type-2 transaction, gasPrice is not the cap you signed but the effective price actually charged, base fee plus tip. In the example below the signed maxFeePerGas is 0x7b61b180 while gasPrice reads 0x7a163827, which is the block's base fee of 0x2e0a427 plus the 2 gwei tip. While the same transaction is pending, gasPrice mirrors maxFeePerGas instead.

Parameters

#NameTypeDescription
1transactionHashstring32-byte transaction hash. Works for mined transactions and for transactions currently in this node's mempool.

What it returns

A transaction object, or null when this node has never seen the hash. Fields: hash, nonce, blockHash, blockNumber, transactionIndex, from, to (null for contract creation), value, gas, input, type, chainId, the fee fields for the transaction type, and the signature components.

Note what is absent: there is no status, no gasUsed, no logs and no contract address. A transaction can be present here with a block number and still have reverted on chain; only the receipt tells you that.

Example response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "hash": "0x1433cd18789195b1f14d55426174f0981ae3ee4256e30804a6d7e1fd286fe840",
    "blockHash": "0x7e9ea4877f25847c29ea338043948a8ea43383da1620ace955a20baf667c5ff5",
    "blockNumber": "0x18789ac",
    "transactionIndex": "0x1d",
    "from": "0xdc4239109ce3a991673d29b26d84d487ad2cb19b",
    "to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "value": "0x0",
    "nonce": "0xa",
    "gas": "0x17199",
    "gasPrice": "0x7a163827",
    "maxFeePerGas": "0x7b61b180",
    "maxPriorityFeePerGas": "0x77359400",
    "input": "0xa9059cbb0000000000000000000000008d287fb56176cbfdc29a7b2df6186c7901a45f60000000000000000000000000000000000000000000000000000000001dcd6500",
    "type": "0x2",
    "chainId": "0x1",
    "accessList": []
  }
}

A mined USDC transfer, signature fields trimmed. The calldata decodes as transfer(address,uint256) to 0x8d287fb5... for 0x1dcd6500 raw units, 500 USDC at 6 decimals. gasPrice is the effective price paid, below the signed maxFeePerGas cap.

eth_getTransactionByHash with ethers.js

import { JsonRpcProvider, Interface, formatUnits } from "ethers";

const provider = new JsonRpcProvider("https://ethereum-rpc.publicnode.com");
const hash = "0x1433cd18789195b1f14d55426174f0981ae3ee4256e30804a6d7e1fd286fe840";

const tx = await provider.getTransaction(hash);
if (!tx) throw new Error("this node has never seen that hash");

console.log(tx.blockNumber === null ? "pending" : `mined in ${tx.blockNumber}`);
console.log("max fee:", formatUnits(tx.maxFeePerGas ?? 0n, "gwei"), "gwei");

// decode the calldata with the ABI of whatever it called
const erc20 = new Interface(["function transfer(address to, uint256 amount)"]);
console.log(erc20.parseTransaction({ data: tx.data })?.args);

Gotchas and common errors

null is four different answers

A null result means this node does not know the hash, which covers a transaction that never existed, one that was broadcast elsewhere and has not propagated here yet, one that was dropped or replaced out of the mempool, and one so old that the node has pruned its transaction lookup index. Only the first is a real "not found". When you are tracking your own submission, retry against the node you broadcast from before concluding anything.

Mempool answers are node-local

There is no global mempool. Each node keeps its own pool, shaped by what its peers gossiped to it and by its own eviction rules, so a pending transaction visible on one node can be invisible on another. Transactions sent through private order flow bypass the public pool entirely and appear only once they are mined. Code that sits on its own node sees that node's unfiltered pool rather than whatever a shared gateway chooses to expose.

gasPrice means different things before and after inclusion

For a pending EIP-1559 transaction, gasPrice echoes maxFeePerGas. Once mined it becomes the effective gas price, base fee plus the tip actually paid, which is what the receipt reports as effectiveGasPrice. Comparing the two across the pending and mined states of the same transaction is a common source of confused fee accounting.

Presence in a block does not mean success

A reverted transaction is still included, still charges gas and still appears here with a block number. The status field lives in the receipt, so any pipeline that treats "transaction found in block" as "my action succeeded" will eventually credit a user for a transfer that reverted.

Blob contents are not here

For a type 0x3 transaction you get blobVersionedHashes, not the blobs. The blob data itself is carried by the consensus layer and retained for about 4096 epochs, roughly 18 days, after which only the commitments survive. Fetching blob contents means asking a beacon node, not the execution JSON-RPC.

What eth_getTransactionByHash costs on BLAZED.sh

eth_getTransactionByHash costs 1 credit per call on BLAZED.sh. Responses are small enough that the over-100KB surcharge is only ever a concern for transactions with enormous calldata. The pattern worth thinking about is the polling loop: watching a submission by hammering this method every few hundred milliseconds turns one transaction into hundreds of billable requests. Watching the mempool and new heads over a WebSocket subscription on a co-located node is both cheaper and closer to the source.

See the full credit price list

eth_getTransactionByHash: frequently asked questions

Why does eth_getTransactionByHash return null?

The node has not seen that hash. Either it was never broadcast, it has not propagated to this node yet, it was dropped or replaced out of the mempool, or it is old enough that this node pruned its transaction index. Query the node you submitted through before assuming it is gone.

How do I tell whether a transaction is pending or mined?

Check blockNumber. It is null while the transaction is in the mempool and holds the block number once mined; blockHash and transactionIndex follow the same rule.

What is the difference between eth_getTransactionByHash and eth_getTransactionReceipt?

This method returns what was submitted: sender, recipient, value, calldata, nonce and fee caps. The receipt returns what happened: success or revert, gas used, effective gas price, emitted logs and the created contract address. You usually need both.

Can I see private or MEV transactions before they are mined?

No. Private order flow goes straight to builders and never enters the public mempool, so it appears only once a block containing it is published. What a direct node view gives you is the full public pool without a gateway filtering or sampling it.

How do I decode the input field?

Feed it to the ABI of the contract it called: ethers' Interface.parseTransaction({ data }) returns the function name and arguments. The first four bytes are the selector, so if you do not have the ABI, a selector database is the starting point.

Call eth_getTransactionByHash from the node itself

Deploy your container or script next to a synced Ethereum node. No rate limits, no compute units, sub-10ms local RPC.