8 个版本 (破坏性更改)
0.20.0 | 2021 年 8 月 6 日 |
---|---|
0.19.0 | 2020 年 12 月 23 日 |
0.18.0 | 2020 年 12 月 15 日 |
0.17.0 | 2020 年 12 月 3 日 |
0.13.0 | 2020 年 10 月 14 日 |
#6 在 #cold
225KB
4.5K SLoC
创建 2of2 多签钱包 p2wsh
在以下步骤中,我们将创建一个测试网 2of2 多签钱包并签名并广播一笔交易。需要同步的比特币节点。
在第一步中,我们将创建两个主密钥。
创建第一个主密钥
这一步创建第一个主密钥。 (可以使用骰子创建密钥,请参阅 firma-offline dice --help
)
firma-offline random --key-name a1
{
"id": {
"kind": "MasterSecret",
"name": "a1",
"network": "testnet"
},
"key": "tprv8ZgxMBicQKsPdQsGb1U22Lw7bPwhbxRkV8Q1mf8mv42q6HpJS7MW5hx1J44gKK6m2pQyC32mG1i6v1P9C97MDx7MvKZzgoXTpcwUgTSEobm"
}
我们可以在保存到磁盘之前加密密钥,例如利用现有的 gpg 设置,如下所示
# encryption key creation and storage in encrypted gpg
dd if=/dev/urandom bs=1 count=32 | gpg --encrypt -r 'DEADBEEF!' >encryption_key.gpg
# bitcoin private key creation
gpg --decrypt encryption_key.gpg | firma-offline --encrypt random --key-name a1
在这种情况下,密钥文件 ~/.firma/testnet/keys/a1/master_secret.json
看起来是这样的
{
"t": "encrypted",
"c": {
"t": "base64",
"c": "5Vqdw61WCoxyvl6mj6WBGEPzzI/SCLxwukHbbxCYsQphkPdoGDMaPhLL7Jg7Ok4yJa7E79LiiOSaRcszjnyLH3lfskF3ii2u5qTcacQhmuh5HV8d275hGAoYejY24MU58h/4Mo5A3om6woRpIgABmAEFXGCeTsjgvvXO+iD0EJA2tse+YQJRhMQGYCMeNH7BcrnWrAhhu3eBCsZdt0j5bsrP6aX3DLQIW6uUhsP7nklscGdRstu82+NEkdwonP+hBXBrkFxfe9DCer/x4IbeZF6TGA=="
}
}
在这种情况下,要读取密钥的纯文本
gpg --decrypt encryption_key.gpg | firma-offline --encrypt export --kind MasterSecret --name a1
{
"id": {
"kind": "MasterSecret",
"name": "a1e",
"network": "testnet"
},
"key": "tprv8ZgxMBicQKsPdHXHYrBsowgZXAh1bisk2nxvJLqRakJ9tZDLTLgFSGZDH79bKF19cTkmW8LHV3ZFbRytQAxjXx1MUFrrzpdfxiFcqqfpjkf"
}
注意:如果钱包文件已加密,则需要使用加密密钥对数据进行加密和解密。
创建第二个主密钥
这个密钥是通过提供骰子启动创建的
firma-offline dice --key-name a2 --faces 20 -l 12 -l 11 -l 1 -l 1 -l 16 -l 8 -l 1 -l 12 -l 7 -l 4 -l 12 -l 8 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 18 -l 19 -l 12 -l 1 -l 16 -l 1 -l 18 -l 1 -l 13 -l 1 -l 1 -l 16 -l 4 -l 3 -l 1 -l 1 -l 1 -l 1 -l 1 -l 20 -l 19 -l 18 -l 17 -l 12 -l 2
{
"dice": {
"faces": 20,
"launches": "[12, 11, 1, 1, 16, 8, 1, 12, 7, 4, 12, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 19, 12, 1, 16, 1, 18, 1, 13, 1, 1, 16, 4, 3, 1, 1, 1, 1, 1, 20, 19, 18, 17, 12, 2]",
"value": "33146769803929392242686007705600000000000000300775117168313561497600063822621"
},
"id": {
"kind": "MasterSecret",
"name": "a2",
"network": "testnet"
},
"key": "tprv8ZgxMBicQKsPdGNW7N9EPsGpWBc56L8kKncoZfxC83M5ipBV2fMhujCBnxiTx33HnqiERg6fYsgKVBdSMNKm8nEcESHfUXAUecnyWnrx6Ls"
}
创建 2of2 多签钱包
首次使用 firma-online
工具时,您需要初始化连接参数
firma-online connect --url http://127.0.0.1:8332 --cookie-file $HOME/.bitcoin/.cookie
每次每个网络都需要这样做,并且每次节点配置更改时也是如此。
对于示例,我们使用先前步骤中创建的两个主密钥。从离线机器将 $HOME/.firma/testnet/keys/a1/descriptor_public_key.json
和 $HOME/.firma/testnet/keys/a2/descriptor_public_key.json
复制到在线机器。您可以选择将文件复制到正确的目标目录,或使用 import
命令,这将允许您选择性地加密这些数据。
firma-online create-wallet --wallet-name firma-wallet -r 2 --key-name a1 --key-name a2
{
"created_at_height": 1934912,
"descriptor": "wsh(multi(2,[2f15d226/48'/1'/0'/2']tpubDFHFgFr6HbP88U7grBQ44yvocSU1EGkXX1dArKRum1qvb4Y6hy4CpJuPqpKZSyVnHptf6zoaW4HUjFHXgmtfy2vTGF1fccPy2ioNvKeZUnq/0/*,[7938c502/48'/1'/0'/2']tpubDEJZZGYXbZKMNEWgCdG9XZDycYM19Y8WxNc2cYcxLYhnNvKpbFNkgAza1x4GCUAHLdxx28R6dX88VhjgmZscW8Dzw6pGDzJ8a4gUCqHh1ny/0/*))#jpa3vwyx",
"id": {
"kind": "Wallet",
"name": "firma-wallet",
"network": "testnet"
}
}
使用sign_wallet
命令可以使用参与者密钥之一对钱包文件wallet.json
进行签名,这可以防止攻击者在未被察觉的情况下篡改仅查看钱包。
创建接收地址
从刚刚生成的钱包中创建一个新的地址。由于已经保存在$HOME/.firma/testnet/firma-wallet/descriptor.json
中,不再需要比特币节点参数。
firma-online get-address --wallet-name firma-wallet
{
"address": "tb1qdkl3aufvvk2zst22dy3ffjt0kfdl79mhvu6jcwecm5exm6j8dveseklast",
"path": "m/0/0"
}
索引状态保存在$HOME/.firma/testnet/wallets/firma-wallet/indexes.json
中,再次调用命令我们有:
{
"address": "tb1q8m2456wjxu8mlkf708d2yvtmtlg59awvd2l3jjzkmt37gtzmx6psva9fnl",
"path": "m/0/1"
}
向地址tb1qdkl3aufvvk2zst22dy3ffjt0kfdl79mhvu6jcwecm5exm6j8dveseklast
发送一些资金
检查余额和硬币
firma-online balance --wallet-name firma-wallet
{
"confirmed": {
"btc": "0.00000000",
"satoshi": 0
},
"pending": {
"btc": "0.00586300",
"satoshi": 586300
}
}
firma-online list-coins --wallet-name firma-wallet
{
"coins": [
{
"amount": 586300,
"outpoint": "43d3a56e8afe96eeb1c3a260bae735d064e5946190d9fb90524047bd21dbf383:0",
"unconfirmed": true
}
]
}
创建PSBT
在收到资金确认后,我们可以创建PSBT,指定接收者和金额,您可以指定多个接收者,并可以使用--coin
显式地使用特定的utxo,请参阅firma-online create-tx --help
firma-online create-tx --wallet-name firma-wallet --recipient tb1q8m2456wjxu8mlkf708d2yvtmtlg59awvd2l3jjzkmt37gtzmx6psva9fnl:22400 --psbt-name test
{
"address_reused": [],
"funded_psbt": {
"name": "test",
"psbt": "cHNidP8BAH0CAAAAAaF+ubg9XAD6ZmGErqdrAdpu4ALBdz7M+TM0oPWNu5scAAAAAAD+////AqMBAAAAAAAAIgAgaMI+YcHlEUY9mvkIVax3/a4d42jXZgcjrbWqpKNFp7l4BQAAAAAAABYAFJmYo0dJtoF0R0qMtwYR5jtL6UGJAAAAAAX8bmFtZQZ0ZXN0LWEAAQEr0AcAAAAAAAAiACASrnn5+Jhe7Sivhhv6EwzbxegCw/oJSyLNg+b0h851tAEFR1IhAuOPRdJj6043K51DVaw+MIyMHEBOuEGrv89me8fOaQLpIQLgQluouXrqa42FwP/Ki9mwFxHFQy/50SN4Zcn73HSwZFKuIgYC4EJbqLl66muNhcD/yovZsBcRxUMv+dEjeGXJ+9x0sGQMeTjFAgAAAAAAAAAAIgYC449F0mPrTjcrnUNVrD4wjIwcQE64Qau/z2Z7x85pAukMyr4y1wAAAAAAAAAAAAEBR1IhAkiG9PSdcBAS08R6LIRS6iGFbQ5ZbjY2an2EMxXcmGbPIQM2XzQNCYGxaFTBlw1c4XU4hQxj7p7ntZZDaVLjrJg39VKuIgICSIb09J1wEBLTxHoshFLqIYVtDlluNjZqfYQzFdyYZs8Myr4y1wEAAAABAAAAIgIDNl80DQmBsWhUwZcNXOF1OIUMY+6e57WWQ2lS46yYN/UMeTjFAgEAAAABAAAAAAA="
},
"psbt_file": "$HOME/.firma/testnet/psbts/test/psbt.json",
"qr_files": [
"$HOME/.firma/testnet/psbts/test/qr/qr-0.png",
"$HOME/.firma/testnet/psbts/test/qr/qr-1.png"
]
}
从节点A进行签名
firma-offline sign --psbt-name test --key-name a1 --wallet-name firma-wallet
{
"balances": "",
"fee": {
"absolute": 193,
"absolute_fmt": "0.00000193 BTC",
"rate": 1.0157894736842106
},
"info": [
"Added signatures"
],
"inputs": [
{
"outpoint": "43d3a56e8afe96eeb1c3a260bae735d064e5946190d9fb90524047bd21dbf383:0",
"signatures": [
"2f15d226"
],
"value": "0.00586300 BTC"
}
],
"outputs": [
{
"address": "tb1q8m2456wjxu8mlkf708d2yvtmtlg59awvd2l3jjzkmt37gtzmx6psva9fnl",
"value": "0.00022400 BTC"
},
{
"address": "tb1qye8gt2pjwpdn8mj7eh3jgnl0hnfwq23lq4cat6s55hsnka3v2kss4jxsmm",
"value": "0.00563707 BTC"
}
],
"psbt_file": "",
"size": {
"estimated": 190,
"psbt": 1083,
"unsigned": 137
}
}
现在位于~/.firma/testnet/psbts/test/psbt.json
的psbt.json已经有了1个签名(注意输出中的Added signatures
)。
从节点B进行签名
firma-offline sign --psbt-name test --key-name a2 --wallet-name firma-wallet
{
"balances": "TODO",
"fee": {
"absolute": 193,
"absolute_fmt": "0.00000193 BTC",
"rate": 1.0157894736842106
},
"info": [
"Added signatures"
],
"inputs": [
{
"outpoint": "43d3a56e8afe96eeb1c3a260bae735d064e5946190d9fb90524047bd21dbf383:0",
"signatures": [
"2f15d226",
"7938c502"
],
"value": "0.00586300 BTC"
}
],
"outputs": [
{
"address": "tb1q8m2456wjxu8mlkf708d2yvtmtlg59awvd2l3jjzkmt37gtzmx6psva9fnl",
"value": "0.00022400 BTC"
},
{
"address": "tb1qye8gt2pjwpdn8mj7eh3jgnl0hnfwq23lq4cat6s55hsnka3v2kss4jxsmm",
"value": "0.00563707 BTC"
}
],
"psbt_file": "",
"size": {
"estimated": 190,
"psbt": 1191,
"unsigned": 137
}
}
合并、最终化和发送交易
firma-online send-tx --wallet-name firma-wallet --psbt-name test --broadcast
{
"broadcasted": true,
"hex": "0200000000010183f3db21bd47405290fbd9906194e564d035e7ba60a2c3b1ee96fe8a6ea5d3430000000000feffffff0280570000000000002200203ed55a69d2370fbfd93e79daa2317b5fd142f5cc6abf194856dae3e42c5b3683fb99080000000000220020264e85a832705b33ee5ecde3244fefbcd2e02a3f0571d5ea14a5e13b762c55a10400473044022041785595cc34a022686213b8d7b34bac2f2bfc77e37a8fa2f2f3019b0646bbfb022047e12715e32b081be49865ffdbca73829b0231e44f77c9afcd6aa25582186e300148304502210081f298aadf2e5f68e322c030b1e97e23f45a1ac9ddf5fa4b964c1a57847f37b70220129c3d54e9f5c946511bfd30fc755846014654d4d693455fa08279a994617e410147522102e43ee99d46f46cd17d25987701576ae07129ab268ca9879e53a345546537dc862102ccbef362214e9e7ece2bcd33731cdabd0c2937d9bec9db2684fb68021297f8b752ae00000000",
"txid": "4e08b321a79465cdbba8ad811ddaa68ffe79604406413b25b55c76b9850902e5"
}
查看交易 4e08b321a79465cdbba8ad811ddaa68ffe79604406413b25b55c76b9850902e5
依赖项
~17–27MB
~340K SLoC