用Go语言开发以太坊区块链钱包,从零到实战的完整指南
以太坊作为全球第二大区块链平台,其生态应用日益丰富,而钱包作为用户与区块链交互的核心入口,是每个开发者必须掌握的基础设施,Go语言凭借其出色的并发性能、简洁的语法以及以太坊官方客户端Geth本身就是Go编写的事实,成为开发区块链应用的首选语言之一,本文将带你一步步使用Go语言开发一个功能完整的以太坊钱包。
以太坊钱包的核心概念
在动手写代码之前,我们需要理解几个关键概念:
- 私钥(Private Key):256位的随机数,是账户资产的最终控制权,一旦泄露资产将不保。
- 公钥(Public Key):由私钥通过椭圆曲线加密算法(secp256k1)推导而来。
- 地址(Address):公钥经过Keccak-256哈希运算后取后20字节生成,以
0x开头。 - Keystore文件:私钥经密码加密后的JSON文件,是以太坊标准的私钥存储格式。
- 助记词(Mnemonic):遵循BIP-39标准的12/24个单词,可推导出多个私钥。
需要强调的是,钱包本身并不“存储”资产,资产记录在区块链上,钱包管理的只是密钥对。
开发环境搭建
首先初始化项目并安装官方库 go-ethereum:
mkdir eth-wallet && cd eth-wallet go mod init eth-wallet go get github.com/ethereum/go-ethereum
创建钱包:生成密钥对
直接生成私钥
package main
import (
"crypto/ecdsa"
"fmt"
"log"
"github.com/ethereum/go-ethereum/crypto"
)
func main() {
// 生成随机私钥
privateKey, err := crypto.GenerateKey()
if err != nil {
log.Fatal(err)
}
// 从私钥推导公钥
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("公钥类型转换失败")
}
// 由公钥生成以太坊地址
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
fmt.Println("地址:", address)
fmt.Printf("私钥: %x\n", crypto.FromECDSA(privateKey))
}
创建Keystore加密钱包(推荐)
package main
import (
"fmt"
"log"
"github.com/ethereum/go-ethereum/accounts/keystore"
)
func main() {
// 在 ./wallets 目录下创建 Keystore
ks := keystore.NewKeyStore(
"./wallets",
keystore.StandardScryptN,
keystore.StandardScryptP,
)
password := "my-strong-password-123"
account, err := ks.NewAccount(password)
if err != nil {
log.Fatal(err)
}
fmt.Println("新钱包地址:", account.Address.Hex())
}
运行后会在 wallets 目录下生成一个JSON加密文件,这就是Keystore。
导入已有钱包
// 通过私钥导入
privateKey, err := crypto.HexToECDSA("你的私钥十六进制字符串")
if err != nil {
log.Fatal(err)
}
// 通过Keystore文件导入
file, err := os.ReadFile("./wallets/UTC--2024--...")
if err != nil {
log.Fatal(err)
}
key, err := keystore.DecryptKey(file, "钱包密码")
if err != nil {
log.Fatal("密码错误")
}
fmt.Println("导入成功:", key.Address.Hex())
连接以太坊网络并查询余额
通过RPC连接节点(可使用Infura、Alchemy等服务):
package main
import (
"context"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://mainnet.infura.io/v3/你的项目ID")
if err != nil {
log.Fatal("连接失败:", err)
}
defer client.Close()
address := common.HexToAddress("0x钱包地址")
balance, err := client.BalanceAt(context.Background(), address, nil)
if err != nil {
log.Fatal(err)
}
// 将Wei转换为ETH(1 ETH = 10^18 Wei)
ethValue := new(big.Float).Quo(
new(big.Float).SetInt(balance),
big.NewFloat(1e18),
)
fmt.Printf("余额: %v ETH\n", ethValue)
}
实现ETH转账交易
package main
import (
"context"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
client, err := ethclient.Dial("https://sepolia.infura.io/v3/你的项目ID")
if err != nil {
The End
发布于:2026-10-05,除非注明,否则均为原创文章,转载请注明出处。

