How to Retrieve All Ethereum Addresses and Balances Using Web3

·

Ethereum, as one of the most influential blockchain platforms, powers a vast ecosystem of decentralized applications (dApps), smart contracts, and digital assets. For developers and blockchain analysts, understanding how to interact with the Ethereum network at a foundational level is essential. One powerful capability is retrieving all Ethereum addresses and their corresponding balances using Web3.js — a popular JavaScript library for interacting with Ethereum.

This guide walks you through the technical process of scanning the Ethereum blockchain to collect wallet addresses and balance data, leveraging core Web3 functionalities. Whether you're building analytics tools, conducting research, or exploring blockchain data structures, this tutorial provides practical insights into Ethereum’s on-chain data retrieval.


Understanding the Core Approach

To extract all Ethereum addresses and their balances, we need to traverse the blockchain from the genesis block to the latest block. Each block contains transaction records that reveal sender (from) and receiver (to) addresses. By processing these transactions and checking for unique addresses, we can compile a comprehensive list of wallets and query their current ETH balances.

The methodology involves several key steps:

  1. Get the current block height – Identify how many blocks exist on the chain.
  2. Iterate through each block – Retrieve block data sequentially.
  3. Extract transactions – Pull transaction hashes from each block.
  4. Fetch transaction details – Obtain from and to addresses.
  5. Differentiate contract vs. external accounts – Avoid redundant queries by identifying contract creation.
  6. Query ETH balance – Use getBalance() for valid external addresses.

These operations are made possible via Web3.js methods such as getBlockNumber(), getBlock(), getTransaction(), and getCode().


Setting Up Web3.js Environment

Before writing any code, ensure your development environment supports Node.js and npm (Node Package Manager). Install Web3.js using the following command:

npm install web3

For users in regions with restricted network access, consider using cnpm (Aliyun mirror) for faster downloads:

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install web3

Once installed, initialize Web3 by connecting to an Ethereum node. Public endpoints like Infura or Alchemy provide reliable access without running a local node.

👉 Discover how to securely connect to Ethereum nodes with advanced API tools.


Step-by-Step Implementation

Below is a complete implementation in JavaScript using asynchronous Web3 calls:

const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'); // Replace with your Infura ID

let addressList = [];

async function getBlockNumber() {
  const latestBlock = await web3.eth.getBlockNumber();
  console.log("Latest Block Number:", latestBlock);
  await throughBlocks(latestBlock);
}

async function throughBlocks(endBlock) {
  for (let i = 0; i <= endBlock; i++) {
    await getBlock(i);
  }
}

async function getBlock(blockNumber) {
  const block = await web3.eth.getBlock(blockNumber, true); // Include full transaction objects
  if (block && block.transactions) {
    for (const tx of block.transactions) {
      await processTransaction(tx);
    }
  }
}

async function processTransaction(tx) {
  if (tx.from) await checkAndStoreAddress(tx.from);
  if (tx.to) await checkAndStoreAddress(tx.to);
}

async function checkAndStoreAddress(address) {
  if (!address || addressList.includes(address)) return;

  try {
    const code = await web3.eth.getCode(address);
    // If code is '0x', it's an externally owned account (EOA), not a contract
    if (code === '0x') {
      await getBalance(address);
      addressList.push(address);
    }
  } catch (err) {
    console.error("Error checking address:", address, err.message);
  }
}

async function getBalance(address) {
  try {
    const balance = await web3.eth.getBalance(address);
    const ethBalance = web3.utils.fromWei(balance, 'ether');
    console.log(`Address: ${address} | Balance: ${ethBalance} ETH`);
  } catch (err) {
    console.error("Failed to get balance for", address, err.message);
  }
}

// Start execution
getBlockNumber().catch(console.error);

Key Notes:


Optimizing Performance and Scalability

Scanning the entire Ethereum blockchain is computationally intensive and time-consuming due to over 20 million blocks (as of 2025). Consider the following optimizations:

👉 Explore high-performance blockchain APIs designed for scalable dApp development.


Frequently Asked Questions (FAQ)

Q: Can I retrieve all Ethereum addresses in a reasonable time?

A: Technically yes, but scanning every block from genesis is extremely slow. As of 2025, Ethereum has over 20 million blocks. Full traversal may take days or weeks depending on infrastructure. For practical use, consider incremental scans or third-party APIs.

Q: Why do we check getCode() before getting a balance?

A: This determines if an address is a smart contract. Contracts often have zero balance and generate noise in analysis. Filtering them out improves efficiency unless contract funds are relevant.

Q: Is it safe to use public nodes like Infura?

A: Yes, for read-only operations. However, rate limits apply. For heavy usage, consider dedicated node services or running your own Geth/Besu node.

Q: How accurate is the balance data?

A: The getBalance() method returns the current balance at the time of query. Since blockchain state changes constantly, balances may differ slightly between scans.

Q: Can this method detect ERC-20 token balances?

A: No — this approach only retrieves ETH balances. To get token holdings, you must query individual token contracts using their ABI and balanceOf() function.

Q: What are alternatives to Web3.js?

A: Libraries like ethers.js offer similar functionality with a more modern API design. Ethers.js is often preferred for its lightweight footprint and better TypeScript support.


Practical Use Cases

This technique enables various real-world applications:

While full scans are resource-heavy, targeted versions (e.g., monitoring specific wallets or DeFi protocols) are highly efficient.


Final Thoughts

Understanding how to programmatically access Ethereum address and balance data opens doors to deeper blockchain analysis. With Web3.js, developers can build powerful tools that interact directly with the decentralized web.

However, scalability remains a challenge when dealing with large-scale data extraction. Combining Web3 with optimized infrastructure — such as high-throughput RPC providers or indexed data layers — enhances performance significantly.

Whether you're a beginner learning blockchain fundamentals or an experienced engineer building dApps, mastering these techniques strengthens your ability to innovate within the Web3 space.

👉 Unlock advanced blockchain development tools and elevate your Web3 projects today.