# 如何存储私钥
在确保私钥安全的情况下,为了更好的体验,我们需要让钱包把私钥存储起来。给用户更好的体验感。Geth是将私钥通过加密技术转换为json格式的文件,这个文件虽然是明文的,但是解析它的时候需要密码,否则将无法解密。
在Geth中,使用`personal.newAccount("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 //keystore对应的key
}
type Key struct{
Id uuid.UUID
Address common.Address
PrivateKey *ecdsa.PrivateKey
}
```
## 生成UUID
借助rand加密包,生成uuid
```go
type UUID []byte
//全局加密随机阅读器
var rander = rand.Reader
//生成UUID
func NewRandom() UUID {
uuid := make([]byte, 16)
io.ReadFull(rand.Reader, 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 *ecdsa.PrivateKey) *HDkeyStore {
//获得UUID
uuid := []byte(NewRandom())
key := keystore.Key{
Id: uuid,
Address: crypto.PubkeyToAddress(privateKey.PublicKey), //地址信息
PrivateKey: privateKey, //私钥信息
}
return &HDkeyStore{
keysDirPath: path,
scryptN: keystore.LightScryptN, //固定参数
scryptP: keystore.LightScryptP, //固定参数
Key: key,
}
}
```
## 写入文件实现
Keystore实际上是以太坊的一个接口,内部定义的三个方法都需要实现
### 实现StoreKey方法
存储key值
```go
//存储key为keystore文件
//StoreKey
func (ks HDkeyStore) StoreKey(filename string, key *keystore.Key, auth string) error {
//编码key为json
keyjson, err := keystore.EncryptKey(key, auth, ks.scryptN, ks.scryptP)
if err != nil {
return err
}
//写入文件
return WriteKeyFile(filename, keyjson)
}
```
### 实现JoinPath方法
用于路径和文件拼接
```go
func (ks HDkeyStore) JoinPath(filename string) string {
//如果filename是绝对路径,则直接返回
if filepath.IsAbs(filename) {
return filename
}
//将路径与文件拼接
return filepath.Join(ks.keysDirPath, filename)
}
```
### 实现GetKey方法
keystore文件解析,形成私钥信息
```go
//解析key
func (ks *HDkeyStore) GetKey(addr common.Address, filename, auth string) (*keystore.Key, error) {
//读取文件内容文章来源:https://www.toymoban.com/news/detail-591540.html
keyjson, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
//利用以太坊DecryptKey解码json文件
key, err := keystore.DecryptKey(keyjson, auth)
if err != nil {
return nil, err
}
// 如果地址不同代表解析失败
if key.Address != addr {
return nil, fmt.Errorf("key content mismatch: have account %x, want %x", key.Address, addr)
}
ks.Key = *key
return key, nil
}
```文章来源地址https://www.toymoban.com/news/detail-591540.html
到了这里,关于GO语言-区块链离线钱包开发之如何存储私钥的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!