在上一篇文章中介绍了如何使用钱包来生成私钥,本文将介绍如何发送btc交易。

balance命令

在发送btcjsonrpc交易之前,我们需要先获取指定地址的余额。钱包提供了balance命令来查看余额。

// balanceCmd 命令主入口
func (c *WalletCommand) balanceCmd() *cobra.Command {
	balanceCmd := &cobra.Command{
		Use:   "balance",
		Short: "Get the balance of the wallet",
		Long:  "Get the balance of the wallet",
	}
	balanceCmd.AddCommand(c.getBalanceCmd())
	return balanceCmd
}

// getBalanceCmd 获取余额命令
func (c *WalletCommand) getBalanceCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "get",
		Short: "Get the balance of the wallet",
		Long:  "Get the balance of the wallet, example: ./wallet balance network[testnet|mainnet] address",
		RunE:  c.runGetBalanceCmd,
	}
}

// runGetBalanceCmd 执行获取余额命令
func (c *WalletCommand) runGetBalanceCmd(cmd *cobra.Command, args []string) error {
	fmt.Println("get balance")

	utxos, err := getUTXOs(args[1], args[0])
	if err != nil {
		return errors.Wrap(err, "get utxos failed")
	}
	balance := 0.0
	for _, utxo := range utxos {
		balance += utxo.Amount
	}
	fmt.Printf("Address: %s Balance: %.9f BTC\n", args[1], balance)
	return nil
}

tx命令

知道了余额之后,我们就可以发送交易了。钱包提供了tx命令来发送交易。

// txCmd 命令主入口
func (c *WalletCommand) txCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "tx",
		Short: "Transaction operations",
		Long:  "Transaction operations",
	}
	cmd.AddCommand(c.sendCmd())
	return cmd
}

// sendCmd 发送交易命令
func (c *WalletCommand) sendCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "send",
		Short: "Send bitcoins, example: ./wallet tx send ./key.key password network from to amount(Satoshi)",
		Long:  "Send bitcoins, example: ./wallet tx send ./key.key password network from to amount(Satoshi)",
		RunE:  c.runSendCmd,
	}
}

// runSendCmd 执行发送交易命令
func (c *WalletCommand) runSendCmd(cmd *cobra.Command, args []string) error {
	fmt.Println("send btc")
	var wif *btcutil.WIF
	var err error

	// 验证from地址是否存在于钱包中
	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.BIP38Decrypt(key, args[1], args[2])
		if err != nil {
			return errors.Wrap(err, "decrypt key failed")
		}
		wif, err = btcutil.DecodeWIF(string(decryptedKey))
		if err != nil {
			return errors.Wrap(err, "decode wif failed")
		}
		addr, err := address.NewBTCAddressFromWIF(wif).GenBech32Address(utils.GetNetwork(args[2]))
		if err != nil {
			return errors.Wrap(err, "generate bech32 address failed")
		}
		if addr == args[3] {
			break
		}
	}
	if wif == nil {
		return errors.New("from address not found")
	}

    
	amount, err := strconv.ParseInt(args[5], 10, 64)
	if err != nil {
		return errors.Wrap(err, "parse account failed")
	}
	// 构建交易输出
	txOut, _, err := buildTxOut(args[4], args[2],amount)
	if err != nil {
		return errors.Wrap(err, "build tx out failed")
	}

	// 构建交易输入
	msgTx,err := buildTxIn(wif, amount, txOut, args[2])
	if err != nil {
		return errors.Wrap(err, "build tx in failed")
	}

	// 发送交易
	txHash,err := client.SendRawTransaction(msgTx,false)
	if err != nil {
		return errors.Wrap(err, "send raw transaction failed")
	}

	fmt.Println("txHash:",txHash)

	return nil
}

项目完整代码在这里

操作示例

# 通过钱包查询指定地址的余额
$ ./btc_wallet balance
Get the balance of the wallet

Usage:
  wallet balance [command]

Available Commands:
  get         Get the balance of the wallet

Flags:
  -h, --help   help for balance

Use "wallet balance [command] --help" for more information about a command.
$ ./btc_wallet balance get testnet tb1q2a6ear6hk2lyk7502kq65j0dx40jh6qv6lu8qh
get balance
Address: tb1q2a6ear6hk2lyk7502kq65j0dx40jh6qv6lu8qh Balance: 0.010000000 BTC

# tx命令
./btc_wallet tx 
Transaction operations

Usage:
  wallet tx [command]

Available Commands:
  send        Send bitcoins, example: ./wallet tx send ./key.key password network from to amount

Flags:
  -h, --help   help for tx

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

$ ./btc_wallet tx send ./key.key password testnet tb1q2a6ear6hk2lyk7502kq65j0dx40jh6qv6lu8qh tb1qndsh2mllf8g2hf29svazpxksa3ns4zga3n55mc 980000
send btc
fee: 82
totalInput: 1000000
txHash: a4b098124fc1f8a92ec9dba24ca4a6e64e0e65e1c0e0dede58f0650c4c0dfead

孟斯特

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

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

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