书接上回,前文介绍了命令行钱包如何创建和导入助记词,本文将介绍如何从助记词生成私钥。

key命令

key命令主要用于从助记词生成私钥、导入私钥、罗列出所有私钥。

// keyCmd 定义了一个用于管理密钥的命令,包括创建、列出、导入和导出密钥
func (c *WalletCommand) keyCmd() *cobra.Command {
	keyCmd := &cobra.Command{
		Use:   "key",
		Short: "Manage key",
		Long:  "Manage key, including create, list",
	}

	keyCmd.AddCommand(c.keyCreateCmd())
	keyCmd.AddCommand(c.keyListCmd())
	keyCmd.AddCommand(c.importKeyCmd())
	return keyCmd
}

// keyCreateCmd 定义了一个用于创建新密钥的命令
func (c *WalletCommand) keyCreateCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "create",
		Short: "Create a new key, example: ./wallet key create ./key.key password network account address_index",
		Long:  "Create a new key, example: ./wallet key create ./key.key password network account address_index",
		RunE:  c.runKeyCreateCmd,
	}
}

// runKeyCreateCmd 执行创建新密钥的命令
// 此代码段负责创建一个密钥,并将其存储在本地存储中。
// 首先,它会检查主密钥是否已经存在,如果不存在,则加载助记词并生成主密钥。
// 然后,解析账户和地址索引,并从主密钥派生子密钥。
// 接着,将子密钥转换为WIF格式,并使用AES加密算法对其进行加密。
// 最后,将加密后的密钥保存到本地存储中,并输出成功信息。
func (c *WalletCommand) runKeyCreateCmd(cmd *cobra.Command, args []string) error {
	fmt.Println("key create")
	if c.masterKey == nil {
		err := c.runLoadMnemonic(cmd, args)
		if err != nil {
			return errors.Wrap(err, "load mnemonic failed")
		}
		masterKey, err := c.genMasterKey(args[1], args[2])
		if err != nil {
			return errors.Wrap(err, "generate master key failed")
		}
		c.masterKey = masterKey
	}

    // 解析账户和地址索引
	account, err := strconv.ParseUint(args[3], 10, 64)
	if err != nil {
		return errors.Wrap(err, "parse account failed")
	}

	addressIndex, err := strconv.ParseUint(args[4], 10, 64)
	if err != nil {
		return errors.Wrap(err, "parse address index failed")
	}

    // 从主密钥派生子密钥
	child, err := kms.DeriveChildKey(c.masterKey, 0, uint32(account), uint32(addressIndex))
	if err != nil {
		return errors.Wrap(err, "derive child key failed")
	}
    // 将子密钥转换为WIF格式
	wif, err := kms.GetWIFFromExtendedKey(child, args[2])
	if err != nil {
		return errors.Wrap(err, "get wif failed")
	}
	fmt.Println("wif: ", wif.String())

    // 使用AES加密算法对秘钥进行加密并存入本地存储
	store := storage.NewLocalStorage(args[0])
	encryptedKey, err := utils.AesEncrypt([]byte(wif.String()), args[1])
	if err != nil {
		return errors.Wrap(err, "encrypt key failed")
	}
	err = store.SaveKey(encryptedKey)
	if err != nil {
		return errors.Wrap(err, "save key failed")
	}
	fmt.Println("key created successfully")
	return nil
}

// keyListCmd 定义了一个用于列出所有密钥的命令
func (c *WalletCommand) keyListCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "list",
		Short: "List all keys, example: ./wallet key list ./key.key password",
		Long:  "List all keys, example: ./wallet key list ./key.key password",
		RunE:  c.runListKeys,
	}
}

// runListKeys 执行列出所有密钥的命令
func (c *WalletCommand) runListKeys(cmd *cobra.Command, args []string) error {
	fmt.Println("key list")
	store := storage.NewLocalStorage(args[0])
    // 解密并输出所有密钥
	keys, err := store.ListKeys()
	if err != nil {
		return errors.Wrap(err, "list keys failed")
	}
	for _, key := range keys {
		decryptedKey, err := utils.AesDecrypt(key, args[1])
		if err != nil {
			return errors.Wrap(err, "decrypt key failed")
		}
		fmt.Println("key: ", string(decryptedKey))
	}
	return nil
}

// importKeyCmd 定义了一个用于导入密钥的命令
func (c *WalletCommand) importKeyCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "import",
		Short: "Import a key, example: ./wallet key import ./key.key password wif",
		Long:  "Import a key, example: ./wallet key import ./key.key password wif",
		RunE:  c.runImportKeyCmd,
	}
}

// runImportKeyCmd 执行导入密钥的命令
func (c *WalletCommand) runImportKeyCmd(cmd *cobra.Command, args []string) error {
	fmt.Println("key import")
	store := storage.NewLocalStorage(args[0])
	encryptedKey, err := utils.AesEncrypt([]byte(args[2]), args[1])
	if err != nil {
		return errors.Wrap(err, "encrypt key failed")
	}
	err = store.SaveKey(encryptedKey)
	if err != nil {
		return errors.Wrap(err, "save key failed")
	}
	fmt.Println("key created successfully")
	return nil
}

操作示例

下面是key命令的简单操作示例:

# 查看 key 命令细节
$ ./btc_wallet key                      
Manage key, including create, list

Usage:
  wallet key [command]

Available Commands:
  create      Create a new key, example: ./wallet key create ./key.key password network account address_index
  import      Import a key, example: ./wallet key import ./key.key wif
  list        List all keys, example: ./wallet key list ./key.key password

Flags:
  -h, --help   help for key

Use "wallet key [command] --help" for more information about a command.

# 创建私钥,password为助记词的加密秘钥;network为网络类型,可选项为 testnet 和 mainnet;account为账户索引,address_index为地址索引
$ ./btc_wallet key create ./key.key 1b983738b1d41babaf955276 testnet 0 0
key create
Your mnemonic is:  deliver punch march control clump expand extend awake relax galaxy another this oval patch coyote seed attack mimic gauge sponsor top drama print safe
wif:  L3qkjKBSc2exZbwZQS2h2DUnL1VRhF94hKmSitVR6MJ1QMGwL7eE
key created successfully

$ ./btc_wallet key create ./key.key 1b983738b1d41babaf955276 testnet 0 1
key create
Your mnemonic is:  deliver punch march control clump expand extend awake relax galaxy another this oval patch coyote seed attack mimic gauge sponsor top drama print safe
wif:  Kwj3hosFzS8rF6CJePY8EZcngpr6MR9Z8nomKuK7cscgeajgePVh
key created successfully
$ ./btc_wallet key create ./key.key 1b983738b1d41babaf955276 testnet 1 0
key create
Your mnemonic is:  deliver punch march control clump expand extend awake relax galaxy another this oval patch coyote seed attack mimic gauge sponsor top drama print safe
wif:  KwKyWaLNqXyDDyC2oHB1EyvNUJ3hHHkNpDKRU3ptGZmW71LEiaig
key created successfully

# 列出所有私钥
$ ./btc_wallet key list ./key.key 1b983738b1d41babaf955276        
key list
key:  L3qkjKBSc2exZbwZQS2h2DUnL1VRhF94hKmSitVR6MJ1QMGwL7eE
key:  Kwj3hosFzS8rF6CJePY8EZcngpr6MR9Z8nomKuK7cscgeajgePVh
key:  KwKyWaLNqXyDDyC2oHB1EyvNUJ3hHHkNpDKRU3ptGZmW71LEiaig

孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特