比特币钱包创建及地址获取

前言
比特币钱包开发中,需要搭建比特币节点来同步交易数据等,并完成转账余额查询等相关操作。本文介绍了比特币节点搭建好之后,在节点服务器上,如何创建账户,如何获取地址的。

比特币的账号是通过bip协议生成种子,然后扩展成多个子地址,这些子地址都由同一个种子可以推导出来,而知道其中一个子账号的私钥不能推导兄弟和父辈节点的私钥,所以将同一个种子扩展生成的子账号统一为一个账号,在每次交易时都可以使用它的新的子地址去交易,这样更安全,也更难追踪,也常常将这个大账号称为钱包。有了大钱包之后,我们就可以创建一系列的钱包地址了。

官网公开的bitcoin-cli 关于钱包的API有53个之多。本文只说明一下bitcoin-cli 常用到的几个命令

1. 创建钱包/CreateWallet

CreateWallet命令参数 创建并加载新钱包。

语法:createwallet "wallet_name" ( disable_private_keys blank )
参数:
    1. "wallet_name"           (字符串,必须项) 钱包名称。如果是路径,将会在指定路径创建钱包。
    2. "disable_private_keys"  (布尔值, 可选项, 缺省值为false) 禁止私钥可能性(这种模式下只有watchonlys可能). 本项一般不用。
    3. "blank"                 (布尔值, 可选项, 缺省值为false) 创建空白钱包。 空白钱包没有私钥也没有HD种子。可以后面用sethdseed来设置。
返回值:
    {
      "name" :    <wallet_name>, (string) 如果创建成功就是钱包名字。路径的情况下显示路径。
      "warning" : <warning>,     (string) 如果钱包没有完好创建会在这里给出警告信息。
    }
例子:
	> bitcoin-cli createwallet "testwallet"
	> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createwallet", "params": ["testwallet"] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

2. 加密钱包/EncryptWallet

encryptwallet调用使用指定的密文加密钱包。该操作只需调用一次,一旦启用加密, 每次需要使用钱包中的密钥时,就需要输入密文。如果在命令行使用这个调用,需要注意你使用的shell可能会保存输入的命令(包括输入 的密文)。另外,一旦钱包启用加密,目前没有其他的RPC接口可以禁用其加密。如果需要一个不加密的钱包,你只能再创建一个新的钱包,然后使用dumpwallet调用的输出来恢复加密钱包中的密钥。

语法:encryptwallet "Passphrase"
参数:
    "Passphrase":用于加密钱包的密文,最短1个字符
返回值:
    encryptwallet 调用将返回一个提醒信息,提示钱包已加密、节点重启。

示例代码:
    下面命令使用密码test加密钱包:
    ~$ bitcoin-cli -testnet encryptwallet "test"
输出如下:
    wallet encrypted; Bitcoin server stopping, restart to run with encrypted
    wallet. The keypool has been flushed, you need to make a new backup.

3. 获取钱包信息/GetWalletInfo

getwalletinfo可以获取账户相关信息。也可以验证前面的加密情况。

语法: getwalletinfo
参数:
	无
返回值:
	getwalletinfo调用返回钱包总体信息,结构如下:
	walletversion:钱包版本
	balance:钱包余额
	txcount:钱包内交易数量
	keypoololdest:密钥池内最早密钥创建时间
	keypoolsize:密钥池大小
	unlocked_until:钱包解锁至何时,仅当钱包加密时有效
示例代码:
	下面的命令返回节点钱包的总体信息:
	~$ bitcoin-cli getwalletinfo
输出结果如下:
{
  "walletname": "",
  "walletversion": 169900,
  "balance": 0.00001,
  "unconfirmed_balance": 0.00000000,
  "immature_balance": 0.00000000,
  "txcount": 7,
  "keypoololdest": 1563790626,
  "keypoolsize": 2000,
  "keypoolsize_hd_internal": 2000,
  "unlocked_until": 0,
  "paytxfee": 0.00000000,
  "hdseedid": "f2ce9cb076bd4d1021a3ba4ed3193573bd....",
  "private_keys_enabled": true
}

