以太坊作为全球领先的智能合约平台,其上的每一笔交易都记录在公开的区块链账本上,对于开发者而言,能够以编程方式查询这些交易信息,是构建区块链应用(如钱包、浏览器、数据分析工具)的核心技能之一,Golang(Go语言)凭借其出色的并发性能、高效的执行效率和简洁的语法,成为了开发区块链应用的理想选择。
本文将详细介绍如何使用Golang来查询以太坊上的交易信息,涵盖从环境搭建、连接节点,到实际查询交易的完整流程。
准备工作:环境与工具
在开始编码之前,我们需要准备以下几项:
-
Go环境:确保你的系统上已安装Go (建议1.15或更高版本)。
-
以太坊节点:查询交易需要连接到一个以太坊节点,你有以下几种选择:
- 本地节点:运行一个全节点(如Geth或Parity),这是最完整但资源消耗最大的方式。
- Infura等第三方服务:Infura提供了公共的以太坊节点API,无需自己维护节点,非常适合开发和测试,你需要在 Infura官网 注册并获取一个项目ID。
- Alchemy等第三方服务:与Infura类似,Alchemy也是一个高性能的区块链节点服务,提供更丰富的开发者工具。
-
以太坊账户地址:你需要查询的交易哈希或发送方/接收方地址。
-
Go-Ethereum库:我们将使用最流行的Go语言以太坊交互库
go-ethereum(也称为geth)。
在你的Go项目目录中初始化模块并安装go-ethereum:
go mod init eth-query-example go get github.com/ethereum/go-ethereum
连接到以太坊网络
所有操作的第一步是建立一个与以太坊网络的连接,无论是连接到本地节点还是远程节点(如Infura),我们都需要使用ethclient包。
下面是一个连接到Infura节点的示例代码:
package main
import (
"context"
"fmt"
"log"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
// 替换成你自己的Infura项目ID
infuraURL := "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID"
// 创建一个以太坊客户端
client, err := ethclient.Dial(infuraURL)
if err != nil {
log.Fatalf("Failed to connect to the Ethereum network: %v", err)
}
defer client.Close()
// 验证连接是否成功
chainID, err := client.NetworkID(context.Background())
if err != nil {
log.Fatalf("Failed to get network ID: %v", err)
}
fmt.Printf("Successfully connected to network with Chain ID: %s\n", chainID)
}
将 YOUR_INFURA_PROJECT_ID 替换为你在Infura上获取的真实ID,运行此代码,如果看到成功信息,说明你已经成功连接到以太坊主网。
核心查询操作
连接建立后,我们就可以开始查询交易了。go-ethereum的ethclient提供了丰富的API。
根据交易哈希查询交易详情
这是最直接的方式,如果你已经知道一笔特定交易的哈希,可以获取其完整信息,包括发送方、接收方、金额、Gas消耗、日志等。
// 假设client已经成功连接
txHash := "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060" // 示例交易哈希
tx, _, err := client.TransactionByHash(context.Background(), common.HexToHash(txHash))
if err != nil {
log.Fatalf("Failed to get transaction: %v", err)
}
fmt.Printf("Tx Hash: %s\n", tx.Hash().Hex())
fmt.Printf("Nonce: %d\n", tx.Nonce())
fmt.Printf("To: %s\n", tx.To().Hex())
fmt.Printf("Value: %s ETH\n", new(big.Float).Quo(
new(big.Float).SetInt(tx.Value()),
big.NewFloat(math.Pow10(18)),
)) // 以太坊精度为18,需要转换
fmt.Printf("Gas: %d\n", tx.Gas())
fmt.Printf("Gas Price: %s Gwei\n", new(big.Float).Quo(
new(big.Float).SetInt(tx.GasPrice()),
big.NewFloat(math.Pow10(9)),
)) // Gas Price单位是Gwei (10^9 Wei
根据地址查询交易列表
如果你想查看某个地址(无论是发送方还是接收方)的所有交易历史,可以使用 FilterLogs 或 PendingTransactions