viem-goviem-go

Examples

Real-world examples showing viem-go in action, with TypeScript comparisons

Basic Examples

Get Transaction Receipt

1txHash := common.HexToHash("0x...")
2
3receipt, err := c.GetTransactionReceipt(context.Background(), txHash)
4if err != nil {
5 log.Fatal(err)
6}
7
8fmt.Printf("Status: %d\n", receipt.Status)
9fmt.Printf("Gas Used: %d\n", receipt.GasUsed)
10fmt.Printf("Block: %d\n", receipt.BlockNumber)

Contract Examples

Read ERC20 Token Info

1import "github.com/ChefBingbong/viem-go/contracts/erc20"
2
3usdcAddress := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
4token, _ := erc20.New(usdcAddress, publicClient)
5
6name, _ := token.Name(context.Background())
7symbol, _ := token.Symbol(context.Background())
8decimals, _ := token.Decimals(context.Background())
9totalSupply, _ := token.TotalSupply(context.Background())
10
11fmt.Printf("Token: %s (%s)\n", name, symbol)
12fmt.Printf("Decimals: %d\n", decimals)
13fmt.Printf("Total Supply: %s\n", totalSupply.String())

Encode Function Data

1import "github.com/ChefBingbong/viem-go/abi"
2
3parsed, _ := abi.Parse([]byte(`[{
4 "name": "transfer",
5 "type": "function",
6 "inputs": [
7 {"name": "to", "type": "address"},
8 {"name": "amount", "type": "uint256"}
9 ]
10}]`))
11
12data, _ := parsed.EncodeFunctionData("transfer",
13 common.HexToAddress("0x..."),
14 big.NewInt(1000000),
15)
16
17fmt.Printf("Encoded: 0x%x\n", data)

Account Examples

Create Account from Private Key

1import "github.com/ChefBingbong/viem-go/accounts"
2
3account, _ := accounts.PrivateKeyToAccount("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
4
5fmt.Printf("Address: %s\n", account.Address)
6fmt.Printf("Public Key: %s\n", account.PublicKey)

Create Account from Mnemonic

1import "github.com/ChefBingbong/viem-go/accounts"
2
3mnemonic := "test test test test test test test test test test test junk"
4
5account, _ := accounts.MnemonicToAccount(mnemonic, nil)
6
7fmt.Printf("Address: %s\n", account.Address)

Utility Examples

Parse and Format Units

1import "github.com/ChefBingbong/viem-go/utils/unit"
2
3// Parse ETH to wei
4wei, _ := unit.ParseEther("1.5")
5fmt.Println("Wei:", wei) // 1500000000000000000
6
7// Parse USDC (6 decimals)
8usdcAmount, _ := unit.ParseUnits("100", 6)
9fmt.Println("USDC:", usdcAmount) // 100000000
10
11// Format back
12ethString := unit.FormatEther(wei)
13fmt.Println("ETH:", ethString) // 1.5

Hash and Signature Utilities

1import (
2 "github.com/ChefBingbong/viem-go/utils/hash"
3 "github.com/ChefBingbong/viem-go/utils/signature"
4)
5
6// Keccak256 hash
7h := hash.Keccak256([]byte("hello"))
8fmt.Printf("Hash: 0x%x\n", h)
9
10// Hash a message for signing (EIP-191)
11messageHash := signature.HashMessage("hello world")
12fmt.Printf("Message Hash: 0x%x\n", messageHash)
13
14// Recover address from signature
15address, _ := signature.RecoverMessageAddress("hello world", sig)
16fmt.Printf("Recovered: %s\n", address)

Real-world (Advanced): UniswapV2 extractor in Go

These snippets are cherry-picked from the Go implementation in viem-go-extractor-demo — a real UniswapV2 pool extractor that heavily exercises multicall batching, concurrent fan-out, reorg-aware log watching, and on-disk caching.

1// mini-extractor-go/extractor/univ2_extractor.go
2// Batch thousands of getReserves calls via Multicall3.
3func (ext *UniV2Extractor) batchGetReserves(ctx context.Context, addresses []common.Address) map[string][2]*big.Int {
4pairABI := univ2pair.MustParsedABI()
5results := make(map[string][2]*big.Int)
6
7for i := 0; i < len(addresses); i += multicallBatchSize {
8 end := i + multicallBatchSize
9 if end > len(addresses) {
10 end = len(addresses)
11 }
12 chunk := addresses[i:end]
13
14 contracts := make([]public.MulticallContract, len(chunk))
15 for j, addr := range chunk {
16 contracts[j] = public.MulticallContract{
17 Address: addr,
18 ABI: pairABI,
19 FunctionName: "getReserves",
20 }
21 }
22
23 mcResults, err := public.Multicall(ctx, ext.client, public.MulticallParameters{
24 Contracts: contracts,
25 AllowFailure: boolPtr(true),
26 })
27 if err != nil {
28 lib.ExtractorError("batchGetReserves multicall error", "error", err)
29 continue
30 }
31
32 for j, r := range mcResults {
33 addrL := strings.ToLower(chunk[j].Hex())
34 if r.Status == "success" {
35 if vals, ok := r.Result.([]any); ok && len(vals) >= 2 {
36 r0, _ := vals[0].(*big.Int)
37 r1, _ := vals[1].(*big.Int)
38 if r0 != nil && r1 != nil {
39 results[addrL] = [2]*big.Int{r0, r1}
40 }
41 }
42 }
43 }
44}
45return results
46}