主页 > imtoken国内怎么下 > 使用测试币体验Bitcoin Core冷钱包离线签名新功能

使用测试币体验Bitcoin Core冷钱包离线签名新功能

imtoken国内怎么下 2023-01-17 09:38:59

冷热钱包分离其实并不是一个新概念。

简单地说,冷端和热端分为两个设备。

热端网络根本不包含私钥。 它负责同步区块链账本,监控钱包中的余额和交易记录,同时负责生成接收地址,生成未签名的交易,然后在冷端对交易进行签名后广播交易。 .

冷端自始至终不联网,负责私钥(包括助记词)的生成和使用; 对于热端通过的未签名交易,由冷端负责校验和签名。

这样私钥就可以自始至终“不上网”,冷热端可以使用二维码等不直接联网的方式传递交易数据。

不过Bitcoin Core作为最“官方”的比特币全节点钱包,在图形界面上一直不支持这个功能——其实Bitcoin Core也不是不能,只是必须要折腾,一般来说就是折腾命令OK,处理listunspent、createrawtransaction、decoderrawtransaction、signrawtransactionwithkey、senddrawtransaction等JSON-RPC命令显然很繁琐,容易出现人为错误。

还有一个论坛朋友速录,以前发过教程,里面折腾命令行的成分比较少,但是如果我没理解错的话,他的方法还是很麻烦的:需要用移动硬盘来将数百GB的block文件从热端电脑复制到冷端电脑,然后在冷端电脑上“一次性”使用这么多block文件,低速删除用完后格式化。

除了麻烦之外,我还经常用其他姿势批评这种方法:地址被重复使用,理论上对隐私不利; 操作过程中没有花掉的币会默认换成新生成的地址(显然这个新地址的私钥之前没有备份过),如果不注意这一点,很容易引出经典的“寻找零丢币”杯子……

我也给论坛里的朋友建议过,可以使用Bither、Electrum等已经完全支持冷热分离的钱包(而且Electrum仍然可以使用Electrum Personal Server来连接Bitcoin Core全节点),但是貌似很多人无论如何都不愿意相信它。 这些是“非官方”钱包软件。

现在,Bitcoin Core已经在主线中加入了对输出描述符(output descriptors)和PSBT(这是近几年开发者提出的一种未签名交易的标准格式)等新特性的支持,虽然新版本还没有正式发布,但我们还是可以直接从开源代码编译,早点体验。

编译好的exe呢,不好意思,我就不贴了。

一方面,发送附件有点麻烦; 另一方面,由于还没有正式发布,最好等code review和测试差不多完成,稳定到可以支持日常使用。

所以,这里我也是用测试网的测试币,就算去掉(不是)也没有损失。

如果没有自己编译过bitcoin-qt.exe,可以直接跳到第三部分开始阅读。

第1部分:生成助记词和助记词对应的HD主公钥/主私钥

第一部分的三个步骤应该是在冷端Bitcoin Core中完成的。

步骤1和2,按理说钱包应该可以直接导入(或生成)BIP39助记词,然后钱包自己可以从助记词中推导出主私钥、主公钥、地址等; 但是Bitcoin Core目前还不支持BIP39助记词,只能借助外部工具来完成。

第三步,我好像没找到什么办法,只能直接用SQLite数据库浏览器打开新版SQLite格式的wallet.dat。

总之,因为Bitcoin Core不支持BIP39助记词,所以在这方面还不够傻。

使用 Ian Coleman 的 BIP39 工具生成 BIP39 助记词:

婴儿小号 upset kid globe domain adapt tool keen turtle rebuild twin

在BIP32 Root Key中可以看到这个助记词对应的BIP32根节点的主私钥:

tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

这里使用测试网,所以“Coin”这里要选择BTC-Bitcoin Testnet,然后可以显示tprv开头的测试网主私钥(否则默认是xprv开头的主网主私钥,不能导入到测试网络钱包中)。

原则上,拿到主私钥后,就可以导入冷端钱包了。

在“派生路径”下选择BIP32,为Client选择自定义派生路径,然后在“BIP32派生路径”中输入派生接收地址主公钥的路径:

米/84'/0'/0'/0

获取接收地址的主公钥:

tpubDF1pTMBKbF1DdzgG6Vy5AJymAG4NUNytiv12g26HwkHr7zuFRSj93SzmrgbWitc1a3vMR8MKa7KwR8fCCPNb6Xg1kFjKpqhudSUhBkXum6C

