我将分为两篇文章介绍以太坊钱包,本文是第一篇。
以太坊上有 2 种钱包:
非确定性钱包,也叫随机钱包,每个账户通过独立的随机数生成器创建,使用keystore
管理账户,没有助记词。
分层确定性钱包,也叫HD Wallet,每个账户通过固定的种子(seed)派生,使用助记词
管理所有账户。
本文讲解非确定性钱包
,因为比较简单,下面会直接给出代码实现。下一篇文章会详细讲解分层确定性钱包
,这个已经成为了行业标准,我会重磅介绍,并对比两种钱包的适用场景。
随机数生成器:如Web3专题(一) 助记词和生成私钥、公钥、地址的基本原理所说,私钥是 256 位随机数字,需要使用安全的随机源生成,并经过一系列算法生成公钥、地址。
keystore:是一种文件格式,称为存储机制,主要目的是提供一种安全的方式来保管私钥,需要用户提供密码来解锁私钥。
通常,用 keystore 文件加密私钥等信息,来保护非确定性钱包
。
import (
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
./keystore
文件夹保存账户。特别提醒:
NewKeyStore
方法只会加载目录,并监控目录的变化,不会创建账户,创建账户在下面第 3 步。NewKeyStore
方法内部会自动扫描./keystore
文件夹,并加载这个文件夹下的所有账户到 keystore 对象
// 第一个参数:./keystore 指定账户所在的文件夹
ks := keystore.NewKeyStore("./keystore", keystore.StandardScryptN, keystore.StandardScryptP)
NewAccount
会利用你指定的密码在./keystore
目录下创建一个 json 文件,这个文件包含了加密过的私钥、公钥、地址等。 每执行一次NewAccount
都会创建一个新账户。因此,如果只需要加载已有账户,则不需要执行这个方法。 所有的 json 文件都会存放在./keystore
文件夹。
acc, err := ks.NewAccount("your password")
if err != nil {
panic(err)
}
ks
对象是第2步创建的,会自动扫描./keystore 文件夹
,拿到所有账户。
for _, acc := range ks.Accounts() {
fmt.Println("账户地址:", acc.Address.String())
}
for _, wallet := range ks.Wallets() {
// 这里每个钱包获得的第一个account和上面第4步的账户是一一对应的
_, _ = wallet.SignTx(wallet.Accounts()[0], nil, nil)
_, _ = wallet.SignData(wallet.Accounts()[0], "", nil)
}
PASSWORD
是上面第3步创建新账户设置的密码。// 先把账户的 json 文件导出为[]byte
kjson, err := ks.Export(ks.Accounts()[0], PASSWORD, PASSWORD)
if err != nil {
panic(err.Error())
}
// 通过kjson+密码可以解密私钥
key, err := keystore.DecryptKey(kjson, PASSWORD)
if err != nil {
panic(err.Error())
}
privateKey := key.PrivateKey
fmt.Println(common.BytesToHash(crypto.FromECDSA(privateKey)).String())
至此,我们已经学会了如何使用 Go 语言创建非确定性钱包
。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!