eth_getTransactionByHash
Returns the information about a transaction requested by transaction hash on Berachain.
When to Use This Method
eth_getTransactionByHash
is essential for:
- Transaction Tracking - Monitor transaction status and confirmation
- Blockchain Analysis - Analyze transaction patterns and flows
- Wallet Applications - Display transaction history and details
- DeFi Integration - Track token transfers and contract interactions
- Audit and Compliance - Verify transaction details for reporting
Parameters
- Transaction Hash -
DATA
, 32 bytes- The hash of a transaction
- Format:
0x
prefixed, 64 hex characters - Example:
0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d
{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [
"0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d"
],
"id": 1
}
Returns
Transaction Object or null
if no transaction is found:
hash
-DATA
, 32 bytes: Hash of the transactionnonce
-QUANTITY
: Number of transactions sent by the sender prior to this oneblockHash
-DATA
, 32 bytes: Hash of the block containing this transaction (null
if pending)blockNumber
-QUANTITY
: Block number containing this transaction (null
if pending)transactionIndex
-QUANTITY
: Integer position in the block (null
if pending)from
-DATA
, 20 bytes: Address of the senderto
-DATA
, 20 bytes: Address of the receiver (null
for contract creation)value
-QUANTITY
: Value transferred in weigasPrice
-QUANTITY
: Gas price provided by the sender in weigas
-QUANTITY
: Gas limit provided by the senderinput
-DATA
: Data sent along with the transactionv
,r
,s
-QUANTITY
: ECDSA signature valuestype
-QUANTITY
: Transaction type (0x0 for legacy, 0x2 for EIP-1559)maxFeePerGas
-QUANTITY
: Maximum fee per gas (EIP-1559 transactions)maxPriorityFeePerGas
-QUANTITY
: Maximum priority fee per gas (EIP-1559 transactions)accessList
- Array of access list entries (EIP-2930/EIP-1559 transactions)
Implementation Examples
- cURL
- JavaScript
- Python
- Go
# Get transaction details by hash
curl -X POST https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [
"0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d"
],
"id": 1
}'
# Check if transaction exists
curl -X POST https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [
"0xnonexistenthash000000000000000000000000000000000000000000000000"
],
"id": 1
}'
// Using ethers.js
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider('https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY');
async function getTransactionDetails(txHash) {
try {
const tx = await provider.getTransaction(txHash);
if (!tx) {
console.log('Transaction not found');
return null;
}
console.log('Transaction Details:');
console.log('Hash:', tx.hash);
console.log('From:', tx.from);
console.log('To:', tx.to);
console.log('Value:', ethers.formatEther(tx.value), 'BERA');
console.log('Gas Price:', ethers.formatUnits(tx.gasPrice, 'gwei'), 'Gwei');
console.log('Block Number:', tx.blockNumber);
console.log('Status:', tx.blockNumber ? 'Confirmed' : 'Pending');
return tx;
} catch (error) {
console.error('Error fetching transaction:', error);
return null;
}
}
// Using fetch API
async function getTransactionRaw(txHash) {
const response = await fetch('https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'eth_getTransactionByHash',
params: [txHash],
id: 1
})
});
const data = await response.json();
return data.result;
}
// Monitor transaction status
async function waitForTransaction(txHash, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const tx = await provider.getTransaction(txHash);
if (!tx) {
throw new Error('Transaction not found');
}
if (tx.blockNumber) {
console.log(`Transaction confirmed in block ${tx.blockNumber}`);
return tx;
}
console.log(`Attempt ${i + 1}: Transaction still pending...`);
await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
}
throw new Error('Transaction not confirmed within timeout');
}
// Get transaction with receipt
async function getFullTransactionData(txHash) {
const [tx, receipt] = await Promise.all([
provider.getTransaction(txHash),
provider.getTransactionReceipt(txHash).catch(() => null)
]);
return {
transaction: tx,
receipt: receipt,
status: receipt ? (receipt.status ? 'Success' : 'Failed') : 'Pending'
};
}
import requests
import json
import time
from web3 import Web3
def get_transaction_by_hash(tx_hash):
url = 'https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY'
payload = {
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [tx_hash],
"id": 1
}
response = requests.post(url, json=payload)
data = response.json()
if 'result' in data and data['result']:
tx = data['result']
print(f"Transaction Hash: {tx['hash']}")
print(f"From: {tx['from']}")
print(f"To: {tx['to']}")
print(f"Value: {int(tx['value'], 16) / 10**18:.6f} BERA")
print(f"Gas Price: {int(tx['gasPrice'], 16) / 10**9:.2f} Gwei")
print(f"Block Number: {int(tx['blockNumber'], 16) if tx['blockNumber'] else 'Pending'}")
return tx
else:
print("Transaction not found")
return None
# Using web3.py
def get_transaction_web3(tx_hash):
w3 = Web3(Web3.HTTPProvider('https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY'))
try:
tx = w3.eth.get_transaction(tx_hash)
print(f"Transaction Details:")
print(f"Hash: {tx['hash'].hex()}")
print(f"From: {tx['from']}")
print(f"To: {tx['to']}")
print(f"Value: {w3.from_wei(tx['value'], 'ether')} BERA")
print(f"Gas Price: {w3.from_wei(tx['gasPrice'], 'gwei')} Gwei")
print(f"Block Number: {tx['blockNumber'] if tx['blockNumber'] else 'Pending'}")
return tx
except Exception as e:
print(f"Error: {e}")
return None
# Monitor transaction confirmation
def wait_for_transaction(w3, tx_hash, timeout=120):
start_time = time.time()
while time.time() - start_time < timeout:
try:
tx = w3.eth.get_transaction(tx_hash)
if tx['blockNumber'] is not None:
print(f"Transaction confirmed in block {tx['blockNumber']}")
return tx
else:
print("Transaction still pending...")
time.sleep(2)
except Exception as e:
print(f"Error checking transaction: {e}")
time.sleep(2)
raise TimeoutError("Transaction not confirmed within timeout")
# Analyze transaction data
def analyze_transaction(tx_hash):
w3 = Web3(Web3.HTTPProvider('https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY'))
tx = w3.eth.get_transaction(tx_hash)
if not tx:
return None
# Get receipt if available
receipt = None
try:
receipt = w3.eth.get_transaction_receipt(tx_hash)
except:
pass
analysis = {
'hash': tx['hash'].hex(),
'from': tx['from'],
'to': tx['to'],
'value_bera': float(w3.from_wei(tx['value'], 'ether')),
'gas_limit': tx['gas'],
'gas_price_gwei': float(w3.from_wei(tx['gasPrice'], 'gwei')),
'nonce': tx['nonce'],
'block_number': tx['blockNumber'],
'transaction_index': tx['transactionIndex'],
'status': 'confirmed' if tx['blockNumber'] else 'pending'
}
if receipt:
analysis['gas_used'] = receipt['gasUsed']
analysis['success'] = receipt['status'] == 1
analysis['logs_count'] = len(receipt['logs'])
return analysis
package main
import (
"context"
"fmt"
"log"
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY")
if err != nil {
log.Fatal(err)
}
// Get transaction by hash
txHash := common.HexToHash("0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d")
tx, isPending, err := client.TransactionByHash(context.Background(), txHash)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Transaction Hash: %s\n", tx.Hash().Hex())
fmt.Printf("From: %s\n", getTransactionSender(tx))
fmt.Printf("To: %s\n", tx.To().Hex())
fmt.Printf("Value: %f BERA\n", weiToBera(tx.Value()))
fmt.Printf("Gas Price: %f Gwei\n", weiToGwei(tx.GasPrice()))
fmt.Printf("Gas Limit: %d\n", tx.Gas())
fmt.Printf("Nonce: %d\n", tx.Nonce())
fmt.Printf("Pending: %t\n", isPending)
// Get additional details if not pending
if !isPending {
receipt, err := client.TransactionReceipt(context.Background(), txHash)
if err == nil {
fmt.Printf("Block Number: %d\n", receipt.BlockNumber.Uint64())
fmt.Printf("Gas Used: %d\n", receipt.GasUsed)
fmt.Printf("Status: %s\n", getReceiptStatus(receipt))
}
}
}
func getTransactionSender(tx *types.Transaction) string {
// Note: This requires the transaction to be signed
// In practice, you might need to use a different method
// or get this from the transaction receipt
from, err := types.Sender(types.NewEIP155Signer(tx.ChainId()), tx)
if err != nil {
return "Unknown"
}
return from.Hex()
}
func weiToBera(wei *big.Int) float64 {
ether := new(big.Float)
ether.SetString(wei.String())
ether = ether.Quo(ether, big.NewFloat(1e18))
result, _ := ether.Float64()
return result
}
func weiToGwei(wei *big.Int) float64 {
gwei := new(big.Float)
gwei.SetString(wei.String())
gwei = gwei.Quo(gwei, big.NewFloat(1e9))
result, _ := gwei.Float64()
return result
}
func getReceiptStatus(receipt *types.Receipt) string {
if receipt.Status == types.ReceiptStatusSuccessful {
return "Success"
}
return "Failed"
}
// Wait for transaction to be mined
func waitForTransaction(client *ethclient.Client, txHash common.Hash, timeout time.Duration) (*types.Transaction, *types.Receipt, error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return nil, nil, fmt.Errorf("timeout waiting for transaction")
case <-ticker.C:
tx, isPending, err := client.TransactionByHash(ctx, txHash)
if err != nil {
continue
}
if !isPending {
receipt, err := client.TransactionReceipt(ctx, txHash)
if err != nil {
continue
}
return tx, receipt, nil
}
}
}
}
// Analyze transaction patterns
func analyzeTransaction(client *ethclient.Client, txHash common.Hash) {
tx, _, err := client.TransactionByHash(context.Background(), txHash)
if err != nil {
log.Printf("Failed to get transaction: %v", err)
return
}
// Analyze transaction type
if tx.To() == nil {
fmt.Println("Transaction Type: Contract Creation")
} else if len(tx.Data()) > 0 {
fmt.Println("Transaction Type: Contract Interaction")
} else {
fmt.Println("Transaction Type: Simple Transfer")
}
// Analyze gas usage
receipt, err := client.TransactionReceipt(context.Background(), txHash)
if err == nil {
gasEfficiency := float64(receipt.GasUsed) / float64(tx.Gas()) * 100
fmt.Printf("Gas Efficiency: %.2f%%\n", gasEfficiency)
}
}
Response Example
Successful Response (Confirmed Transaction)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"hash": "0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d",
"nonce": "0x15",
"blockHash": "0x8b535bf5c6cf7e1b5f9b8f7a9b5e9b3a2b8f7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
"blockNumber": "0x5bad55",
"transactionIndex": "0x2",
"from": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"to": "0x8ba1f109551bD432803012645Hac136c8ab3b",
"value": "0x1bc16d674ec80000",
"gas": "0x5208",
"gasPrice": "0x174876e800",
"input": "0x",
"v": "0x1c",
"r": "0x9a3d...af6c",
"s": "0x6f1a...7b2e",
"type": "0x0"
}
}
Successful Response (Pending Transaction)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"hash": "0x1e2910a262b2a9ed0b4b0c8e5e6e2b4d8e1e2b3c4d5f6a7b8c9d0e1f2a3b4c5d",
"nonce": "0x16",
"blockHash": null,
"blockNumber": null,
"transactionIndex": null,
"from": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"to": "0x8ba1f109551bD432803012645Hac136c8ab3b",
"value": "0x1bc16d674ec80000",
"gas": "0x5208",
"gasPrice": "0x174876e800",
"input": "0x",
"v": "0x1c",
"r": "0x9a3d...af6c",
"s": "0x6f1a...7b2e",
"type": "0x0"
}
}
Transaction Not Found
{
"jsonrpc": "2.0",
"id": 1,
"result": null
}
Common Use Cases
1. Transaction Status Tracking
Monitor transaction confirmation status:
class TransactionTracker {
constructor(provider) {
this.provider = provider;
}
async trackTransaction(txHash) {
const tx = await this.provider.getTransaction(txHash);
if (!tx) {
return { status: 'not_found' };
}
if (!tx.blockNumber) {
return {
status: 'pending',
transaction: tx
};
}
const currentBlock = await this.provider.getBlockNumber();
const confirmations = currentBlock - tx.blockNumber + 1;
const receipt = await this.provider.getTransactionReceipt(txHash);
return {
status: 'confirmed',
confirmations,
success: receipt.status === 1,
transaction: tx,
receipt
};
}
async waitForConfirmations(txHash, requiredConfirmations = 6) {
while (true) {
const result = await this.trackTransaction(txHash);
if (result.status === 'not_found') {
throw new Error('Transaction not found');
}
if (result.status === 'confirmed' && result.confirmations >= requiredConfirmations) {
return result;
}
console.log(`Confirmations: ${result.confirmations || 0}/${requiredConfirmations}`);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
}
2. Transaction Analysis
Analyze transaction patterns and details:
async function analyzeTransaction(provider, txHash) {
const tx = await provider.getTransaction(txHash);
if (!tx) return null;
const analysis = {
hash: tx.hash,
type: 'unknown',
value: ethers.formatEther(tx.value),
gasPrice: ethers.formatUnits(tx.gasPrice, 'gwei'),
gasLimit: tx.gas.toString(),
from: tx.from,
to: tx.to
};
// Determine transaction type
if (!tx.to) {
analysis.type = 'contract_creation';
} else if (tx.data && tx.data !== '0x') {
analysis.type = 'contract_interaction';
analysis.inputSize = (tx.data.length - 2) / 2; // bytes
} else {
analysis.type = 'simple_transfer';
}
// Get execution results if available
if (tx.blockNumber) {
const receipt = await provider.getTransactionReceipt(txHash);
analysis.gasUsed = receipt.gasUsed.toString();
analysis.gasEfficiency = (Number(receipt.gasUsed) / Number(tx.gas) * 100).toFixed(2);
analysis.success = receipt.status === 1;
analysis.logCount = receipt.logs.length;
}
return analysis;
}
3. Batch Transaction Lookup
Efficiently look up multiple transactions:
async function batchGetTransactions(provider, txHashes) {
const batch = txHashes.map((hash, index) => ({
jsonrpc: '2.0',
method: 'eth_getTransactionByHash',
params: [hash],
id: index + 1
}));
const response = await fetch('https://api-berachain-mainnet.n.dwellir.com/YOUR_API_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(batch)
});
const results = await response.json();
return results.map((result, index) => ({
hash: txHashes[index],
transaction: result.result,
found: result.result !== null
}));
}
4. Transaction History Builder
Build transaction history for an address:
async function buildTransactionHistory(provider, address, startBlock, endBlock) {
const history = [];
// This would typically use eth_getLogs or other methods to find transactions
// This is a simplified example
for (let blockNumber = startBlock; blockNumber <= endBlock; blockNumber++) {
const block = await provider.getBlock(blockNumber, true);
const relevantTxs = block.transactions.filter(tx =>
tx.from.toLowerCase() === address.toLowerCase() ||
tx.to?.toLowerCase() === address.toLowerCase()
);
for (const tx of relevantTxs) {
const receipt = await provider.getTransactionReceipt(tx.hash);
history.push({
hash: tx.hash,
blockNumber: tx.blockNumber,
timestamp: block.timestamp,
from: tx.from,
to: tx.to,
value: ethers.formatEther(tx.value),
gasUsed: receipt.gasUsed.toString(),
success: receipt.status === 1,
type: tx.from.toLowerCase() === address.toLowerCase() ? 'sent' : 'received'
});
}
}
return history.sort((a, b) => b.blockNumber - a.blockNumber);
}
Performance Optimization
Transaction Result Caching
Cache transaction results to reduce API calls:
class TransactionCache {
constructor(ttl = 300000) { // 5 minute cache for confirmed txs
this.cache = new Map();
this.ttl = ttl;
}
async getTransaction(provider, txHash) {
const cached = this.cache.get(txHash);
if (cached) {
// For pending transactions, check more frequently
if (!cached.data.blockNumber) {
if (Date.now() - cached.timestamp < 10000) { // 10 second cache for pending
return cached.data;
}
} else if (Date.now() - cached.timestamp < this.ttl) {
return cached.data;
}
}
const tx = await provider.getTransaction(txHash);
if (tx) {
this.cache.set(txHash, {
data: tx,
timestamp: Date.now()
});
}
return tx;
}
invalidate(txHash) {
this.cache.delete(txHash);
}
clear() {
this.cache.clear();
}
}
Batch Processing
Process multiple transaction lookups efficiently:
async function processTransactionBatch(provider, txHashes, concurrency = 10) {
const results = [];
for (let i = 0; i < txHashes.length; i += concurrency) {
const batch = txHashes.slice(i, i + concurrency);
const batchPromises = batch.map(async (hash) => {
try {
const tx = await provider.getTransaction(hash);
return { hash, transaction: tx, success: true };
} catch (error) {
return { hash, error: error.message, success: false };
}
});
const batchResults = await Promise.all(batchPromises);
results.push(...batchResults);
}
return results;
}
Error Handling
Common errors and solutions:
Error Code | Description | Solution |
---|---|---|
-32602 | Invalid params | Check transaction hash format (64 hex chars) |
-32603 | Internal error | Retry with exponential backoff |
-32000 | Transaction not found | Verify hash or wait if recently submitted |
async function safeGetTransaction(provider, txHash, maxRetries = 3) {
// Validate hash format
if (!/^0x[a-fA-F0-9]{64}$/.test(txHash)) {
throw new Error('Invalid transaction hash format');
}
for (let i = 0; i < maxRetries; i++) {
try {
return await provider.getTransaction(txHash);
} catch (error) {
console.error(`Attempt ${i + 1} failed:`, error.message);
if (error.code === -32602) {
throw new Error(`Invalid transaction hash: ${error.message}`);
}
if (i === maxRetries - 1) {
throw error;
}
// Exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}
// Usage with comprehensive error handling
try {
const tx = await safeGetTransaction(provider, txHash);
if (!tx) {
console.log('Transaction not found - may not exist or not yet propagated');
return;
}
if (!tx.blockNumber) {
console.log('Transaction is pending');
} else {
console.log(`Transaction confirmed in block ${tx.blockNumber}`);
}
} catch (error) {
console.error('Failed to retrieve transaction:', error.message);
}
Transaction Validation Utilities
Hash Format Validation
function isValidTransactionHash(hash) {
return /^0x[a-fA-F0-9]{64}$/.test(hash);
}
function normalizeTransactionHash(hash) {
if (!hash.startsWith('0x')) {
hash = '0x' + hash;
}
return hash.toLowerCase();
}
Transaction Analysis
function analyzeTransactionGas(tx, receipt = null) {
const gasLimit = Number(tx.gas);
const gasPrice = Number(tx.gasPrice);
const maxCost = gasLimit * gasPrice;
const analysis = {
gasLimit,
gasPrice: gasPrice / 1e9, // in Gwei
maxCostWei: maxCost,
maxCostBera: maxCost / 1e18
};
if (receipt) {
const gasUsed = Number(receipt.gasUsed);
analysis.gasUsed = gasUsed;
analysis.actualCostWei = gasUsed * gasPrice;
analysis.actualCostBera = analysis.actualCostWei / 1e18;
analysis.gasEfficiency = (gasUsed / gasLimit * 100).toFixed(2) + '%';
}
return analysis;
}
Need help? Contact our support team or check the Berachain documentation.