How to Transfer and Query ETH on a Local Private Blockchain

This guide provides a step-by-step explanation of how to transfer ETH tokens and query balances on a locally hosted Ethereum private blockchain using Go and the go-ethereum library.


Core Concepts

1. Private Blockchain Basics

  • A private Ethereum blockchain allows controlled access and customization of network rules.
  • Transactions are validated only by designated nodes, eliminating the need for gas fees in test environments.

2. Key Components

  • Keystore Files: Encrypted wallet files storing private keys (e.g., UTC--2020-05-26T03-30-15.678995000Z--d8e670...).
  • Web3 Providers: Local RPC endpoints (e.g., http://127.0.0.1:8545) connect your application to the blockchain node.
  • Wei and ETH: The smallest denomination (1 ETH = 10¹⁸ wei).

👉 Learn how to set up a private Ethereum network


Step-by-Step Implementation

1. Initialize Account and Client

“`go
type accountBody struct {
File string
Passwd string
Address string
}

func newAccount(file string) *accountBody {
return &accountBody{
File: file,
Passwd: “111111”, // Default password for demo
}
}

func newClient(rawurl string) *clientManage {
rpcDial, err := rpc.Dial(rawurl)
if err != nil { panic(err) }
return &clientManage{
ethConn: ethclient.NewClient(rpcDial),
}
}
“`

2. Query ETH Balances

“`go
func (ec *clientManage) getBalance(address string) (string, error) {
account := common.HexToAddress(address)
balance, err := ec.ethConn.BalanceAt(context.Background(), account, nil)
if err != nil { return “”, err }

// Convert wei to ETH
fbalance := new(big.Float).SetInt(balance)
ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))
return ethValue.String(), nil

}
“`

3. Transfer ETH Between Accounts

“`go
func (ec clientManage) transferEth(pk, fromAddress, toAddress string, weiValue big.Int) (string, error) {
privateKey, err := crypto.HexToECDSA(pk)
if err != nil { log.Fatal(err) }

nonce, err := ec.ethConn.PendingNonceAt(context.Background(), common.HexToAddress(fromAddress))
if err != nil { log.Fatal(err) }

tx := types.NewTransaction(
    nonce,
    common.HexToAddress(toAddress),
    weiValue,
    21000, // Gas limit
    big.NewInt(1), // Gas price (adjust for private chains)
    nil,
)

signedTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(150)), privateKey)
if err := ec.ethConn.SendTransaction(context.Background(), signedTx); err != nil {
    log.Fatal(err)
}
return signedTx.Hash().Hex(), nil

}
“`

👉 Explore advanced blockchain development tools


Key Functions Explained

Function Purpose
keyStoreToPrivateKey() Decrypts keystore files to extract private keys and addresses.
EthToWei() Converts ETH values to wei for precise transactions.
getBalance() Fetches the ETH balance of a given address from the blockchain state.

FAQs

1. Why use a private blockchain for testing?

  • Avoids real gas costs and provides deterministic environments for debugging.

2. How do I generate a keystore file?

  • Use Geth or MetaMask to create wallets. Keystores are typically stored in ./wallets/.

3. What’s the role of chainID in signing?

  • Prevents replay attacks. For private chains, this is arbitrary (e.g., 150 in the example).

4. How to handle transaction failures?

  • Check gas limits, nonce values, and network connectivity. Private chains often skip gas validation.

5. Can I use this for mainnet transactions?

  • Yes, but replace test parameters (e.g., gas price, chainID) with mainnet-compatible values.

Best Practices

  • Security: Never hardcode passwords or private keys in production code.
  • Error Handling: Implement robust checks for RPC connectivity and transaction receipts.
  • Testing: Use tools like Ganache for local blockchain simulations.

By following this guide, you’ll master ETH transactions and balance queries on private networks, a foundational skill for blockchain developers. 🚀