#### 1. 安装 Go 环境
首先,确保你的机器上已安装 Go。可以在终端中运行以下命令检查是否已成功安装:
```bash
go version
```
如果还没有安装,可以去 [Go 官方网站](https://golang.org/dl/) 下载并安装。
#### 2. 初始化 Go 项目
在开始之前,我们先创建一个新的 Go 项目。打开终端并输入以下命令:
```bash
mkdir eth-wallet
cd eth-wallet
go mod init eth-wallet
```
这将生成一个新的模块,名字为 `eth-wallet`。
#### 3. 引入必要的库
我们需要两个主要库来与以太坊网络交互,一个是 `go-ethereum`,另一个是 `hex` 用于处理16进制数据。通过以下命令安装这些库:
```bash
go get github.com/ethereum/go-ethereum
```
#### 4. 生成钱包地址
创建一个新的文件 `wallet.go`,我们将在其中编写生成钱包地址的逻辑。
```go
package main
import (
"crypto/ecdsa"
"crypto/rand"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"math/big"
)
func generateWallet() (string, *ecdsa.PrivateKey, error) {
// 生成私钥
priv, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader)
if err != nil {
return "", nil, err
}
// 从私钥导出公钥
pub := priv.Public()
addr := crypto.PubkeyToAddress(*pub.(*ecdsa.PublicKey))
return addr.Hex(), priv, nil
}
func main() {
address, privateKey, err := generateWallet()
if err != nil {
fmt.Println("Error generating wallet:", err)
return
}
fmt.Println("钱包地址:", address)
fmt.Println("私钥:", privateKey.D.String())
}
```
在这段代码中,我们使用 `ecdsa` 生成了一个私钥和对应的公钥,从而得到以太坊地址。执行代码后,你应该能看到你的钱包地址和私钥。
#### 5. 保存钱包信息
在实际应用中,我们不能只在控制台输出私钥。需要将钱包信息保存在安全的地方,如数据库或加密文件。在这里我们简单讲下如何将私钥保存到文件中。
```go
import (
"encoding/json"
"io/ioutil"
"os"
)
type Wallet struct {
Address string
PrivateKey string
}
func saveWallet(wallet Wallet) error {
data, err := json.Marshal(wallet)
if err != nil {
return err
}
// 将文件写入到本地
return ioutil.WriteFile("wallet.json", data, 0644)
}
// 在主函数中调用
err = saveWallet(Wallet{Address: address, PrivateKey: privateKey.D.String()})
if err != nil {
fmt.Println("无法保存钱包:", err)
}
```
通过上述代码,我们将钱包信息保存到 `wallet.json` 文件中,方便后续使用。
#### 6. 发送以太坊
当然,创建一个以太坊钱包最重要的功能之一就是发送以太坊。我们接下来实现一个发送以太坊的简单功能。
```go
import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
)
func sendEth(fromPrivKey string, toAddress string, amount *big.Int) error {
client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")
if err != nil {
return err
}
// 解密私钥
privateKey, err := crypto.HexToECDSA(fromPrivKey)
if err != nil {
return err
}
fromAddress := crypto.PubkeyToAddress(privateKey.PublicKey)
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
return err
}
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
return err
}
to := common.HexToAddress(toAddress)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, nil)
// 签名交易
chainID, err := client.NetworkID(context.Background())
if err != nil {
return err
}
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
return err
}
err = client.SendTransaction(context.Background(), signedTx)
if err != nil {
return err
}
fmt.Println("交易发送成功,txHash:", signedTx.Hash().Hex())
return nil
}
```
在实际应用中,你还需要特定的地址、金额等信息来调用 `sendEth` 函数。确保替换 `YOUR_INFURA_PROJECT_ID` 为你的 Infura 项目 ID。
#### 7. 交易的确认
发送交易后,病要确认交易是否成功。在以太坊上,可以通过查询交易的哈希值来确认。
```go
func checkTxStatus(txHash string) error {
client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")
if err != nil {
return err
}
tx, isPending, err := client.TransactionByHash(context.Background(), common.HexToHash(txHash))
if err != nil {
return err
}
if isPending {
fmt.Println("交易还未确认...")
} else {
fmt.Printf("交易已确认!详情:%v\n", tx)
}
return nil
}
```
这样,我们就能通过交易哈希查询交易状态。在主函数中调用这个函数,传入你之前发送交易后获得的交易哈希即可。
#### 8. 总结
用 Golang 创建以太坊钱包实际上是一个相对简单的过程。虽然在这里我们提供了一个基础的框架,但实际情况中你可能会需要考虑更多的安全性、错误处理、用户体验等问题。通过不断地实践和学习,你将会在这方面越来越熟练。
希望这个简单的示例能帮助你入门到以太坊开发世界。如果有疑问,欢迎随时问我哦!