eth_getTransactionReceipt
Returns the receipt of a transaction by transaction hash. The receipt is available only for mined transactions.
Parameters
- Transaction Hash -
DATA, 32 Bytes
- Hash of a transaction
Returns
Object
- A transaction receipt object, or null
when no receipt was found:
transactionHash
- Hash of the transactiontransactionIndex
- Index position in the blockblockHash
- Hash of the block containing this transactionblockNumber
- Block number containing this transactionfrom
- Address of the senderto
- Address of the receiver (null for contract creation)cumulativeGasUsed
- Total gas used in the block up to this transactiongasUsed
- Gas used by this specific transactioncontractAddress
- Contract address created (if contract creation)logs
- Array of log objects generated by this transactionlogsBloom
- Bloom filter for the logsstatus
-1
(success) or0
(failure)
Request Example
{
"jsonrpc": "2.0",
"method": "eth_getTransactionReceipt",
"params": [
"0xc6ef2fc5426d6ad6fd9e2a26a6b2e2b7e7e5d4f3c8a9b8a7c6d5e4f3b2a1c9d8"
],
"id": 1
}
Implementation Examples
- JavaScript
- Python
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider('https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY');
// Get transaction receipt
async function getReceipt(txHash) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
console.log('Transaction not yet mined');
return null;
}
return {
status: receipt.status === 1 ? 'Success' : 'Failed',
blockNumber: receipt.blockNumber,
gasUsed: receipt.gasUsed.toString(),
effectiveGasPrice: receipt.effectiveGasPrice?.toString(),
logs: receipt.logs.length,
confirmations: receipt.confirmations
};
}
// Wait for receipt with timeout
async function waitForReceipt(txHash, timeout = 60000) {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const receipt = await provider.getTransactionReceipt(txHash);
if (receipt) {
return receipt;
}
// Check every 2 seconds
await new Promise(resolve => setTimeout(resolve, 2000));
}
throw new Error(`Transaction receipt not found after ${timeout}ms`);
}
// Parse receipt logs
async function parseReceiptLogs(txHash, contractABI) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
throw new Error('Receipt not found');
}
const iface = new ethers.Interface(contractABI);
const parsedLogs = [];
for (const log of receipt.logs) {
try {
const parsed = iface.parseLog(log);
parsedLogs.push({
name: parsed.name,
args: parsed.args,
address: log.address,
blockNumber: log.blockNumber
});
} catch (e) {
// Log doesn't match this ABI
}
}
return parsedLogs;
}
// Analyze gas usage
async function analyzeGasUsage(txHash) {
const [receipt, tx, block] = await Promise.all([
provider.getTransactionReceipt(txHash),
provider.getTransaction(txHash),
provider.getBlock('latest')
]);
if (!receipt) {
throw new Error('Receipt not found');
}
const gasPrice = tx.gasPrice || tx.effectiveGasPrice;
const gasUsed = receipt.gasUsed;
const gasLimit = tx.gasLimit;
return {
gasUsed: gasUsed.toString(),
gasLimit: gasLimit.toString(),
gasEfficiency: `${(Number(gasUsed) * 100 / Number(gasLimit)).toFixed(2)}%`,
actualCost: ethers.formatEther(gasUsed * gasPrice),
status: receipt.status === 1 ? 'Success' : 'Failed',
blockGasUsed: block.gasUsed.toString(),
percentOfBlock: `${(Number(gasUsed) * 100 / Number(block.gasUsed)).toFixed(2)}%`
};
}
from web3 import Web3
import time
w3 = Web3(Web3.HTTPProvider('https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY'))
def get_transaction_receipt(tx_hash):
"""Get transaction receipt"""
receipt = w3.eth.get_transaction_receipt(tx_hash)
if receipt is None:
return None
return {
'status': 'Success' if receipt['status'] == 1 else 'Failed',
'block_number': receipt['blockNumber'],
'gas_used': receipt['gasUsed'],
'cumulative_gas_used': receipt['cumulativeGasUsed'],
'logs_count': len(receipt['logs']),
'contract_address': receipt['contractAddress']
}
def wait_for_receipt(tx_hash, timeout=60):
"""Wait for transaction receipt with timeout"""
start_time = time.time()
while time.time() - start_time < timeout:
try:
receipt = w3.eth.get_transaction_receipt(tx_hash)
if receipt:
return receipt
except:
pass
time.sleep(2)
raise TimeoutError(f"Receipt not found after {timeout} seconds")
def parse_receipt_events(tx_hash, contract):
"""Parse events from receipt"""
receipt = w3.eth.get_transaction_receipt(tx_hash)
if not receipt:
raise ValueError("Receipt not found")
# Get all events from the contract
events = []
for log in receipt['logs']:
# Match log to contract events
try:
event = contract.events.parse_log(log)
events.append({
'name': event['event'],
'args': dict(event['args']),
'address': log['address'],
'block': log['blockNumber']
})
except:
# Log doesn't match contract ABI
pass
return events
def analyze_transaction_cost(tx_hash):
"""Analyze transaction costs"""
receipt = w3.eth.get_transaction_receipt(tx_hash)
tx = w3.eth.get_transaction(tx_hash)
if not receipt:
raise ValueError("Receipt not found")
gas_used = receipt['gasUsed']
gas_price = tx.get('gasPrice', tx.get('effectiveGasPrice', 0))
cost_wei = gas_used * gas_price
cost_eth = w3.from_wei(cost_wei, 'ether')
return {
'gas_used': gas_used,
'gas_limit': tx['gas'],
'gas_price_gwei': w3.from_wei(gas_price, 'gwei'),
'cost_eth': cost_eth,
'efficiency': f"{(gas_used * 100 / tx['gas']):.2f}%",
'status': 'Success' if receipt['status'] == 1 else 'Failed'
}
Common Use Cases
1. Contract Deployment Verification
// Verify contract deployment
async function verifyDeployment(txHash) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
return { status: 'Pending' };
}
if (receipt.status === 0) {
return {
status: 'Failed',
reason: 'Deployment transaction reverted'
};
}
if (!receipt.contractAddress) {
return {
status: 'Failed',
reason: 'Not a contract deployment transaction'
};
}
// Verify contract code exists
const code = await provider.getCode(receipt.contractAddress);
if (code === '0x') {
return {
status: 'Failed',
reason: 'No code at contract address'
};
}
return {
status: 'Success',
contractAddress: receipt.contractAddress,
deploymentBlock: receipt.blockNumber,
gasUsed: receipt.gasUsed.toString()
};
}
2. Event Monitoring
// Monitor specific events from receipt
async function getTransferEvents(txHash) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
throw new Error('Receipt not found');
}
// ERC20 Transfer event signature
const transferTopic = ethers.id('Transfer(address,address,uint256)');
const transfers = receipt.logs
.filter(log => log.topics[0] === transferTopic)
.map(log => ({
from: ethers.getAddress('0x' + log.topics[1].slice(26)),
to: ethers.getAddress('0x' + log.topics[2].slice(26)),
value: BigInt(log.data),
token: log.address,
logIndex: log.logIndex
}));
return transfers;
}
3. Transaction Confirmation Status
// Get detailed confirmation status
async function getConfirmationStatus(txHash) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
return {
status: 'Pending',
confirmed: false
};
}
const currentBlock = await provider.getBlockNumber();
const confirmations = currentBlock - receipt.blockNumber;
// Linea zkEVM finality
const zkFinalityBlocks = 12; // ~2.4 minutes at 12s blocks
return {
status: receipt.status === 1 ? 'Success' : 'Failed',
confirmed: true,
confirmations: confirmations,
finalized: confirmations >= zkFinalityBlocks,
blockNumber: receipt.blockNumber,
currentBlock: currentBlock,
gasUsed: receipt.gasUsed.toString(),
effectiveGasPrice: receipt.effectiveGasPrice?.toString()
};
}
zkEVM-Specific Receipt Features
Linea zkEVM receipts have unique characteristics:
// Analyze zkEVM-specific receipt data
async function analyzeZkEvmReceipt(txHash) {
const receipt = await provider.getTransactionReceipt(txHash);
if (!receipt) {
throw new Error('Receipt not found');
}
// Get block for additional zkEVM data
const block = await provider.getBlock(receipt.blockNumber);
// zkEVM-specific analysis
const zkEvmData = {
// Basic receipt data
transactionHash: receipt.transactionHash,
blockNumber: receipt.blockNumber,
status: receipt.status === 1 ? 'Success' : 'Failed',
// Gas analysis for zkEVM
gasUsed: receipt.gasUsed.toString(),
cumulativeGasUsed: receipt.cumulativeGasUsed.toString(),
gasEfficiency: `${(Number(receipt.gasUsed) * 100 / Number(receipt.cumulativeGasUsed)).toFixed(2)}%`,
// zkEVM batch information (if available)
zkBatch: {
timestamp: block.timestamp,
transactionsInBlock: block.transactions.length,
blockGasUsed: block.gasUsed.toString()
},
// Finality status
finality: {
l2Finalized: true, // zkProofs provide instant L2 finality
confirmations: await provider.getBlockNumber() - receipt.blockNumber
}
};
return zkEvmData;
}
Error Handling
// Robust receipt fetching with retry
async function getReceiptWithRetry(txHash, maxRetries = 60) {
for (let i = 0; i < maxRetries; i++) {
try {
const receipt = await provider.getTransactionReceipt(txHash);
if (receipt) {
// Validate receipt structure
if (!receipt.blockNumber || !receipt.transactionHash) {
throw new Error('Invalid receipt structure');
}
return receipt;
}
// Transaction might still be pending
const tx = await provider.getTransaction(txHash);
if (!tx) {
throw new Error('Transaction not found');
}
// Wait before retry (longer wait as attempts increase)
await new Promise(resolve =>
setTimeout(resolve, Math.min(2000 * (i + 1), 10000))
);
} catch (error) {
if (error.message.includes('not found') && i === maxRetries - 1) {
throw new Error(`Transaction ${txHash} not found after ${maxRetries} attempts`);
}
if (i === maxRetries - 1) {
throw error;
}
}
}
return null;
}
Need help? Contact our support team or check the Linea documentation.