然后,在BIP32 Derivation Path中输入变更地址主公钥的导出路径:

米/84'/0'/0'/1

获取找零地址的主公钥:

tpubDF1pTMBKbF1DerRsx3DSrX1s8AqMhS2wro9qvpP49o7MqUCsCies9Z58i5gvyzWUedTVFQHiJnRZKWLYtKi​​DDuXo1UcBPRKB6fonSXZiGjf

(这里使用BIP84规定的标准推导路径生成Bech32原生隔离见证地址)

原则上,拿到主公钥后,就可以导入热端钱包了。

第二部分:创建和设置钱包

以测试网模式启动最新编译的比特币核心作为热端:

bitcoin-qt.exe -testnet -datadir=D:\Bitcoin\data

因为这只是一个测试,为了方便,我不会在另一台真正离线的机器上启动冷端Bitcoin Core,而是在同一台机器上启动,但是这次更改数据目录,并使其不连接到比特币P2P网络(所以区块当然不会同步),模拟离线情况:

bitcoin-qt.exe -testnet -datadir=D:\Bitcoin\data-cold -networkactive=0

可以看到热端Bitcoin Core同步了区块(右下角是一个勾,因为我已经同步完成了);

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

冷端不会同步,会显示从零开始的进度条,不会消失:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

而且大家也可以看到,新版Bitcoin Core不会再自动创建默认钱包了。

离线签名btc冷钱包_btc钱包注册_向btc钱包充值

在冷端,点击“文件”菜单,选择“创建钱包”。

它是否加密并不重要。 我这里选择不加密(实际上如果开启加密,地址和交易信息都不会加密,只会加密私钥);

“禁用私钥”留空,不勾选;

应勾选“创建空白钱包”;

应检查“Descriptor Wallet”。

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

同样,在热点方面,需要创建一个钱包。 不同的是需要在热端勾选“Disable private key”。

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

第7、8、10、11、12步是折腾命令行比较麻烦的步骤。 在Bither、Electrum等其他支持冷热分离的钱包中,扫一扫二维码是简单傻瓜操作。

Bitcoin Core目前在这方面还算不上傻瓜,有点折腾,但也应该看到基本功能已经实现,扫一扫已经是傻瓜化的“最后一公里”了代码。

如果这里还有难点,可能是钱包信息导入/导出的格式可能还需要标准化——PSBT已经标准化了未签名的交易,所以钱包实际上可以“混搭”。 如果钱包信息的导入/导出 导出也可以标准化,更容易混搭。

在冷端创建钱包后,点击冷端的“Window”菜单,选择“Console”。 因为在Bitcoin Core中使用输出描述符(output descriptors)导入HD主密钥时,必须提供校验和(checksum),所以这里先使用getdescriptorinfo命令计算校验和。

首先获取HD根节点的主私钥,

tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4

重写为输出描述符格式。 先在以tprv开头的主私钥后加上接收地址的HD推导路径/84'/0'/0'/0/*,变为:

tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/0/*

(星号*表示一个范围内有多个子私钥,这里默认是从0号子私钥开始,也就是第一个接收地址)

然后用wpkh()把它包围起来,表示这些子私钥会生成Bech32原生隔离见证地址(而不是其他类型的地址),变成:

wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/0/*)

这是接收地址的输出描述符。

最后,使用 getdescriptorinfo 命令计算其校验和:

getdescriptorinfo“wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/0/*)”

btc钱包注册_离线签名btc冷钱包_向btc钱包充值

(这里就不发图了,帖子已经很长了)命令执行后,可以看到结果中有一行"checksum": "fy95gzqr",然后我们可以加上数字符号# 到校验和,并将其更改为:

wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/0/*)#fy95gzqr

现在我们只有冷端的接收地址,我们需要做同样的事情来获取找零地址。 改地址的HD推导路径为/84'/0'/0'/1/*离线签名btc冷钱包,不同的是最后的0改成了1,加上校验码后为:

wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/1/*)#csq44hsm

上一步我们将HD根节点的主私钥重写成输出描述符的格式(并添加了校验和),指定地址类型为Bech32,并指定了两条HD推导路径,分别用于Generate payment和change地址。

现在,使用 importdescriptors 命令,您可以将收据和零钱的两个输出描述符(本质上是私钥)导入到冷端钱包中。

导入接收地址的输出描述符:

importdescriptors "[{\"desc\":\"wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/0/*)#fy95gzqr\",\"active\":true,\"timestamp\":\" now\",\"internal\":false,\"label\":\"BIP39-84-account0-receiving\"}]"

导入更改地址的输出描述符:

importdescriptors "[{\"desc\":\"wpkh(tprv8ZgxMBicQKsPeBuxB4sxhkKmXwRSQVqrtCvaQz2CSExKWXhiAcBTezRNV8mb6Dus61Lo64o6kTrp2sSZgmK2cP17gR8Pcb8nEp5DcKLEVG4/84'/0'/0'/1/*)#csq44hsm\",\"active\":true,\"timestamp\":\"现在\",\"内部\":true}]"

现在冷端钱包已经可以生成接收地址了。 回到钱包主界面,切换到“接收”选项卡,点击“新建支付地址”按钮,生成测试网支付地址tb1qtu0ualg6jk9l7h7fkzsjcjfxajlyzmlckx9gfa。

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

网上有很多测试网水龙头,可以索取测试币,楼主就是用这个地址索取测试币的。

回到冷端的控制台,输入以下命令:

获取地址信息 tb1qtu0ualg6jk9l7h7fkzsjcjfxajlyzmlckx9gfa

可以看到返回的结果中也包含了输出描述符信息:

“desc”:“wpkh([702ee02c/84'/0'/0'/0/0]0269343479a77090536f7425b6c079ab799584c8178b27b3d90418007504fcab38)#0rewm4x6”

但是这里只显示这个地址的公钥,没有显示HD主公钥。 我们只取方括号中的[702ee02c/84'/0'/0'/0/0]部分,描述这个地址的来源,我们复制出来。 其中离线签名btc冷钱包,702ee02c为HD根节点主私钥指纹。

冷钱包现已设置。 现在您可以设置热端。

与冷端类似,我们也需要先使用getdescriptorinfo命令计算校验和。

我们这里要带的不是tprv开头的高清主私钥,而是两个tpub开头的高清主公钥。

以接收地址的HD主公钥为例:

向btc钱包充值_离线签名btc冷钱包_btc钱包注册

tpubDF1pTMBKbF1DdzgG6Vy5AJymAG4NUNytiv12g26HwkHr7zuFRSj93SzmrgbWitc1a3vMR8MKa7KwR8fCCPNb6Xg1kFjKpqhudSUhBkXum6C

在前面加上[702ee02c/84'/0'/0'/0](也就是之前在冷端看到的地址推导源信息,删掉最后一个/0,因为这里描述的是主公钥,主公钥显然在地址的上层),然后在其后加上推导路径/*,最后用wpkh()括起来:

wpkh([702ee02c/84'/0'/0'/0]tpubDF1pTMBKbF1DdzgG6Vy5AJymAG4NUNytiv12g26HwkHr7zuFRSj93SzmrgbWitc1a3vMR8MKa7KwR8fCCPNb6Xg1kFjKpqhudSUhBkXum6C)/*

使用此输出描述符通过 getdescriptorinfo 命令计算校验和:

getdescriptorinfo "wpkh([702ee02c/84'/0'/0'/0]tpubDF1pTMBKbF1DdzgG6Vy5AJymAG4NUNytiv12g26HwkHr7zuFRSj93SzmrgbWitc1a3vMR8MKa7KwR8fCCPNb6Xg1kFjKpqhud)6

获取校验码c8zgl83l。 有了验证码,我们就可以导入进去了。

在热端Bitcoin Core的“Window”菜单中选择“Console”,打开命令行控制台,输入:

importdescriptors "[{\"desc\":\"wpkh([702ee02c/84'/0'/0'/0]tpubDF1pTMBKbF1DdzgG6Vy5AJymAG4NUNytiv12g26HwkHr7zuFRSj93SzmrgbWitc1a3vMR8MKa7KwR8fCCPNb6Xg1kFjKpqhudSUhBkXum6C/*)#c8zgl83l\",\"active\":true,\"timestamp\" :\"now\",\"internal\":false,\"label\":\"BIP39-84-account0-receiving\"}]"

这样就把支付地址的HD主公钥导入到热端。

同理,也可以导入变更地址的HD主公钥:

importdescriptors "[{\"desc\":\"wpkh([702ee02c/84'/0'/0'/1]tpubDF1pTMBKbF1DerRsx3DSrX1s8AqMhS2wro9qvpP49o7MqUCsCies9Z58i5gvyzWUedTVFQHiJnRZKWLYtKi​​DDuXo1UcBPRKB6fonSXZiGjf/*)#f79wwrk7\",\"active\":true,\"timestamp\" :\"现在\",\"内部\":true}]"

好了,现在冷端和热端都设置好了。 这是令人兴奋的 -

第 3 部分:(模拟)离线冷签名

这里为了操作方便,我在同一台机器上同时运行冷端和热端,所以只能称之为模拟离线冷签名。 但显然,整个操作也可以在两台真正冷热分离的不同机器上完成。

可以看到,热端同步完块后,可以看到交易记录; 冷端不与网络同步,当然支付暂时看不到,冷端也不需要看到。 这不是冷端的分工。

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

而且,没有私钥的热端也可以创建一个新的支付地址(这个地址也是HD生成的,归根结底是BIP39助记词衍生出来的):

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

只是之前我们使用冷端生成支付地址来接收测试网水龙头的测试币。

貌似Bitcoin Core不允许消费零确认收据,需要至少等待1个区块确认后才能消费。 既然水龙头的测试币已经收到了,在热端的“发送”选项卡上,我们输入一个地址(这里是测试网水龙头的测试币回收地址),试试看如何使用线下冷签名发送刚收到的测试币花费币:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

点击“Create Unsigned Transaction”,出现3秒确认操作窗口:

btc钱包注册_向btc钱包充值_离线签名btc冷钱包

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

等待3秒后,点击“Create Unsigned”,弹窗提示未签名交易(标准PSBT格式)已创建并复制到剪贴板(用记事本粘贴,可以看到是Base64编码),并询问我们是否保存到文件:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

可以想象,这笔Base64编码的PSBT未签名交易可以通过二维码等方式在冷端和热端之间传递。 只是为了测试方便,这里我选择“Discard”,不保存到文件,只使用剪贴板。 (我试过存成文件,得到的PSBT文件是二进制格式的,但是不知道为什么,冷端加载不出来,加载的时候会报错。如果要保存,可以在记事本中粘贴,将Base64编码的PSBT数据保存起来)

不过,有一件事要说,二维码的数据容量也是有限的。 单个二维码只能容纳不到 4KB 的内容。 如果交易内容太大,单个二维码将容纳不下,所以如何解决似乎也没有定论。 (Bita解决这个问题的方法是拆分成多个二维码)。

现在回到冷端,在“文件”菜单中选择“从剪贴板加载PSBT”,读取刚刚从剪贴板生成的未签名的PSBT交易数据。

对话框中绿色突出显示的文本提示用户可以在此处签署此未签名的 PSBT 交易(冷端)。 目的地地址和金额等重要信息也显示在下方:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

请务必核对数据,确认无误后,点击“Sign Tx”按钮对交易进行签名。

然后在对话框中,绿色高亮文字提示用户:签名完成:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

但显然冷端没有联网,不能广播交易,所以点击“复制到剪贴板”按钮,将已签名的PSBT交易复制到剪贴板,这样就可以传给热端了。

交易已签署。 现在回到热端,在“文件”菜单中选择“从剪贴板加载PSBT”,这次是从剪贴板加载已签名的PSBT交易数据。

在对话框中,绿色高亮文字提醒用户:交易已经完全签署,可以广播:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

你还在等什么? 点击“Broadcast Tx”按钮,交易将广播到比特币P2P网络,等待矿工打包确认。

绿色高亮文字提示用户:广播成功,显示交易的TXID:

向btc钱包充值_btc钱包注册_离线签名btc冷钱包

啊,终于,这个测试终于完成了。

可见,目前Bitcoin Core虽然要设置钱包(使用BIP39助记词的HD钱包),但还是比较麻烦,需要折腾命令行;

不过大家应该也能看出来,这个测试之所以显得麻烦,主要是因为使用了HD钱包,每次转入/转出币都会改变新的地址,而不是重复使用单一的私钥。

撇开钱包设置的链接不说,离线签名的链接已经很简单很傻了——我之前也想达到同样的目的,但是不得不折腾listunspent、createrawtransaction、decoderrawtransaction、signrawtransactionwithkey、sendrawtransaction等等,还有很多命令,使用HD钱包会比较麻烦——在支持“输出描述符”之前,Bitcoin Core的HD默认只能硬推。 也就是说,没有办法将HD主公钥导出到热端生成地址,监控钱包金额和交易记录。

据我所知,很多Core开发者都不是很喜欢BIP39……不过,至少有一个不喜欢BIP39的开发者最初提出要扩展输出描述符的功能,加入BIP39支持——虽然这只是一个提议,但也应该是一个非常积极的信号。 所以,让我们拭目以待。