How to Get Ethereum Account Balance Using Go

·

Understanding how to retrieve an Ethereum account's balance is a fundamental skill for blockchain developers. Whether you're building decentralized applications, analyzing wallet activity, or auditing transactions, being able to query on-chain data accurately and efficiently is crucial. In this guide, we’ll walk through how to use Go (Golang) to fetch the ETH balance of any Ethereum address—whether it’s an externally owned account (EOA), a smart contract, or a DeFi protocol vault.

This method does not require private keys—only the public address and access to an Ethereum node. We'll use the go-ethereum library, which provides robust tools for interacting with the Ethereum blockchain programmatically.


Core Keywords

These keywords reflect both technical search intent and developer-focused queries commonly used when learning about blockchain integration with Go.


Querying ETH Balance Without Private Keys

To retrieve an account’s ETH balance, you only need two things:

  1. The Ethereum address (e.g., 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045)
  2. A connection to the Ethereum mainnet via an RPC endpoint

You do not need the private key—this makes the process safe and widely applicable for read-only operations such as balance checks, transaction history analysis, or monitoring smart contracts.

The primary function used in the go-ethereum library is client.BalanceAt(), which takes three parameters:

If you pass nil as the block number, it returns the latest balance. If you specify a past block number, it performs an historical balance lookup, useful for audits or analytics.

👉 Learn how to securely connect to Ethereum nodes using modern tools

ctx := context.Background()
addr := common.HexToAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") // vitalik.eth
bn := big.NewInt(18382246)
balance, err := client.BalanceAt(ctx, addr, bn)

In this example, we're checking Vitalik Buterin’s ETH balance at block 18,382,246. The returned value is in Wei, the smallest denomination of Ether (1 ETH = 10¹⁸ Wei).


Handling Precision: Avoiding Data Loss in Balance Conversion

One of the most critical aspects when working with blockchain values is precision handling. Ethereum uses 256-bit unsigned integers (uint256) for balances, which can represent extremely large numbers.

Why Precision Matters

When converting from Wei to Ether, dividing by 1e18, standard floating-point types like float64 will lose precision due to limited significant digits. Even big.Float may truncate results if not handled carefully.

For example:

Using big.Float might give you only: 935.1430017 ETH — losing over 10 decimal places.

Recommended Approach: Use High-Precision Libraries

Option 1: Using math/big.Float

bf := big.NewFloat(0).SetInt(balance)
bf.Quo(bf, big.NewFloat(1e18))
log.Printf("Balance (big.Float): %s", bf.String())

While better than native floats, this still risks rounding errors.

Option 2: Using shopspring/decimal (Recommended)

This library supports arbitrary-precision decimal arithmetic and preserves full accuracy.

bd := decimal.RequireFromString(balance.String())
bd = bd.Div(decimal.NewFromFloat(1e18))
log.Printf("Balance (Decimal): %s", bd.String())

Output: 935.1430017464869741 — much closer to the true value.

⚠️ Best Practice: Store and process balances in Wei internally. Only convert to Ether for display purposes, and always use high-precision libraries when conversion is necessary.

Complete Working Example in Go

Below is a complete, runnable Go program that connects to the Ethereum mainnet via Infura, retrieves an account’s balance at a specific block, and prints it in both Wei and Ether with high precision.

package main

import (
    "context"
    "log"
    "math/big"
    "os"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
    "github.com/shopspring/decimal"
)

func main() {
    apiKey := os.Getenv("INFURA_API_KEY")
    url := "https://mainnet.infura.io/v3/" + apiKey

    client, err := ethclient.Dial(url)
    if err != nil {
        log.Fatalf("Could not connect to Infura: %v", err)
    }
    defer client.Close()

    ctx := context.Background()
    addr := common.HexToAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") // vitalik.eth
    bn := big.NewInt(18382246)

    balance, err := client.BalanceAt(ctx, addr, bn)
    if err != nil {
        log.Fatalf("Failed to get balance: %v", err)
    }

    log.Printf("Balance in Wei: %s", balance.String())

    // Convert using big.Float (moderate precision)
    bf := big.NewFloat(0).SetInt(balance)
    bf.Quo(bf, big.NewFloat(1e18))
    log.Printf("Balance in Ether (big.Float): %s", bf.Text('f', 10))

    // Convert using decimal.Decimal (high precision)
    bd := decimal.RequireFromString(balance.String())
    bd = bd.Div(decimal.NewFromFloat(1e18))
    log.Printf("Balance in Ether (decimal.Decimal): %s", bd.String())
}

Ensure you set your INFURA_API_KEY environment variable before running this code.

👉 Access reliable blockchain APIs for seamless development workflows


Frequently Asked Questions (FAQ)

Q: Can I get the balance of any Ethereum address?

Yes. Any public Ethereum address—whether an EOA (Externally Owned Account), a smart contract, or a DeFi pool—can have its ETH balance queried without authentication or permission.

Q: What is the difference between Wei and Ether?

Wei is the base unit of Ether. 1 Ether = 1,000,000,000,000,000,000 Wei (10¹⁸). All calculations on-chain are done in Wei to avoid floating-point inaccuracies.

Q: Why should I avoid using float64 for balance conversion?

float64 has limited precision (~15–17 significant digits). Large balances in Wei exceed this range, leading to irreversible rounding errors. Always use big.Int or decimal.Decimal.

Q: Can I query historical balances?

Yes. By passing a specific block number (as a *big.Int) to BalanceAt(), you can retrieve the balance at that point in time. This is useful for audits, tax reporting, or analytics.

Q: Do I need my own Ethereum node?

No. You can use third-party services like Infura, Alchemy, or QuickNode to access Ethereum data via HTTPS/WSS endpoints. These platforms abstract away node management.

Q: Is this method safe for production use?

Absolutely. Since no private keys are involved and the operation is read-only, it’s safe for frontends, backend services, monitoring tools, and analytics dashboards.


By mastering how to query Ethereum balances accurately in Go, you lay the foundation for more advanced blockchain interactions—such as transaction signing, contract calls, event listening, and real-time data processing.

👉 Explore powerful blockchain development tools to scale your projects