bitcoin icon indicating copy to clipboard operation
bitcoin copied to clipboard

Awesome multisig PR labyrinth guide

Open Sjors opened this issue 3 years ago • 14 comments

@ryanofsky recently suggested that I should write an overview of how the various pull requests spread over different repositories relate to some bigger picture view.

See the multisig tutorial for how things currently work.

I typically have the following future multisig wallet in mind to guide my thinking:

  1. a computer running Bitcoin Core holding one master key (key 1)
  2. one or more hardware wallets with additional keys, via HWI (keys 2 ... n)
  3. taproot keypath using n-of-n MuSig2
  4. a fallback with fewer keys after some time elapsed
  5. a GUI wizard to set this up (simple Python command line tool until then)

The descriptors for this could be hand crafted, but it would be nice to have: 6. Miniscript compiler that can generate this

What's Missing?

  • Taproot support for external signers:
    • [x] #22558 (PSBT fields)
    • [x] #23578 (External signer support)
  • [x] Timelock support for descriptors: this will be added along with full MiniScript support in #24148 & #24149 (@darosior).
  • [ ] Ability to handle descriptors for which we have 1-of-N keys. Descriptor wallets currently expect the wallet to be either watch-only and have no keys, or to have all the keys.
    • [ ] #25907 makes it possible to create a wallet with a seed, but without any descriptors.
    • [ ] The user would grab an xpub from it (#22341 ) to construct a multisig descriptor and then import that.
      • [x] #29130 added gethdkeys, helpful but doesn't support arbitrary derivation paths
  • [ ] MuSig2 setup and signing support, which requires:
    • [x] a BIP to specify new PSBT fields (tracked in #23326)
    • [ ] Bitcoin Core MuSig2 support: #31245
    • [ ] At least one other (hardware) wallet to support it
      • [ ] Ledger demo app, see #31245
    • HWI changes: probably none needed
  • [ ] a simple Python setup wizard
    • right now Specter Desktop is by far the easiest way to setup a multisig wallet. But it's a huge dependency (including a bunch of NPM packages for their web interface). A simple Python script in contrib/ could call HWI to get a list of signers, ask what threshold to use, call createwallet to generate a blank wallet, fetch an xpub from it, and then call importdescriptors.
    • the script could use BIP 129 / BSMS (perhaps initially without encryption)
    • Specter doesn't set the external_signer wallet flag, so I have a trivial PR to do that manually: #21928 (up for grabs)
  • [ ] a GUI setup wizard: once we have an established work flow, we would implement that in the GUI

Misc

I have a PR that improves address display handling on the device:

  • [x] https://github.com/bitcoin/bitcoin/pull/24313

Even better would be if we had a feature to ask the wallet for a signature to prove it has the private key (without passing that information to the outside world of course, see #24186). This requires BIP-322 support on our end (#24058), at least one hardware wallet to support it, and a new HWI signmessage command. Perhaps this can later be expanded to allow your device to prove that it (still) has the keys it needs as a co-signer.

Miniscript compilers currently doesn't support Taproot (e.g. to find the optimal tree structure), but I'm assuming you can still hand craft a leaf containing MiniScript.

Sjors avatar Apr 15 '22 11:04 Sjors

Thanks @Sjors, this is very helpful.

jonatack avatar Apr 15 '22 11:04 jonatack

Thanks! It's definitely good to have an umbrella issue here, how to get to the point where it's more or less easy to do multisig with bitcoin core.

laanwj avatar Apr 15 '22 11:04 laanwj

we would just add support new commands in the external signer command interface

Can you elaborate on your longer term plans for external signing / Boost Process.

Process is currently relatively poorly maintained; bugs are remaining unfixed for multiple Boost releases, the code and issue tracking is confusingly spread across multiple repositories (which have different versions of the code), no recent "modernization" (i.e no option use std::filesystme over boost::filesystem, like other Boost modules, which is why we no-longer support external signing on Windows). It's inclusion in our project is also a downside to our Boost consolidation / removal, i.e #24742.

If we continue to use it going forward, I think we need some sort of plan, addressing the above, rather than leaving it ignored while start accumulating workarounds in our own code to support it, and it's presence potentially blocks other goals.

Happy to split this out into a separate issue for discussion.

fanquake avatar Apr 17 '22 12:04 fanquake

Can you elaborate on your longer term plans for external signing / Boost Process.

Ideally replace it, but I have no idea with what. That hasn't changed since 2019. In the original PR https://github.com/bitcoin/bitcoin/pull/15382#issuecomment-462370972 Garzik pointed an alternative from a 2016 blog post. Interesting that repo does have some ongoing development: https://github.com/arun11299/cpp-subprocess

It doesn't support Windows (well) at the moment, but that might be acceptable since we already (temporally) Windows support anyway.

Happy to split this out into a separate issue for discussion.

Indeed seems better to have a separate issue. Swapping out the implementation of RunCommandParseJSON should have no impact on the rest of the architecture.

Sjors avatar Apr 18 '22 12:04 Sjors

I too had some concerns with one of the original PRs (https://github.com/bitcoin/bitcoin/pull/21935#issuecomment-840110786) re: external signers. Revisiting this I think could be good. I typically build with ./configure --disable-external-signer

That being said, my main goal is setting up (offline) multisig with Bitcoin Core, and I think it is many other people's goals to set up a wallet as you described in the OP - so thank you for setting up this umbrella issue Sjors! We are getting closer and closer to the final goal!

I think some other PRs that could be good to add to the above tasklist would be:

For Taproot support for external signers: (Besides the already linked #22558 in the OP):

  • [ ] https://github.com/bitcoin/bitcoin/pull/23578 There's also an issue created in HWI repo to track Taproot support:
  • [ ] https://github.com/bitcoin-core/HWI/issues/501

Additional Miniscript PRs:

  • [x] https://github.com/bitcoin/bitcoin/pull/24860
  • [x] https://github.com/bitcoin-core/qa-assets/pull/86
  • [x] https://github.com/bitcoin-core/qa-assets/pull/89
  • [ ] https://github.com/bitcoin/bitcoin/pull/25540
  • [ ] https://github.com/bitcoin-core/qa-assets/pull/87

Descriptors

  • [ ] https://github.com/bitcoin/bitcoin/pull/22838
  • [ ] https://github.com/bitcoin/bitcoin/pull/24361
  • [ ] https://github.com/bitcoin-core/qa-assets/pull/92

The GUI probably should be built with the new QML based fork? (https://github.com/bitcoin-core/gui-qml) @jarolrod @hebasto @Bosch-0

GUI:

  • [ ] ~https://github.com/bitcoin/bitcoin/issues/9913~ https://github.com/bitcoin-core/gui/issues/670 Possibly out of scope (but nice to have):
  • [ ] https://github.com/bitcoin-core/gui/pull/537
  • [ ] https://github.com/bitcoin-core/gui/pull/562

BIPs to be supported:

  • [ ] https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki BIP 87 Is fulfilled by #23544
  • [ ] https://github.com/bitcoin/bips/blob/master/bip-0129.mediawiki

I had set a $1,500 bounty for a GUI in Bitcoin Core that allows for the setting up of an (offline) multisignature wallet (here: https://github.com/bitcoin/bitcoin/issues/21071). Since then, there's been further work and standardization on this project. I am raising this bounty to $10,000, to be paid out in bitcoin. Payments will be made in part as individual tasklists are completed; to be divided up to developers who worked on the code and helped review it; at my discretion. This bounty update overrules and succeeds completely the original $1,500 bounty.

Bounty_Signed.txt

Also:

Addition:

  • [ ] The GetExternalSigner changes that will be needed as discussed here

Also, ultimately:

  • [ ] https://github.com/ElementsProject/secp256k1-zkp/pull/138

So that threshold spends can be implemented privately

Edit: Damn formatting

Rspigler avatar Apr 18 '22 16:04 Rspigler

Thanks for putting this together Sjors, mulitisg in core would be great.

As @Rspigler mentioned, the QML project aims to be a more modern, user friendly version of the current GUI. Would be great for the GUI component of this effort was put towards the new QML framework. Imo putting a feature freeze on the widgets GUI and slowly moving towards QML as the project develops would prevent a lot of technical debt - something we don't have a lot of room for.

Tagging others on the project for visibility @GBKS @promag @Mogashni.

If you are looking ahead as to how an app like this would function, Nunchuk is a great example and imo easier to use than Specter. @hugohn

Bosch-0 avatar Apr 20 '22 03:04 Bosch-0

~~Also, ultimately:~~ ~~- [ ] https://github.com/ElementsProject/secp256k1-zkp/pull/138~~

~~So that threshold spends can be implemented privately~~

Placed in my original post here

Rspigler avatar May 02 '22 22:05 Rspigler

@Sjors Can you update the title to show the bounty? Thanks.

Rspigler avatar May 04 '22 00:05 Rspigler

Should also add this to https://bitcoinbounties.org/ 👀

Bosch-0 avatar May 04 '22 02:05 Bosch-0

Submitted!

Rspigler avatar May 04 '22 02:05 Rspigler

Don't know about changing the title. I'll add a link to that site to the PR description once its added.

Sjors avatar May 10 '22 13:05 Sjors

@Sjors #22558 can be checked off :partying_face:

Rspigler avatar Jun 28 '22 17:06 Rspigler

Slightly updated the PR description, mainly: point to #26728 which replaces an earlier attempt, drop mention of potential NthKey MuSig2 support, since I discontinued that app.

Are any other wallets working on MuSig2?

Sjors avatar Sep 28 '23 10:09 Sjors

Main momentum on MuSig2 is in #31245, which also links to a demo Ledger app. This still requires a fair amount of skill and copy-pasting to setup and use.

Sjors avatar Dec 06 '24 10:12 Sjors

The action moved to https://github.com/bitcoin/bitcoin/pull/29675#issuecomment-2459516090. First thing people should review is probably #31247.

Sjors avatar Feb 21 '25 13:02 Sjors

The MuSig2 party is now at #31244.

Meanwhile it's still very tedious to setup a multisig wallet, MuSig2 or otherwise. Suggested review to make progress is #29136 which introduces a unused(KEY) descriptor.

Building on that, I think we need a gethdkey (singular) RPC that can derive any xpub for an unused(KEY), in particular m/87'/0'/0'. After that we need to make the wallet a bit smarter when it imports a descriptor that contains an xpub for which it has the master key.

The final piece is exportwatchonly introduced in #32489.

With those ingredients you can somewhat practically setup a multisig wallet, e.g. between Alice with a Bitcoin Core hot wallet and Bob with a hardware wallet:

  • Bob doesn't create a wallet. Instead he gets his m/87'/0'/0' xpub using HWI's getxpub
  • Alice creates a blank wallet, calls addhdkey (which generates a random unused(KEY))
  • Alice calls gethdkey m/87h/0h/0h on the new wallet
  • Alice manually constructs the final descriptor (musig(Alice,Bob))
  • Alice imports this descriptor (optionally: the usused(KEY) disappears)
  • Alice then calls exportwatchonly and hands the wallet file to Bob
  • Bob calls listdescriptors on it to verify his xpub is there

Perhaps the GUI can have a "my multisig xpub" button, which creates a unused(KEY) if needed, especially if we go for a design like this.

Sjors avatar May 19 '25 18:05 Sjors

Alice calls getxpub m/87h/0h/0h on the new wallet

Is this supposed to use the not yet present gethdkey RPC instead? Asking because afaik there is no getxpub in the core wallet.

rkrux avatar May 21 '25 11:05 rkrux

@rkrux yes, fixed. HWI has a getxpub command, but in Bitcoin Core it would probably be called gethdkey (since it might also fetch the extended private key).

Sjors avatar May 21 '25 11:05 Sjors

Opened a draft PR for derivehdkey: #32784

Sjors avatar Jun 20 '25 15:06 Sjors

I recently made quite a lot of progress in getting MuSig2 setups (with fallback branches) to work, mainly tested against Ledger which has BIP388 support.

You can try for yourself with those branches for Bitcoin Core and HWI:

  • https://github.com/Sjors/bitcoin/pull/91
  • https://github.com/bitcoin-core/HWI/pull/794

Sjors avatar Aug 06 '25 15:08 Sjors