How to Check Ethereum Account Balances Using Go

·

Retrieving an Ethereum account balance programmatically is a fundamental task for developers. This guide will walk you through the process using the Go programming language and the go-ethereum library, covering both current and historical balances, unit conversion, and pending balances.

Prerequisites for Reading Ethereum Balances

Before diving into the code, ensure you have the necessary tools and libraries installed. You'll need a basic understanding of Go and access to an Ethereum node, which you can connect to via a service like Infura or a local node. The go-ethereum SDK (geth) is the primary library for interacting with the Ethereum blockchain in Go.

Install the required package using the following command:

go get github.com/ethereum/go-ethereum/ethclient

This library provides the methods needed to query blockchain data, including account balances.

Retrieving the Latest Balance

To fetch the most recent balance of an account, use the BalanceAt method from the Ethereum client. This method requires the account address and a block number parameter. Setting the block number to nil returns the balance at the latest mined block.

Here's a basic example:

account := common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")
balance, err := client.BalanceAt(context.Background(), account, nil)
if err != nil {
    log.Fatal(err)
}
fmt.Println(balance) // Output: 25893180161173005034

This code snippet connects to an Ethereum client, specifies an account address, and retrieves its current balance in wei.

Fetching Historical Balances

You can also retrieve an account's balance at a specific block height by passing a block number to the BalanceAt method. The block number must be of type *big.Int.

blockNumber := big.NewInt(5532993)
balance, err := client.BalanceAt(context.Background(), account, blockNumber)
if err != nil {
    log.Fatal(err)
}
fmt.Println(balance) // Output: 25729324269165216042

This is useful for auditing, historical analysis, or verifying state at a particular point in time.

Converting Wei to Ether

Ether values on the Ethereum blockchain are represented in wei, the smallest unit. To convert a balance from wei to ETH, divide the value by 10^18. Since we're dealing with large numbers, use Go's math and math/big packages for precision.

fbalance := new(big.Float)
fbalance.SetString(balance.String())
ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))
fmt.Println(ethValue) // Output: 25.729324269165216041

This conversion is essential for displaying human-readable values.

Checking Pending Balances

In some cases, you might need to check the pending balance of an account, which includes transactions that have been submitted but not yet confirmed. Use the PendingBalanceAt method for this purpose.

pendingBalance, err := client.PendingBalanceAt(context.Background(), account)
if err != nil {
    log.Fatal(err)
}
fmt.Println(pendingBalance) // Output: 25729324269165216042

This is particularly useful for applications that need to reflect unconfirmed transactions, such as exchanges or wallets.

👉 Explore advanced blockchain development tools

Complete Code Example

Below is a complete Go program that demonstrates all the concepts covered above. It connects to an Ethereum node, retrieves current and historical balances, performs unit conversion, and checks pending balances.

package main

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

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

func main() {
    client, err := ethclient.Dial("https://cloudflare-eth.com")
    if err != nil {
        log.Fatal(err)
    }

    account := common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")

    // Get latest balance
    balance, err := client.BalanceAt(context.Background(), account, nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(balance) // 25893180161173005034

    // Get historical balance
    blockNumber := big.NewInt(5532993)
    balanceAt, err := client.BalanceAt(context.Background(), account, blockNumber)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(balanceAt) // 25729324269165216042

    // Convert wei to ETH
    fbalance := new(big.Float)
    fbalance.SetString(balanceAt.String())
    ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))
    fmt.Println(ethValue) // 25.729324269165216041

    // Get pending balance
    pendingBalance, err := client.PendingBalanceAt(context.Background(), account)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(pendingBalance) // 25729324269165216042
}

Frequently Asked Questions

What is the difference between BalanceAt and PendingBalanceAt?
BalanceAt returns the account balance at a specific block height (or the latest mined block if nil is passed). PendingBalanceAt returns the balance that includes transactions from the mempool that are not yet confirmed, reflecting the pending state.

Why is my balance displayed in such a large number?
Ether values are stored in wei on the blockchain, which is the smallest unit. A single ETH is equivalent to 10^18 wei. You must convert wei to ETH for human-readable displays using the conversion method shown.

How can I handle errors when the Ethereum client connection fails?
Always check the error returned by ethclient.Dial and BalanceAt methods. Use proper error handling, such as logging the error and exiting gracefully, to avoid runtime panics.

Can I use this code with any Ethereum-compatible blockchain?
Yes, the same code can be used with other EVM-compatible blockchains (e.g., BSC, Polygon) by connecting to the appropriate RPC endpoint. Ensure the client URL points to the correct network.

What are common issues when converting wei to ETH?
The most common issue is precision loss due to improper handling of large numbers. Always use the math/big package for calculations to maintain accuracy.

Is it necessary to use a remote node, or can I run my own?
You can use either. Remote nodes (like Infura) are convenient for quick setup, while running your own node gives you full control and independence but requires more resources.

👉 Get detailed guides on blockchain development