description: Tutorial on how to read account balances from the blockchain with Go.

Account Balances

Reading the balance of an account is pretty simple; call the BalanceAt method of the client passing it the account address and optional block number. Setting nil as the block number will return the latest balance.

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

Passing the block number let’s you read the account balance at the time of that block. The block number must be a big.Int.

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

Numbers in ethereum are dealt using the smallest possible unit because they’re fixed-point precision, which in the case of ETH it’s wei. To read the ETH value you must do the calculation wei / 10^18. Because we’re dealing with big numbers we’ll have to import the native Go math and math/big packages. Here’s how’d you do the conversion.

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

Pending balance

Sometimes you’ll want to know what the pending account balance is, for example after submitting or waiting for a transaction to be confirmed. The client provides a similar method to BalanceAt called PendingBalanceAt which accepts the account address as a parameter.

  1. pendingBalance, err := client.PendingBalanceAt(context.Background(), account)
  2. fmt.Println(pendingBalance) // 25729324269165216042

Full code

account_balance.go

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "math"
  7. "math/big"
  8. "github.com/ethereum/go-ethereum/common"
  9. "github.com/ethereum/go-ethereum/ethclient"
  10. )
  11. func main() {
  12. client, err := ethclient.Dial("https://mainnet.infura.io")
  13. if err != nil {
  14. log.Fatal(err)
  15. }
  16. account := common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")
  17. balance, err := client.BalanceAt(context.Background(), account, nil)
  18. if err != nil {
  19. log.Fatal(err)
  20. }
  21. fmt.Println(balance) // 25893180161173005034
  22. blockNumber := big.NewInt(5532993)
  23. balanceAt, err := client.BalanceAt(context.Background(), account, blockNumber)
  24. if err != nil {
  25. log.Fatal(err)
  26. }
  27. fmt.Println(balanceAt) // 25729324269165216042
  28. fbalance := new(big.Float)
  29. fbalance.SetString(balanceAt.String())
  30. ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))
  31. fmt.Println(ethValue) // 25.729324269165216041
  32. pendingBalance, err := client.PendingBalanceAt(context.Background(), account)
  33. fmt.Println(pendingBalance) // 25729324269165216042
  34. }