Home / Computer Science / Python / Track Ethereum Transactions Using Python (Etherscan API Guide)

Track Ethereum Transactions Using Python (Etherscan API Guide)

If you’re dealing with Ethereum transactions—whether for security audits, tax reporting, or investigating suspicious activity—you need a reliable way to fetch transaction history. In this guide, I’ll show you how to build a Python script that pulls transaction details (TX hash, timestamp, and amount) from Etherscan for any wallet address.

Ethereum Transaction Extraction and Why Script is Useful

  • Audit wallets for incoming/outgoing transactions.
  • Track stolen funds in real time (useful for hackers exploiting DeFi protocols).
  • Monitor whale movements (large ETH transfers).
  • Automate transaction logging for accounting or legal purposes.

How the Script Works

The script uses Etherscan’s free API to:

  1. Fetch normal transactions (ETH transfers).
  2. Fetch internal transactions (smart contract interactions).
  3. Combine and sort them by timestamp.
  4. Filter by destination wallet (if needed).

Step-by-Step Setup

1. Get an Etherscan API Key

  • Go to Etherscan.io → Sign up (free).
  • Navigate to “API-Keys” → Create a new key.
  • Replace YOUR_ETHERSCAN_API_KEY in the script.

2. Install Required Libraries

Run this in your command prompt terminal:

pip install requests

3. Run the Script by replacing the API key

import requests
import json
from datetime import datetime

# Etherscan API configuration
ETHERSCAN_API_KEY = "###"  # Replace with your Etherscan API key
ETHERSCAN_API_URL = "https://api.etherscan.io/api"

def get_transactions(wallet_address):
    """
    Fetch all normal transactions for a given Ethereum wallet address
    """
    params = {
        "module": "account",
        "action": "txlist",
        "address": wallet_address,
        "startblock": 0,
        "endblock": 99999999,
        "sort": "asc",
        "apikey": ETHERSCAN_API_KEY
    }
    
    response = requests.get(ETHERSCAN_API_URL, params=params)
    data = response.json()
    
    if data["status"] != "1":
        print(f"Error: {data.get('message', 'Unknown error')}")
        return []
    
    return data["result"]

def get_internal_transactions(wallet_address):
    """
    Fetch all internal transactions for a given Ethereum wallet address
    """
    params = {
        "module": "account",
        "action": "txlistinternal",
        "address": wallet_address,
        "startblock": 0,
        "endblock": 99999999,
        "sort": "asc",
        "apikey": ETHERSCAN_API_KEY
    }
    
    response = requests.get(ETHERSCAN_API_URL, params=params)
    data = response.json()
    
    if data["status"] != "1":
        print(f"Error: {data.get('message', 'Unknown error')}")
        return []
    
    return data["result"]

def format_transactions(transactions, internal=False):
    """
    Format transaction data into a more readable structure
    """
    formatted = []
    for tx in transactions:
        # Convert timestamp to readable date
        timestamp = int(tx["timeStamp"])
        date = datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
        
        # Determine amount in Ether
        if internal:
            amount = int(tx["value"]) / 10**18
        else:
            amount = int(tx["value"]) / 10**18 if "value" in tx else 0
        
        formatted.append({
            "tx_hash": tx["hash"],
            "timestamp": timestamp,
            "date": date,
            "amount_eth": amount,
            "from": tx["from"],
            "to": tx["to"],
            "is_internal": internal
        })
    
    return formatted

def get_all_transactions(wallet_address):
    """
    Get both normal and internal transactions for a wallet
    """
    normal_txs = get_transactions(wallet_address)
    internal_txs = get_internal_transactions(wallet_address)
    
    all_txs = format_transactions(normal_txs) + format_transactions(internal_txs, True)
    
    # Sort all transactions by timestamp
    all_txs.sort(key=lambda x: x["timestamp"])
    
    return all_txs

def filter_by_destination(transactions, destination_wallet):
    """
    Filter transactions by destination wallet
    """
    return [tx for tx in transactions if tx["to"].lower() == destination_wallet.lower()]

def main():
    # Get user input
    wallet_address = input("Enter the source wallet address: ").strip()
    destination_wallet = input("Enter the destination wallet address (leave empty to see all transactions): ").strip()
    
    print(f"\nFetching transactions for wallet: {wallet_address}")
    
    # Get all transactions
    transactions = get_all_transactions(wallet_address)
    
    # Filter by destination if provided
    if destination_wallet:
        transactions = filter_by_destination(transactions, destination_wallet)
    
    # Display results
    if not transactions:
        print("No transactions found.")
        return
    
    print("\nTransaction Hash".ljust(66), "Timestamp".ljust(20), "Amount (ETH)".ljust(20), "Internal")
    print("-" * 120)
    
    for tx in transactions:
        print(
            tx["tx_hash"].ljust(66),
            tx["date"].ljust(20),
            str(tx["amount_eth"]).ljust(20),
            "Yes" if tx["is_internal"] else "No"
        )

if __name__ == "__main__":
    main()

How to Use It

  1. Run the script → Enter a wallet address (e.g., 0x742d35Cc...)
Ethereum Transaction
  1. (Optional) Filter by a destination wallet to see only outgoing TXs.
  2. See results in a clean table format like the above picture. Here, I blurred the wallet address because of security.

Limitations & Improvements

  • Rate Limits: Etherscan’s free API allows 5 calls/sec.
  • ERC-20 Tokens: This script tracks only ETH—expand it to support tokens.
  • Large Data Handling: For wallets with 10,000+ TXs, use pagination.

Final Thoughts

This script is a powerful starting point for Ethereum transaction analysis. For advanced tracking (e.g., Tornado Cash withdrawals), you’d need to integrate Dune Analytics or Arkham Intelligence.

Need help customizing it? Drop a comment below

(Disclaimer: This script is for educational purposes only. Always comply with local laws when tracking blockchain transactions.)

About GSK

I'm Santosh Gadagamma, an Experienced Software Engineer passionate about sharing knowledge in technologies like Java, C/C++, DBMS/RDBMS, Bootstrap, Big Data, Javascript, Android, Spring, Hibernate, Struts, and all levels of software design, development, deployment, and maintenance. I believe computers are essential for the world's functioning, and I'm committed to helping others learn the skills they need to succeed in tech. My website is a valuable learning tool to help you reach greater heights in your education and career, and I believe that education has no end points.

Check Also

Lists in Python

Unlock the power of Python lists with our detailed guide. Learn to create, modify, and optimize lists in Python with over 10 proven techniques.

Leave a Reply