在上一篇文章中介绍了如何使用钱包来生成私钥,本文将介绍如何发送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: 恋水无意
腾讯云开发者社区:孟斯特