Golang Ethereum教程 完整代码: https://github.com/mazezen/learn/tree/master/01-part-eth-ehereum
动动手指,欢迎点个⭐️
准备
- 注册 INFURA账号,以太坊API和网关服务.会提供需要用的节点地址
- 安装 ganache-cli , 可以在本机跑起来一个本地网络,并提供10个地址和私钥,和用于测试的gas费. 每个地址有100ETH
- 测试网水龙头领取eth sepolia测试币
安装go-ethereum依赖
go get -d github.com/ethereum/go-ethereum/...
教程
1.获取区块高度.
# 连接服务
ethclient.DialContext(context.Background(), url)
if err != nil {
log.Fatalf("failed to connect to infura: %v", err)
}
# 拿高度
client.BlockByNumber(context.Background(), nil)
if err != nil {
log.Fatalf("failed to get block number: %v", err)
}
url: 节点地址.用的哪个网络就填写哪个网络的地址. 比如主网, 测试网,或者使用本地网络节点
2. 获取Address eth余额
ethclient.DialContext(context.Background(), url)
addr := common.HexToAddress("0xD6c57F704B9dBD6b9B9700cc5cD9f0e88C217E7D")
balanceAt, err := client.BalanceAt(context.Background(), addr, nil)
if err != nil {
log.Fatalf("failed to get balance of %v: %v", addr, err)
}
// 单位是WEI
fmt.Println(balanceAt)
// 科学计数表示法
fBalance := new(big.Float)
fBalance.SetString(balanceAt.String())
fmt.Println(fBalance)
value := new(big.Float).Quo(fBalance, big.NewFloat(math.Pow10(18)))
// 单位是eth
fmt.Println(value)
100000000000000000000
1e+20
100
3. 创建地址
// 生成私钥
pvK, err := crypto.GenerateKey()
if err != nil {
log.Fatal(err)
}
ecdsa := crypto.FromECDSA(pvK)
encode := hexutil.Encode(ecdsa)
// 私钥生成公钥
crypto.FromECDSAPub(&pvK.PublicKey)
// 公钥派生出地址
crypto.PubkeyToAddress(pvK.PublicKey).Hex()
4. 创建钱包
key := keystore.NewKeyStore("./wallet", keystore.StandardScryptN, keystore.StandardScryptP)
password := "password"
a, err := key.NewAccount(password)
if err != nil {
log.Fatal(err)
}
fmt.Println(a.Address)
会在生产一个wallet文件夹,存放着钱包的信息
5. 解析钱包,拿到私钥,公钥 和地址
by, err := os.ReadFile("./wallet/file")
if err != nil {
log.Fatalf("failed to read wallet: %v", err)
}
pvk, err := keystore.DecryptKey(by, password)
if err != nil {
log.Fatalf("failed to decrypt key: %v", err)
}
pData := crypto.FromECDSA(pvk.PrivateKey)
fmt.Println(hexutil.Encode(pData))
pData = crypto.FromECDSAPub(&pvk.PrivateKey.PublicKey)
fmt.Println(hexutil.Encode(pData))
fmt.Println(crypto.PubkeyToAddress(pvk.PrivateKey.PublicKey).Hex())
6. 获取地址剩余的eth
ethclient.Dial(url)
if err != nil {
log.Fatal(err)
}
add1 := common.HexToAddress("0x483Df743a6521F2cbd6Ce68Cca1121B95e09679a")
add2 := common.HexToAddress("352da91c8901722f424d00a6e1eba8297074262d")
fmt.Println(add1)
fmt.Println(add2)
balanceAt, err := client.BalanceAt(context.Background(), add1, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(balanceAt.String())
balanceAt, err = client.BalanceAt(context.Background(), add2, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(balanceAt.String())
代码中的两个地址用的是ganache-cli本地网络供的地址. url为本地网络地址 也可以使用第四步,创建钱包.去测试网水龙头领取测试等
7. 交易(Transfer)
// 链接网络
ethclient.Dial(url)
// 获取余额
client.BalanceAt(context.Background(), add1, nil)
client.BalanceAt(context.Background(), add2, nil)
// 拿到nonce
client.PendingNonceAt(context.Background(), add1)
// 拿gas费
client.SuggestGasPrice(context.Background())
// 创建交易数据,交易1个ETH
transaction := types.NewTx(&types.LegacyTx{
Nonce: nonceAt,
GasPrice: gasPrice,
Gas: 21000,
To: &add2,
Value: big.NewInt(1000000000000000000),
})
// 获取chaninID
client.NetworkID(context.Background())
pvkStr := "6ee4e3758996db5d5c3bab59c778c133637d99f7774a49cd831cdb13529a9c60"
privateKey, err := crypto.HexToECDSA(pvkStr)
if err != nil {
log.Fatal(err)
}
tx, err := types.SignTx(transaction, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
log.Fatal(err)
}
fmt.Println(tx.Hash().Hex())
此次交易用的是ganache-cli 跑的本地网络 两个地址用的也是本地网络提供的地址.每个地址有100ETH
完整代码: https://github.com/mazezen/learn/tree/master/01-part-eth-ehereum