2. go语言从零实现以太坊客户端-查询区块链账户余额

go语言从零实现以太坊客户端-查询区块链账户余额

  • [1. 环境配置和合约代码](#1. 环境配置和合约代码)
  • [2. 编写调试代码](#2. 编写调试代码)
    • [2.1 基类,用于初始化常量](#2.1 基类,用于初始化常量)
    • [2.2 核心业务类](#2.2 核心业务类)
    • [2.3 JSON-RPC库](#2.3 JSON-RPC库)
    • [2.4 装饰器](#2.4 装饰器)
    • [2.5 工具类](#2.5 工具类)
    • [2.6 主函数](#2.6 主函数)
  • [3. 测试](#3. 测试)
    • [3.1 hardhat node节点](#3.1 hardhat node节点)
    • [3.2 sepolia节点](#3.2 sepolia节点)

代码链接

1. 环境配置和合约代码

参考文章12. Hardhat编写、编译、部署、测试Solidity ERC20合约 - 进阶篇 - Metamask导入代币,转账ETH,转账代币

GoLand 2025.2.4版本

go 1.25.4

2. 编写调试代码

可连接hardhat node本地网络和sepolia测试网络

为了突出业务逻辑,省略了错误处理。

2.1 基类,用于初始化常量

后面文章中的类均继承BaseService类

clike 复制代码
package service

import "client/utils/jsonrpc"

type BaseService struct {
	url          string
	contractAddr string
	from         string
	to           string
	privateKey   string
	chainID      uint64
}

func (this *BaseService) Init() {
	this.url = "http://localhost:8545"
	this.contractAddr = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
	// hardhat 默认账户地址1
	this.from = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
	// hardhat 默认账户地址2
	this.to = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
	this.privateKey = 你自己的私钥
	this.chainID = uint64(1337)

	//this.url = "https://ethereum-sepolia-rpc.publicnode.com"
	//this.contractAddr = "0x451Dc02Cee616361815253C858Df0a3028c42901"
	//// sepolia 账户地址1
	//this.from = "0xc312c07abEb8246510412a7ce87A295E0ceC5D48"
	//// sepolia 账户地址1
	//this.to = "0xE78Ff27498c9a6Fd8BC3ff8170Ecf9a13ECBE49e"
	//this.privateKey = 你自己的私钥
	//this.chainID = uint64(11155111)

	//this.url = "https://webhook.site/fc1b1d2d-7dcd-4a2a-b653-16d8f2b9de0e"
	jsonrpc.InitJsonRPCClient(this.url)
}

2.2 核心业务类

继承基类。查询区块链ID和账户余额

//go:decor decorator.LogJsonRPC是装饰器,用来做返回值类型转换。以太坊JSON-RPC返回的数据是十六进制字符串,要转换为对应的类型

clike 复制代码
package service

import (
	_ "client/domain/decorator"
	"client/utils/jsonrpc"

	_ "github.com/dengsgo/go-decorator/decor"
)

//go:decor decorator.LogJsonRPC
type BlockChainRead struct {
	BaseService
}

func (this *BlockChainRead) GetChainID() interface{} {
	return jsonrpc.SendJsonRPC("eth_chainId")
}

// GetBalance
// DATA, 20 Bytes - address to check for balance.
// QUANTITY|TAG - integer block number, or the string "latest", "earliest", "pending", "safe", or "finalized", see the block parameter
// params: ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]
func (this *BlockChainRead) GetBalance() interface{} {
	return jsonrpc.SendJsonRPC("eth_getBalance", this.from, "latest")
}

2.3 JSON-RPC库

使用JSON-RPC库github.com/ybbus/jsonrpc/v3,组装

clike 复制代码
{
	jsonrpc: '2.0',
	method: "eth_getBalance"
	params: [this.from, "latest"]
	id: 1
}
clike 复制代码
package jsonrpc

import (
	_ "client/domain/decorator"
	"context"

	_ "github.com/dengsgo/go-decorator/decor"
	"github.com/ybbus/jsonrpc/v3"
)

var JsonRPCClient jsonrpc.RPCClient

func InitJsonRPCClient(url string) {
	JsonRPCClient = jsonrpc.NewClient(url)
}

func SendJsonRPC(funcName string, params ...interface{}) interface{} {

	var rsp interface{}
	err := JsonRPCClient.CallFor(context.Background(), &rsp, funcName, params)
	if err != nil {
		panic(err)
	}
	return rsp
}

2.4 装饰器

以太坊的JSON-RPC返回的值是十六进制字符串,需要转换为对应的类型。为了分离非业务代码和业务代码,架构层面分层清晰,这里统一使用装饰器做返回值转换,这里选择了"github.com/dengsgo/go-decorator/decor"开源框架,只需要在被装饰的类上加//go:decor decorator.LogJsonRPC即可。

clike 复制代码
package decorator

import (
	"client/utils"

	"github.com/dengsgo/go-decorator/decor"
)

func LogJsonRPC(ctx *decor.Context) {
	if ctx.Func != nil {
		ctx.Func()
		if ctx.TargetOut == nil || len(ctx.TargetOut) == 0 {
			return
		}

		ctx.TargetOut[0] = utils.HexStrToInt(ctx.TargetOut[0].(string))

	}
}

2.5 工具类

工具类

clike 复制代码
package utils

import (
	"math/big"
	"strings"
)

func HexStrToInt(hexStr string) *big.Int {

	data, _ := new(big.Int).SetString(strings.TrimPrefix(hexStr, "0x"), 16)
	return data
}

2.6 主函数

clike 复制代码
package main

import (
	"fmt"

	"client/ethereum.client.blockchain/service"
)

func main() {
	blockchainRead()
}

func blockchainRead() {
	blockChainRead := service.BlockChainRead{}
	blockChainRead.Init()
	id := blockChainRead.GetChainID()
	balance := blockChainRead.GetBalance()
	fmt.Println(id, balance)
}

3. 测试

3.1 hardhat node节点

3.2 sepolia节点

代码链接

相关推荐
Data_agent2 小时前
Python 编程实战:函数与模块化编程及内置模块探索
开发语言·python
new_zhou2 小时前
vs2019+qt工程中生成dump文件及调试
开发语言·qt·visual studio·dump调试
栈与堆2 小时前
LeetCode 19 - 删除链表的倒数第N个节点
java·开发语言·数据结构·python·算法·leetcode·链表
一路向北·重庆分伦2 小时前
03-01:MQ常见问题梳理
java·开发语言
txinyu的博客2 小时前
结合游戏场景理解,互斥锁,读写锁,自旋锁,CAS / 原子变量,分段锁
开发语言·c++·游戏
阿里嘎多学长3 小时前
2026-01-11 GitHub 热点项目精选
开发语言·程序员·github·代码托管
yuanyikangkang3 小时前
STM32 lin控制盒
开发语言
txinyu的博客3 小时前
HTTP服务实现用户级窗口限流
开发语言·c++·分布式·网络协议·http