# 如何存储私钥
在确保私钥安全的情况下,为了更好的体验,我们需要让钱包把私钥存储起来。给用户更好的体验感。Geth是将私钥通过加密技术转换为json格式的文件,这个文件虽然是明文的,但是解析它的时候需要密码,否则将无法解密。
在Geth中,使用`("password")`,password就是密码。在keystore的文件中,我们可以看到一些关键元素。
- Address:账户地址信息
- Crypto:加密算法部分
```
1、Cipher:对称加密
2、Kdf:密钥生成函数
3、Mac:验证密码的代码
```
- ID:uuid,系统内的唯一标识
- Version:版本号
## 定义hdkeystore包和结构
自定义一个HDkeystore结构体
```go
//HDkeystore使用的并非是私钥,它也是一个结构体,内部包含私钥
type HDkeyStore struct {
keysDirPath string //文件所在路径
scryptN int //生成加密文件的参数N
scryptP int //生成加密文件的参数P
Key //keystore对应的key
}
type Key struct{
Id
Address
PrivateKey *
}
```
## 生成UUID
借助rand加密包,生成uuid
```go
type UUID []byte
//全局加密随机阅读器
var rander =
//生成UUID
func NewRandom() UUID {
uuid := make([]byte, 16)
(, uuid)
//版本4规范处理与变形
uuid[6] = (uuid[6] & 0x0f) | 0x40
uuid[8] = (uuid[8] & 0x3f) | 0x80
return uuid
}
```
## 编写HDkeystore构造函数
面向对象编程的通用思想
```go
//给出一个生成HDkeyStore对象的方法,通过privatekey生成
func NewHDkeyStore(path string, privateKey *) *HDkeyStore {
//获得UUID
uuid := []byte(NewRandom())
key := {
Id: uuid,
Address: (), //地址信息
PrivateKey: privateKey, //私钥信息
}
return &HDkeyStore{
keysDirPath: path,
scryptN: , //固定参数
scryptP: , //固定参数
Key: key,
}
}
```
## 写入文件实现
Keystore实际上是以太坊的一个接口,内部定义的三个方法都需要实现
### 实现StoreKey方法
存储key值
```go
//存储key为keystore文件
//StoreKey
func (ks HDkeyStore) StoreKey(filename string, key *, auth string) error {
//编码key为json
keyjson, err := (key, auth, , )
if err != nil {
return err
}
//写入文件
return WriteKeyFile(filename, keyjson)
}
```
### 实现JoinPath方法
用于路径和文件拼接
```go
func (ks HDkeyStore) JoinPath(filename string) string {
//如果filename是绝对路径,则直接返回
if (filename) {
return filename
}
//将路径与文件拼接
return (, filename)
}
```
### 实现GetKey方法
keystore文件解析,形成私钥信息
```go
//解析key
func (ks *HDkeyStore) GetKey(addr , filename, auth string) (*, error) {
//读取文件内容
keyjson, err := (filename)
if err != nil {
return nil, err
}
//利用以太坊DecryptKey解码json文件
key, err := (keyjson, auth)
if err != nil {
return nil, err
}
// 如果地址不同代表解析失败
if != addr {
return nil, ("key content mismatch: have account %x, want %x", , addr)
}
= *key
return key, nil
}
```