---
概述: 用Go生成以太坊錢包的教程。
---
# 生成新錢包
要首先生成一個新的錢包,我們需要導入go-ethereum`crypto`包,該包提供用于生成隨機私鑰的`GenerateKey`方法。
```go
privateKey, err := crypto.GenerateKey()
if err != nil {
log.Fatal(err)
}
```
然后我們可以通過導入golang`crypto/ecdsa`包并使用`FromECDSA`方法將其轉換為字節。
```go
privateKeyBytes := crypto.FromECDSA(privateKey)
```
我們現在可以使用go-ethereum`hexutil`包將它轉換為十六進制字符串,該包提供了一個帶有字節切片的`Encode`方法。 然后我們在十六進制編碼之后刪除“0x”。
```go
fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) // fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19
```
這就是用于簽署交易的私鑰,將被視為密碼,永遠不應該被共享給別人,因為誰擁有它可以訪問你的所有資產。
由于公鑰是從私鑰派生的,因此go-ethereum的加密私鑰具有一個返回公鑰的`Public`方法。
```go
publicKey := privateKey.Public()
```
將其轉換為十六進制的過程與我們使用轉化私鑰的過程類似。 我們剝離了`0x`和前2個字符`04`,它始終是EC前綴,不是必需的。
```go
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
}
publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) // 9a7df67f79246283fdc93af76d4f8cdd62c4886e8cd870944e817dd0b97934fdd7719d0810951e03418205868a5c1b40b192451367f28e0088dd75e15de40c05
```
現在我們擁有公鑰,就可以輕松生成你經常看到的公共地址。 為了做到這一點,go-ethereum加密包有一個`PubkeyToAddress`方法,它接受一個ECDSA公鑰,并返回公共地址。
```go
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
fmt.Println(address) // 0x96216849c49358B10257cb55b28eA603c874b05E
```
公共地址其實就是公鑰的Keccak-256哈希,然后我們取最后40個字符(20個字節)并用“0x”作為前綴。 以下是使用go-ethereum的`crypto/sha3` Keccak256函數手動完成的方法。
```go
hash := sha3.NewKeccak256()
hash.Write(publicKeyBytes[1:])
fmt.Println(hexutil.Encode(hash.Sum(nil)[12:])) // 0x96216849c49358b10257cb55b28ea603c874b05e
```
---
### 完整代碼
```go
package main
import (
"crypto/ecdsa"
"fmt"
"log"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
)
func main() {
privateKey, err := crypto.GenerateKey()
if err != nil {
log.Fatal(err)
}
privateKeyBytes := crypto.FromECDSA(privateKey)
fmt.Println(hexutil.Encode(privateKeyBytes)[2:]) // 0xfad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
}
publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
fmt.Println(hexutil.Encode(publicKeyBytes)[4:]) // 0x049a7df67f79246283fdc93af76d4f8cdd62c4886e8cd870944e817dd0b97934fdd7719d0810951e03418205868a5c1b40b192451367f28e0088dd75e15de40c05
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
fmt.Println(address) // 0x96216849c49358B10257cb55b28eA603c874b05E
hash := sha3.NewKeccak256()
hash.Write(publicKeyBytes[1:])
fmt.Println(hexutil.Encode(hash.Sum(nil)[12:])) // 0x96216849c49358b10257cb55b28ea603c874b05e
}
```
- 客戶端
- 創建客戶端
- 以太坊賬戶
- 賬戶余額
- 賬戶代幣余額
- 生成新錢包
- 密匙庫
- 硬件錢包
- 地址驗證
- 交易
- 查詢區塊
- 查詢交易
- ETH轉賬
- 代幣轉賬
- 監聽新區塊
- 創建裸交易
- 發送裸交易
- 智能合約
- 智能合約 & ABI
- 部署智能合約
- 加載智能合約
- 查詢智能合約
- 寫入智能合約
- 讀取智能合約二進制碼
- 查詢ERC20代幣智能合約
- 事件日志
- 監聽事件日志
- 讀取時間日志
- 讀取ERC20代幣的事件日志
- 讀取0x Protocol事件日志
- 簽名
- 生成簽名
- 驗證簽名
- 測試
- 發幣龍頭
- 使用模擬客戶端
- Swarm存儲
- 創建 Swarm存儲
- 上傳文件到Swarm
- 從Swarm下載文件
- Whisper通信協議
- 創建Whisper客戶端
- 生成Whisper密匙對
- 在Whisper上發送消息
- 監聽Whisper消息
- 工具
- 工具集合
- 專有詞匯表
- 資源