Last release of Core is amazing !
The main new feature is sortedmulti
descriptor. This allows you to import your multisig setup in Core almost as if it was Electrum when combine to the new PSBT export in GUI !
As it needs command line and some weird checksum, you also need to input very long command in the console and if you made a mistake, you cannot copy the last command you made. So take your time when the commands are long to check everything and don't miss anything, use copy paste before validating the long command. You only have to do this once fortunately :)
I detail here how you do it with a k
of n
setup, good luck:
- Use HWI to get the
n
xpub and fingerprint of all your hardware wallets signers (basically, you will do some command like./hwi.py enumerate
to get the fingerprintfffffff
and./hwi.py -f fffffff getxpub derivation_path
for each of the hardware wallets used in the multisig setup, for air-gapped ones you normally have native way to get xpub). If you use other tools, remember it must be xpub formated, not Zpub or Ypub (which may represent the same key but very differently, use https://jlopp.github.io/xpub-converter/ at your own risk if you don't want to use HWI). - Create a blank wallet in Core console (or cli) with
createwallet "Name_wallet" true true
, the private key are also disabled. Load this wallet in command line of QT (you must selectName_wallet
in Qt at the top of command line, or load it withloadwallet
). All command must be run with this wallet loaded (don't load another one in between ....) - Let details the descriptors we can use. For a P2SH (legacy) multisig setup it looks like
sh(sortedmulti(k,...))
, for a P2WSH (native segwit) setupwsh(sortedmulti(k,...))
, and for a P2SH-P2WSH (segwit)sh(wsh(sortedmulti(k,...)))
because we all want to spare fees, I will take P2WSH for what happens next but you know how to get other addresses type. Our descriptors will look likewsh(sortedmulti(k,[path1]xpub1.../0/*,[path2]xpub2.../0/*,...,[pathn]xpubn/0/*))
for receiving addresses andwsh(sortedmulti(k,[path1]xpub1.../1/*,[path2]xpub2.../1/*,...,[pathn]xpubn/1/*))
for change.pathm
is the derivation path of them
th xpub of our setup (order of xpub doesn't matter). But be careful: for a derivation path likem/44'/0'/0'/312
you must writepathm
asfffffff/44h/0h/0h/312
wherefffffff
is the fingerpring of the xpubm
given by HWI andh
replace'
(else it is harder to input in command-line, you need to input\'
instead of'
each time) - We need to get the checksum of the descriptors we use. We call
getdescriptorinfo "wsh(sortedmulti(k,[path1]xpub1.../0/*,[path2]xpub2.../0/*,...,[pathn]xpubn/0/*))"
andgetdescriptorinfo "wsh(sortedmulti(k,[path1]xpub1.../1/*,[path2]xpub2.../1/*,...,[pathn]xpubn/1/*))"
. In the two cases, the result is a JSON with a new descriptor (we don't care of it) and a field like so"checksum": "nefdbkdf"
. This second string is what we want, we namechecksum0
andchecksum1
the checksum results of the two calls. - We import the 2000 first receiving addresses with
importmulti '[{"desc": "wsh(sortedmulti(k,[path1]xpub1.../0/*,[path2]xpub2.../0/*,...,[pathn]xpubn/0/*))#check_sum0", "timestamp": birth_timestamp, "range": [0,2000], "watchonly": true, "keypool": true}]'
. You recognize the same first descriptor and we appendchecksum0
to it with a#
. If you didn't use this wallet setup before (in Electrum ...), setbirth_timestamp
to"now"
else input a timestamp close to the first time you used the wallet to avoid a full rescan (if you don't remember, delete it from the call and enjoy a coffee during full rescans) - We import the 2000 first change addresses with
importmulti '[{"desc": "wsh(sortedmulti(k,[path1]xpub1.../1/*,[path2]xpub2.../1/*,...,[pathn]xpubn/1/*))#check_sum1", "timestamp": birth_timestamp, "range": [0,2000], "watchonly": true, "internal": true}]'
. Notice thatkeypool
is not set, so it is set to false: the keypool is needed to show you receiving addresses one by one to avoid addresses reuse. For change addresses, we need to setinternal
to true so that they are added to the outputs as change automatically.
And you are DONE ! You should get the exact same addresses than Electrum and you can created receiving addresses in Qt ! To send money, just go to the send section, use the new coin control feature and export a partially signed transaction. You can use HWI or Electrum to sign it with your hardware wallets !
Notice: You can import more or less than 2000 addresses of each type. If less, blockchain rescan is faster but you may need to redo what we have done here later when all addresses will have been used once. If more, it is the contrary.
You now have the most possibly secure setup in one software: multisig with hardware on the full node wallet. When Bitcoin Core 0.21.0 will be out, we will also have native descriptor wallet so maybe we will have HD version of this. But for now, this is the best you can do ! Enjoy :)
P.S. : if you like doing things in one shot you can do the last two steps in one big command: importmulti '[{"desc": "wsh(sortedmulti(k,[path1]xpub1.../0/*,[path2]xpub2.../0/*,...,[pathn]xpubn/0/*))#check_sum0", "timestamp": birth_timestamp, "range": [0,2000], "watchonly": true, "keypool": true}, {"desc": "wsh(sortedmulti(k,[path1]xpub1.../1/*,[path2]xpub2.../1/*,...,[pathn]xpubn/1/*))#check_sum1", "timestamp": birth_timestamp, "range": [0,2000], "watchonly": true, "internal": true}]'
[link] [comments]
No comments:
Post a Comment