作者:Isilva01
来源:https://github.com/bitcoin/bitcoin/blob/master/doc/managing-wallets.md
编者注:Bitcoin Core 软件一向搭配了钱包功能模块,但在其版本迭代过程中,存储钱包信息(私钥、地址)的文件格式发生了许多变化。
与我们特别相关的是,自 2020 年末发布的 Bitcoin Core 0.21 版本以来,Bitcoin Core 一直支持两种钱包格式,一种是所谓的 “传统钱包(legacy wallet)”,另一种是所谓的 “描述符钱包” ;并且,自那以来,开发者就一直在逐步地移除对第一种钱包格式地支持;到了 2025 年 10 月发布的 Bitcoin Core 30.0 版本,移除工作完成,传统钱包不再受到支持。
- 关于这个逐步移除过程的计划及实现的细节,可见这个 Issue 页面:https://github.com/bitcoin/bitcoin/issues/20160
- 关于描述符钱包对比传统钱包的优势,可见:https://achow101.com/2020/10/0.21-wallets
本文是 Bitcoin Core 的使用说明书之一,介绍了如何在 Bitcoin Core 中生成、备份、复原钱包以及变更钱包格式(从传统钱包迁移为描述符钱包)。
从 2022 年初发布的 23.0 版本及以后版本中,Bitcoin Core 默认创建描述符钱包,因此,如果你的钱包是在 23.0 及以后版本创建的,那么你可能无需变更钱包格式,更新 Bitcoin Core 软件版本不会影响你的使用;反之,如果你的钱包是在较旧版本中创建的,那么你可能需要在 30.0 以前的版本中,将它变更为描述符钱包,才能确保钱包的功能不受软件更新的影响。
1. 备份与恢复钱包
1.1 创建钱包
自 0.21 版本以来,Bitcoin Core 不再于初次启动时默认生成一个钱包。钱包可以用在命令行界面中用 createwallet RPC 命令来创建,也可以在图形界面(Bitcoin Core GUI)中使用 Create wallet(“创建钱包”)菜单选项来创建。
在图形界面中,如果软件当前还未加载任何钱包,那么 Create a new wallet(“创建一个新钱包”)会显示在主界面上。此外,可以在菜单栏的 “文件” 按钮进入这个功能(File ->Create wallet)。
举个例子,下面这行命令会创建一个描述符钱包。关于这条命令的更多信息,可通过运行 bitcoin-cli help createwallet 命令获得。
(译者注:在 23.0 版本及以后版本中,Bitcoin Core 默认创建描述符钱包;但在此前,此命令会创建传统钱包。)
bitcoin-cli createwallet "wallet-01"
bitcoin-cli 也可以替换成 bitcoin rpc。
默认情况下,所生成的钱包文件会放置在 Bitcoin Core 数据目录的 wallets 文件夹中。至于这个数据目录,其位置会因为操作系统的不同而不同,如下表所示。用户还可以使用 -datadir 或 -walletdir 启动参数来分别改变数据目录和钱包目录的位置。
(译者注:在配置文件中使用 datadir= 条目也是改变数据目录位置的常用方法。)
| 操作系统 | 默认钱包目录 |
|---|---|
| Linux | /home/<user>/.bitcoin/wallets |
| Windows | C:\Users\<user>\AppData\Local\Bitcoin\wallets |
| macOS | /Users/<user>/Library/Application Support/Bitcoin/wallets |
1.2 加密钱包
默认情况下,上述命令所生成的 wallet.dat 钱包文件是未加密的,因此,只要攻击者能够访问保存该钱包文件或其备份的设备,它就会曝光。
钱包加密可以放置未经授权的访问。然而,它也极大地提升了因为忘记密语(译者注:passphrase,俗语称为 “密码”)而丢失资金的风险。密语是无法找回的。用户应该自己想清楚这其中的取舍。
钱包加密同样可能无法抵御更加复杂的攻击。比如,(如果攻击者能摸到你的电脑),攻击者可以在你的电脑上安装一个键盘记录软件(keylogger),从而获得你的密语。
给钱包加密或者变更了密语之后,你需要立即创建一个新的备份。原因在于,钱包加密之后,就会刷新密钥池(keypool)、创建一个新的层级式确定性钱包种子(HD seed)。任何使用新种子(所生成的地址)收到的比特币都无法从老备份中复原出来。
使用这样一行命令,就可以给钱包的私钥加密:
bitcoin-cli -rpcwallet="wallet-01" encryptwallet "passphrase"
加密之后,可以通过 walletpassphrasechange 命令来改变密语:
bitcoin-cli -rpcwallet="wallet-01" walletpassphrasechange "oldpassphrase" "newpassphrase"
在上述两条命令中,-rpcwallet 后面接的是需要加密的钱包的名称。
只有钱包的私钥会被加密。所有其它的钱包信息,比如交易,依然是可见的。
也可以在创建钱包的同一时间就给钱包的私钥加密,通过 passphrase 参数:
bitcoin-cli -named createwallet wallet_name="wallet-01" passphrase="passphrase"
再次提醒,如果你弄丢了密语,钱包中所有的资金都会永久丢失。
1.3 解锁钱包
如果钱包加密了,那么当用户尝试任何跟私钥相关的操作(比如发送比特币)时,都可能遇上这样的报错消息:
bitcoin-cli -rpcwallet="wallet-01" sendtoaddress "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx" 0.01
error code: -13
error message:
Error: Please enter the wallet passphrase with walletpassphrase first.
(这条消息的意思是:你需要先输入钱包的密语以解锁钱包。)
为了解锁这个钱包并许可运行这些跟私钥相关的操作,你需要 walletpassphrase RPC 命令。
这条命令会接收密语以及一个叫做 timeout(“超时时间”)的参数,该参数指定了将钱包解密密钥存储在内存中的时间(以秒计)。在这段时间过后,你就需要再次输入密语。
bitcoin-cli -rpcwallet="wallet-01" walletpassphrase "passphrase" 120
在图形界面中,没有哪一个菜单选项是用来解锁钱包的。每当用户要发送比特币的时候,软件都会自动弹出窗口来要求用户输入口令。
1.4 备份钱包
要备份钱包,必须使用 backupwallet PRC 命令或者图形界面的 Backup Wallet(“备份钱包”)选项,以保证在你复制文件时,它已处于安全状态。
在这个命令中,副本目的地参数必须包含文件名,否则,这行命令可能会返回一条报错消息,类似于 “ Error: Wallet backup failed! ”(“错误:钱包备份失败!”)。
bitcoin-cli -rpcwallet="wallet-01" backupwallet /home/node01/Backups/backup-01.dat
在图形界面中,可通过右上角的 Wallet(“菜单”)下拉菜单来选择要备份的钱包。如果这个列表没出现,那么说明你需要先加载钱包,办法是在菜单栏的 “文件” 菜单中选择 “打开钱包”(File ->Open Wallet)。然后,可通过 “文件” 菜单的 “备份钱包” 选项来备份(File -> Backup Wallet…)。
这个备份文件可以存储在一个或多个断网设备中,并且这样的设备必须在能在紧急情况下可靠地运行,还要保证没有感染恶意软件。备份好了之后,还要定期测试备份文件,以避免出现问题。
如果计算机感染了恶意软件,它可能会在你从备份文件复原钱包时攻陷钱包。尽可能降低这种风险的一种办法是不让备份文件连接到一个联网的设备。
如果因为某些原因,一个钱包以及它所有的备份都弄丢了,那么跟这个钱包相关的比特币就永远无法找回了。
1.5 备份的频率
最初的 Bitcoin Core 钱包只是一系列不相关私钥的集合。在这种非层级式确定性钱包(non-HD wallet)中,每当你使用一个新的(还未备份过的)地址来收款,都必须立即备份。否则,使用以往的备份来复原钱包就会丢失资金,因为(以往的备份不包含这个地址,同时又)没有确定性机制来找回这个地址。
Bitcoin Core 0.13 版本引入了带有确定性密钥派生的 HD 钱包。有了 HD 钱包,用户就不会再因为使用旧备份来复原钱包而弄丢资金了,因为所有地址都是从同一个 HD 钱包种子中派生出来的。
这意味着一个备份就足以找回任何时间收到的资金。但是,依然推荐定期备份(比如每周一次),或者在收到许多新交易之后就备份一次,以便为备份及时更新元数据(比如交易的标签)。这些元数据是无法通过区块链扫描来找回的,所以如果备份太老了(一直没更新),这些元数据就会永远丢失。
在 0.13 版本以前的 Bitcoin Core 软件中创建的钱包不是 HD 钱包,因此必须每使用 100 新个密钥就备份一次;若要保护元数据,还必须更加频繁。
(译者注:使用新密钥的必要性在于不重复使用相同的地址,从而增强隐私性。)
1.6 从备份文件中复原钱包
要复原钱包时,必须使用 restorewallet RPC 选项或者图形界面的 Restore Wallet(“复原钱包”)菜单选项(File -> Restore Wallet…)。
bitcoin-cli restorewallet "restored-wallet" /home/node01/Backups/backup-01.dat
然后,使用 getwalletinfo 来检查钱包是否已经完全复原。
bitcoin-cli -rpcwallet="restored-wallet" getwalletinfo
在图形界面中,复原好的钱包也可以通过 “文件” - “打开钱包”( File ->Open wallet)来加载。
钱包密语
理解钱包的安全性对于安全地保管你的比特币是极为关键的。一个关键的方面就是钱包密语,它是用来加密的。我们来探究它的细微之处、作用、加密过程以及局限性。
- 并非种子:钱包的密语与种子(seed)是钱包安全性的两个独立组件。种子,也叫 “HD 种子”,是一个主密钥 ,用于按照层级式确定性(HD)钱包的方法来派生私钥和公钥。相反,密钥是一个额外的安全层,专门设计为保护钱包中的私钥。密钥是一种保护措施,要求通过额外的一层验证才能访问钱包中的资金。
- 阻止未经许可的访问:密语是一种保护措施,在一个未经许可的用户触及你的已经解锁的电脑或设备(且该设备运行着你的钱包应用)时,保护你的资金。如果他们不知道你的密语,就无法使用你的钱包中的资金(无法发起交易)。然而,要注意的是,如果他们能给你的电脑安排键盘记录器,就有可能打破密语这一层安全性。
- 并不加密元数据和公钥:值得提醒的是,密语主要用于保护私钥(也就是对钱包资金的使用权)。它并不加密跟交易有关的元数据,也不加密公钥。关于你的交易历史和公钥的信息,即使加密了钱包,也依然是可见的。
- 如果忘记或丢失,可能弄丢资金:如果钱包的密语过于复杂、并且日后忘记了或弄丢了,就有永远失去这些资金的使用权的风险。忘记密语会导致你无法解锁你的钱包、使用其中的资金。
将传统钱包迁移为描述符钱包
使用 migratewallet RPC 命令,就可以将 “Legacy wallet(传统的、不基于描述符的钱包)” 迁移成 “描述符钱包”。这将把原钱包中的所有地址和私钥添加到一个新创建的描述符钱包中(只是名称与原钱包的名称一样)。因为描述符钱包不支持既有私钥、又有 “仅观察(watch-only)” 的地址(脚本),所以迁移操作可能会创建最多两个额外的钱包。除了使用相同名称的一个描述符钱包,可能还会有一个名称为 <name>_watchonly 的钱包,以及一个名为 <name>_solvables 的钱包。 <name>_watchonly 包含了所有的仅观察地址。而 <name>_solvables 则包含了钱包知道、但并未监控其对应的 P2(W)SH 脚本的任何脚本。如果原本的传统钱包只包含仅观察地址,不包含私钥,就只有 <name>_watchonly 会被创建、并且使用相同名称的描述符不会被创建出来。此外,创建出来的仅观察描述符钱包也将不支持使用私钥。
迁移后的钱包可能也会创建出不一样的新地址。虽然会使用相同的 BIP32 种子,但(与传统钱包不同的是,它也)会使用 BIP 44\49\84\86 的标准派生不中。迁移之后,用户需要创建一个(甚至是多个)新的钱包备份。
因为传统钱包可以理解、观察和签名的脚本的配置可能性是非常非常多的,migratewallet 只能尽最大努力来尝试捕捉所有这些可能性。可能会有一些无法预见的配置,导致迁移过程将一些脚本排除在外。如果迁移意外地失败了,或者丢失了任何脚本,请在 GitHub 上创建一个 Issue 来报告这些情形。原钱包的一个备份,会以名为 <name>-<timestamp>.legacy.bak 的文件,出现在钱包目录中。
这个备份可以使用上文 “从备份文件中复原钱包” 章节所述的方法,复原你的原传统钱包。
(完)