4. 生成新地址/getnewaddress

返回用于接收付款的新比特币地址。

语法:getnewaddress ( "label" "address_type" )
参数:
    1. "label" :字符串,可选。要链接到的地址的标签名称,若未指定,默认为空。label可以不存在
    2. "address_type" :字符串,可选。若使用本选项,可用选项为"legacy", "p2sh-segwit","bech32"。默认值为bitcoind运行时-address_type指定的值。
运行结果:
    "address"       #字符串,新的bitcoin地址

5. 获取地址信息/GetAddressInfo

0.17.0之后本方法开始启用。
因地址唯一但账户名可重复,所以一个账户名称对应多个地址现象

语法:getaddressinfo "address"
参数:
	"address": 字符串,必须项。比特币地址。
返回值:
	地址关联信息。
{
  "address" : "address",        (string)验证过的比特币地址
  "scriptPubKey" : "hex",       (string) 地址生成的十六进制编码scriptPubKey
  "ismine" : true|false,        (boolean) 地址是否是你的
  "iswatchonly" : true|false,   (boolean) 地址是watchonly的
  "solvable" : true|false,      (boolean) 我们是否知道如何花费发送到该地址的硬币,忽略可能缺少私钥的情况。
  "desc" : "desc",            (string, optional) 发送至该地址的比特币消费的描述(仅在可解决时)
  "isscript" : true|false,      (boolean) 如果key是脚本
  "ischange" : true|false,      (boolean) 如果该地址用于更改输出
  "iswitness" : true|false,     (boolean) 如果该地址是见证人地址
  "witness_version" : version   (numeric, optional) 见证程序的版本号
  "witness_program" : "hex"     (string, optional) 见证程序的十六进制值
  "script" : "type"             (string, optional) 输出脚本类型。仅在“ isscript”为真且知道重新命名的情况下。可能的类型: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash, witness_v0_scripthash, witness_unknown
  "hex" : "hex",                (string, optional) p2sh地址的兑现脚本
  "pubkeys"                     (string, optional) 与已知兑现脚本关联的公钥数组(仅当“ script”为“ multisig”)
    [		
      "pubkey"		
      ,...		
    ]		
  "sigsrequired" : xxxxx        (numeric, optional) 花费多重签名输出所需的签名数(仅当“脚本”为“多重签名”时)
  "pubkey" : "publickeyhex",    (string, optional) 原始公共密钥的十六进制值,用于单密钥地址(可能嵌入在P2SH或P2WSH中)
  "embedded" : {...},           (object, optional) 如果相关且已知,则为有关嵌入在P2SH或P2WSH中的地址的信息。它包括嵌入式地址的所有getaddressinfo输出字段,但不包括元数据(“ timestamp”,“ hdkeypath”,“ hdseedid”)
  "iscompressed" : true|false,  (boolean, optional) 如果pubkey被压缩
  "label" :  "label"         (string) 与地址关联的标签,“”是默认标签
  "timestamp" : timestamp,      (number, optional) 密钥的创建时间(自纪元开始,以秒为单位)(格林尼治标准时间197011日)
  "hdkeypath" : "keypath"       (string, optional) HD密钥路径(如果密钥是HD且可用)
  "hdseedid" : ""      (string, optional) HD种子的Hash160值
  "hdmasterfingerprint" : "" (string, optional) 万能钥匙的指纹。
  "labels"                      (object) 与地址关联的标签数组。
    [		
      { (json object of label data		
        "name": "labelname" (string) 标签
        "purpose": "string" (string) 地址的用途(“发送”用于发送地址,“接收”用于接收地址)
      },...		
}	

6. 获取余额/getbalance

getbalance调用返回钱包中所有账户(或指定账户)的比特币数量,该调用 需要节点启用钱包功能。

语法:getbalance "Account","Confirmations","WatchOnlyIncl"
参数:
    "Account":要查看余额的钱包账户,可选,默认值为*,表示全部账户
    "Confirmations": 可计入余额的UTXO所需要的最小确认数,可选,默认值:6
    "WatchOnlyIncl": 是否包含那些仅用于跟踪的地址,可选,默认值:true
返回值:
    getbalance调用返回以bitcoin为单位的余额。

示例代码:
下面的命令统计账户test1中包含至少一个确认的UTXO的总金额:
    ~$ bitcoin-cli -testnet getbalance "test1" 1 true
输出结果如下:
    0.00010000

7. 用密码解锁钱包/walletpassphrase

在设置的timeout时间内,将钱包解密密钥存储在内存中。在执行与私钥相关的事务前,这是必须操作。

语法:walletpassphrase "passphrase" timeout
参数:
    "passphrase":字符串,必须项。钱包密码。
    "timeout":数值,必须项。保存解密密钥的时间(以秒为单位)。限制在最多1073741824(2^30)秒。任何大于1073741824秒的值将被设置为1073741824秒。
注意:
    在钱包已经解锁时发出walletpassphrase命令将设置一个新的解锁时间并覆盖旧解锁时间。

比特币节点常用命令

#运行节点(conf参数有默认值,可以省略)
bitcoind -conf=/data/bitcoin/bitcoin.conf -daemon
#停止节点
bitcoin-cli stop
#其它常用命令
bitcoin-cli getnetworkinfo              #查看网络状态
bitcoin-cli getpeerinfo                 #查看网络节点
bitcoin-cli getblockchaininfo           #查看区块链信息:如同步进度
bitcoin-cli help                        #查看所有命令

注:
bitcoin.conf的默认路径如下:

linux:   bitcoin.conf的默认路径为$HOME/.bitcoin/bitcoin.conf
windows: bitcoin.conf的默认路径为%APPDATA%\bitcoin\bitcoin.conf
mac:     bitcoin.conf的默认路径为$HOME/Library/Application Support/Bitcoin/bitcoin.conf

补充1

如果比特币节点上有多个钱包,获取钱包信息的时候,会出现“没有分配钱包文件”的错误信息。如下所示:

ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli getwalletinfo
error code: -19
error message:
Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).
Try adding "-rpcwallet=" option to bitcoin-cli command line.

原因在于,节点上存在多个钱包导致的。可以按照下面的操作,去卸载掉一个钱包。

ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli listwallets
[
  "",
  "mywallet"
]
ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli listwalletdir
{
  "wallets": [
    {
      "name": "mywallet"
    },
    {
      "name": ""
    }
  ]
}
ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli unloadwallet ""
ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli listwallets
[
  "mywallet"
]
ubuntu@xxx:~/bitcoin-0.18.0/bin$ ./bitcoin-cli getwalletinfo
{
  "walletname": "mywallet",
  "walletversion": 169900,
  "balance": 0.00000000,
  "unconfirmed_balance": 0.00000000,
  "immature_balance": 0.00000000,
  "txcount": 0,
  "keypoololdest": 1575551886,
  "keypoolsize": 2000,
  "keypoolsize_hd_internal": 2000,
  "paytxfee": 0.00000000,
  "hdseedid": "f70531cccac5be23c0870d9a84cc02bcf3xxx",
  "private_keys_enabled": true
}

补充2 更换默认比特币钱包

其实比较简单,三步。

  1. 首先停止比特币节点
bitcoin-cli stop
  1. 覆盖默认钱包目录的数据文件
    钱包所在目录为 ~/.bitcoin/wallets。注意做好备份。
ubuntu@xxx:~/.bitcoin$ ls wallets/
database/  db.log  mywallet/  wallet.dat

移动文件,注意做好备份。

cd ~/.bitcoin/wallets
cp mywallet/* .
  1. 重启比特币节点即可
bitcoind -daemon

参考:
6. bitcoin-cli常用命令与描述(官方)
7. 比特币 bitcoin-cli 操作示例
8. 【比特币钱包开发 五】新建钱包:生成子账号地址与路径

你可能感兴趣的:(区块链)