前面的几篇文章主要是介绍了一些btc的基础知识,现在我们可以开发自己的btc钱包了。本文是系列文章的第六篇,主要介绍助记词命令,包括创建并保存助记词、导入助记词。

钱包主入口

下面主要介绍下命令行钱包的主入口:

// WalletCommand 结构体表示钱包命令,包含命令名称、助记词以及根命令
type WalletCommand struct {
	name     string
	mnemonic string

	rootCmd *cobra.Command
}

// NewWalletCommand 函数创建并初始化一个新的 WalletCommand 实例
func NewWalletCommand(name string) *WalletCommand {
	c := &WalletCommand{
		name: strings.ToLower(name),
	}
	c.init()
	return c
}

// init 方法初始化 WalletCommand 的根命令及其子命令
func (c *WalletCommand) init() {
	c.rootCmd = &cobra.Command{
		Use:   cmdName,
		Short: longName,
		Args:  cobra.MinimumNArgs(1),
	}

	// mnemonics subcommand
	c.rootCmd.AddCommand(c.mnemonicCmd())
}

// Execute 方法执行 WalletCommand 的根命令
func (c *WalletCommand) Execute() error {
	return c.rootCmd.Execute()
}

WalletCommand 结构体包含钱包命令的名称、助记词以及根命令。NewWalletCommand 函数创建并初始化一个新的 WalletCommand 实例,并初始化其根命令及其子命令。Execute 方法执行 WalletCommand 的根命令。

助记词命令

上面介绍了钱包命令的主入口,接下来介绍助记词子命令。助记词子命令主要用来创建并保存助记词、导入助记词。

// mnemonicCmd 方法定义了一个用于管理助记词的命令,该命令包含创建和加载助记词的子命令。
func (c *WalletCommand) mnemonicCmd() *cobra.Command {
	genMnemonicCmd := &cobra.Command{
		Use:   "mnemonic",
		Short: "Manage mnemonic",
		Long:  "Manage mnemonic",
	}

	genMnemonicCmd.AddCommand(c.createMnemonic())
	// genMnemonicCmd.AddCommand(c.saveMnemonic())
	genMnemonicCmd.AddCommand(c.loadMnemonic())

	return genMnemonicCmd
}

// createMnemonic 方法定义了一个创建新助记词的命令,该命令会生成一个新的助记词并保存到文件中。
func (c *WalletCommand) createMnemonic() *cobra.Command {
	return &cobra.Command{
		Use:   "create",
		Short: "Create a new mnemonic and save it to file",
		Long:  `Create a new mnemonic and save it to file, example: ./wallet mnemonic create ./mnemonic.txt password
		The password is optional, if not provided, the program will generate a random password.`,
		RunE:  c.runCreateMnemonic,
	}
}

// loadMnemonic 方法定义了一个从文件加载助记词的命令。
func (c *WalletCommand) loadMnemonic() *cobra.Command {
	return &cobra.Command{
		Use:   "load",
		Short: "Load a mnemonic from file",
		Long:  "Load a mnemonic from file",
		RunE:  c.runLoadMnemonic,
	}
}

// runCreateMnemonic 方法实现了创建新助记词的逻辑,包括生成助记词和保存助记词到文件。
func (c *WalletCommand) runCreateMnemonic(cmd *cobra.Command, args []string) error {
	fmt.Println("Create a new mnemonic")
	if len(args) < 1 {
		return errors.New("Please provide the file path to save the mnemonic, e.g. ./mnemonic.txt password")
	}

	mnemonic, err := kms.GenMnemonic()
	if err != nil {
		return errors.Wrap(err, "generate mnemonic failed")
	}

	fmt.Println("Your new mnemonic is: ", mnemonic)
	c.mnemonic = mnemonic

	return c.runSaveMnemonic(cmd, args)
}

// runSaveMnemonic 方法实现了保存助记词到文件的逻辑,包括加密助记词和保存加密后的内容到文件。
func (c *WalletCommand) runSaveMnemonic(cmd *cobra.Command, args []string) error {
	store := storage.NewLocalStorage(args[0])
	var password string
	var err error

	if len(args) == 2 {
		password = args[1]
	} else {
		password, err = utils.CreatePassphrase(12)
		if err != nil {
			return errors.Wrap(err, "create password failed")
		}
	}
	// encrypt the mnemonic with password
	encryptedMnemonic, err := utils.AesEncrypt([]byte(c.mnemonic), password)
	if err != nil {
		return errors.Wrap(err, "encrypt mnemonic failed")
	}
	// save the mnemonic to file
	err = store.Save(encryptedMnemonic)
	if err != nil {
		return errors.Wrap(err, "save mnemonic failed")
	}

	fmt.Println("Your mnemonic is saved to file with password: ", password)
	return nil
}

// runLoadMnemonic 方法实现了从文件加载助记词的逻辑,包括从文件读取加密的助记词和解密助记词。
func (c *WalletCommand) runLoadMnemonic(cmd *cobra.Command, args []string) error {
	if len(args) < 2 {
		return errors.New("Please provide the file path and password")
	}

	store := storage.NewLocalStorage(args[0])
	encryptedMnemonic, err := store.Load()
	if err != nil {
		return errors.Wrap(err, "load mnemonic failed")
	}

	// decrypt the mnemonic with password
	mnemonic, err := utils.AesDecrypt(encryptedMnemonic, args[1])
	if err != nil {
		return errors.Wrap(err, "decrypt mnemonic failed")
	}

	c.mnemonic = string(mnemonic)
	fmt.Println("Your mnemonic is: ", c.mnemonic)
	return nil
}

mnemonicCmd 方法定义了一个用于管理助记词的命令,该命令包含创建和加载助记词的子命令。createMnemonic 方法定义了一个创建新助记词的命令,该命令会生成一个新的助记词并保存到文件中。loadMnemonic 方法定义了一个从文件加载助记词的命令。

项目完整代码在这里

操作示例

下面是助记词命令的简单操作示例:

# 创建助记词并保存到文件,密码是可选的,如果不提供密码,程序会生成一个随机密码。
$ ./btc_wallet mnemonic create ./mnemonic.txt 
Create a new mnemonic
Your new mnemonic is:  divorce oyster guess skull vivid cabbage pulse world whisper yard benefit veteran fancy round post loud base lab head accident light noise frequent hurt
Your mnemonic is saved to file with password:  4e3095ba55a2a07cda6765cd

# 从文件加载助记词,密码是必需的。
$ ./btc_wallet mnemonic load ./mnemonic.key 4e3095ba55a2a07cda6765cd
Your mnemonic is:  divorce oyster guess skull vivid cabbage pulse world whisper yard benefit veteran fancy round post loud base lab head accident light noise frequent hurt

孟斯特

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

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

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