3_balance

command
v0.0.0-...-6e38dd8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2023 License: MIT Imports: 7 Imported by: 0

README

账户余额

上一节已经获取到了以太坊公链的信息,这一节尝试获取某个账户的余额信息。(这里的余额指的是ETH余额,不是ERC-20代币余额。)

查询账户信息不需要私钥,只需要地址即可。地址的类型是common.Address,可以是普通的账户(EOA),也可以是智能合约地址(代币、金库、AA钱包、各种Pool等)。

接口除了接收地址参数以外,还有一个可选参数blockNumber,如果想查询指定区块上的余额,则传入区块号,查询最新余额的话,传入nil

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

返回值balance的单位是Wei,要转换成Ether需要除以1e18,详见https://etherscan.io/unitconverter

需要特别注意的是,账户余额可能是非常大的整数(uint256),极易出现精度损失,所以非必要不转换,在本地最好存储成Wei,以便和链上保持一致。

如果使用标准库的big.Float转换,可以这么做

bf := big.NewFloat(0).SetInt(balance)
bf.Quo(bf, big.NewFloat(1e18)) // 935.1430017

如果使用另一个常用库decimal转换,可以这么做

bd := decimal.RequireFromString(balance.String())
bd = bd.Div(decimal.NewFromFloat(1e18)) // 935.1430017464869741

上述示例中,V神在区块18382246的余额是935143001746486974073 Wei,即935.143001746486974073 Ether,而使用Float转换得到的是935.1430017 Ether,使用Decimal转换后得到的是935.1430017464869741 Ether,都不准确。

完整代码

package main

import (
	"context"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/shopspring/decimal"
	"log"
	"math/big"
	"os"
)

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 with ethclient: %s", err)
	}

	ctx := context.Background()
	addr := common.HexToAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") // vitalik.eth
	bn := big.NewInt(18382246)
	balance, err := client.BalanceAt(ctx, addr, bn) // 935143001746486974073
	if err != nil {
		log.Fatalf("get chainId error: %s", err)
	}
	log.Printf("balance in Wei: %s", balance)
	bf := big.NewFloat(0).SetInt(balance)
	bf.Quo(bf, big.NewFloat(1e18)) // 935.1430017
	log.Printf("balance in Ether (converted by big.Float): %s", bf.String())

	bd := decimal.RequireFromString(balance.String())
	bd = bd.Div(decimal.NewFromFloat(1e18)) // 935.1430017464869741
	log.Printf("balance in Ether (converted decimal.Decimal): %s", bd.String())
}

如果有任何疑问,欢迎留言交流。

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL