External signer multisig support #16895

pull Sjors wants to merge 71 commits into bitcoin:master from Sjors:2019/09/hww-multisig changing 62 files +3788 −182
  1. Sjors commented at 10:43 am on September 17, 2019: member

    This adds 7 commits on top of #16546 (External signer support) to enable multisig functionality.

    It introduces a new createmultisigwallet RPC which can also be used without external signer support (although it’s only marginally easier than importing descriptors).

    It automatically fetches xpubs from connected hardware devices (using HWI), constructs BIP67 multisig descriptors (native and wrapped SegWit) and imports them into a new wallet. For not connected external signers it’s also possible to manually provide an xpub.

    Use enumeratesigners to get a list of device fingerprints, and then call the new createmultisigwallet :

     0createmultisigwallet "wallet_name" threshold ["fingerprint","xpub1","xpub2",...] ( avoid_reuse )
     1
     2Creates and loads a new multisig wallet.
     3Only native segwit bech32 addresses are supported.
     4Arguments:
     51. wallet_name           (string, required) The name for the new wallet. If this is a path, the wallet will be created at the path location.
     62. threshold             (numeric, required) Number of required signatures
     73. signers               (json array, required) A json array of signers identified by their BIP32 fingerprint
     8     [
     9       "fingerprint",    (string, required) master key fingerprint. Can be obtained using emumeratesigners.
    10       "xpub1",          (string) the xpub at deriviation path m/48h/0h/0h/1h used for P2SH_SEGWIT, obtained automatically if -signer if configured
    11       "xpub2",          (string) the xpub at deriviation path m/48h/0h/0h/2h used for native SegWit, obtained automatically if -signer if configured
    12       ...
    13     ]
    144. avoid_reuse           (boolean, optional, default=false) Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind.
    15
    16Result:
    17{
    18  "name" :    <wallet_name>,        (string) The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path.
    19  "warning" : <warning>,            (string) Warning message if wallet was not loaded cleanly.
    20}
    21
    22Examples:
    23> bitcoin-cli createmultisigwallet "ManualMultisigWallet" 2 '[{"fingerprint": "d34db33f", "xpub2": "xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY"}, {"fingerprint": "3442193e", "xpub1": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"}]'
    24> bitcoin-cli createmultisigwallet "AutomaticMultisigWallet" 2 '[{"fingerprint": "d34db33f"}, {"fingerprint": "3442193e"}]'
    25> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createmultisigwallet", "params": ["ManualMultisigWallet", 2, '[{"fingerprint": "d34db33f", "xpub2": "xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY"}, {"fingerprint": "3442193e", "xpub1": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"}]'] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
    26> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "createmultisigwallet", "params": ["AutomaticMultisigWallet", 2, '[{"fingerprint": "d34db33f"}, {"fingerprint": "3442193e"}]'] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
    

    It uses the getxpub HWI method instead of getdescriptors, and constructs the descriptor locally.

    TODO:

    • displayaddress support for all connected devices (only ColdCard can handle this afaik, but requires producing a Multisig.txt file)
    • wait for improved change address detection support, or add strong warning

    See also: Junction or Specter Desktop for similar workflows.

    Change detection

    Note that due to limitations in HWI, hardware wallet firmware and the PSBT format, the current multisig flow is pretty unsafe. This is because change detection generally doesn’t work.

    On ColdCard you can put a multisig.txt file to enable change detection:

    0Name: My-2-of-2
    1Policy: 2 of 2
    2Derivation: m/48h/0h/0h/2h
    3
    4A1A1A1A1: xpub...
    5B1B1B1B1: xpub...
    
  2. Sjors commented at 10:45 am on September 17, 2019: member
    cc @justinmoon @stepansnigirev thoughts on derivation paths?
  3. DrahtBot added the label Build system on Sep 17, 2019
  4. DrahtBot added the label Docs on Sep 17, 2019
  5. DrahtBot added the label GUI on Sep 17, 2019
  6. DrahtBot added the label RPC/REST/ZMQ on Sep 17, 2019
  7. DrahtBot added the label Tests on Sep 17, 2019
  8. DrahtBot added the label Utils/log/libs on Sep 17, 2019
  9. DrahtBot added the label Wallet on Sep 17, 2019
  10. stepansnigirev commented at 12:43 pm on September 17, 2019: contributor

    Using m/48h/0h/0h/1h derivation path by default is ok, but I would like to be able to change the derivation path in options. Also it would be nice to provide xpub without fingerprint, then fingerprint of the xpub and m/ as derivation path could be used, but not sure if it makes sense.

    0[
    1       "fingerprint",   (string, required) master key fingerprint. Can be obtained using emumeratesigners.
    2       "derivation",    (string) deriviation path for the key, m/48h/0h/0h/1h by default
    3       "xpub",          (string) the xpub, obtained automatically if -signer if configured
    4]
    
  11. Sjors force-pushed on Sep 18, 2019
  12. laanwj removed the label Tests on Oct 2, 2019
  13. laanwj added the label Feature on Oct 2, 2019
  14. laanwj removed the label Utils/log/libs on Oct 2, 2019
  15. laanwj removed the label Build system on Oct 2, 2019
  16. laanwj removed the label Docs on Oct 2, 2019
  17. Sjors force-pushed on Oct 29, 2019
  18. Sjors commented at 3:26 pm on October 29, 2019: member

    It now uses sortedmulti() from #17056 and creates both native segwit and P2SH wrapped SegWit descriptors. This should match the derivation paths used by Electrum and ColdCard: https://github.com/spesmilo/electrum/pull/4465

    You can test this with HWI, a ColdCard simulator plus one other wallet, e.g. Trezor (Simulator) or Ledger. After you called createmultisigwallet, you need to create a multisig text file for the ColdCard simulator in work/MicroSD/multisig.txt, using fingerprints and xpubs used in the wallet. You can see those in the descriptor, by generating an address and calling getaddressinfo.

    0Name: My-2-of-2
    1Policy: 2 of 2
    2Derivation: m/48h/0h/0h/2h
    3
    4A1A1A1A1: tpub...
    5B1B1B1B1: tpub...
    

    Now you can send and receive, even with the GUI. Note that HWI automatically clicks Yes on the ColdCard simulator screen to sign….

  19. Sjors force-pushed on Oct 29, 2019
  20. Sjors force-pushed on Oct 29, 2019
  21. DrahtBot commented at 8:54 am on October 30, 2019: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #18052 (Remove false positive GCC warning by hebasto)
    • #18034 (Get the OutputType for a descriptor by achow101)
    • #18032 (Output a descriptor in createmultisig and addmultisigaddress by achow101)
    • #18027 (“PSBT Operations” dialog by gwillen)
    • #17877 (qt, refactor: Make enums in BitcoinUnits class scoped by hebasto)
    • #17786 (refactor: Nuke policy/fees->mempool circular dependencies by hebasto)
    • #17681 (wallet: Keep inactive seeds after sethdseed and derive keys from them as needed by achow101)
    • #17566 (Switch to weight units for all feerates computation by darosior)
    • #16722 (build: Disable warnings for leveldb subtree by default by hebasto)
    • #16681 (Tests: Use self.chain instead of ‘regtest’ in all current tests by jtimon)
    • #16528 (Native Descriptor Wallets using DescriptorScriptPubKeyMan by achow101)
    • #16440 (BIP-322: Generic signed message format by kallewoof)
    • #16432 (qt: Add privacy to the Overview page by hebasto)
    • #16367 (Multiprocess build support by ryanofsky)
    • #16365 (Log RPC parameters (arguments) if -debug=rpcparams by LarryRuane)
    • #16224 (gui: Bilingual GUI error messages by hebasto)
    • #15590 (Descriptor: add GetAddressType() and IsSegWit() by Sjors)
    • #15382 (util: add runCommandParseJSON by Sjors)
    • #15112 (build: Optionally enable -Wzero-as-null-pointer-constant by Empact)
    • #14920 (Build: enable -Wdocumentation via isystem by Empact)
    • #11413 ([wallet] [rpc] sendtoaddress/sendmany: Add explicit feerate option by kallewoof)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  22. Sjors force-pushed on Oct 30, 2019
  23. Sjors force-pushed on Oct 31, 2019
  24. ryanofsky added this to the "PRs" column in a project

  25. Sjors force-pushed on Nov 7, 2019
  26. Sjors force-pushed on Dec 9, 2019
  27. Output a descriptor in createmultisig dd92677895
  28. Introduce SetType function to tell ScriptPubKeyMans the type and internal-ness of it 83a61b78f0
  29. Introduce DescriptorScriptPubKeyMan as a dummy class 3f6cbc5bb1
  30. Add WALLET_FLAG_DESCRIPTORS 949e0734d4
  31. Return nullptr from GetLegacyScriptPubKeyMan if descriptor wallet cf3bc7a550
  32. Create LegacyScriptPubKeyMan when not a descriptor wallet e40a833c3b
  33. Add a lock cs_desc_man for DescriptorScriptPubKeyMan b502a15a95
  34. Store WalletDescriptor in DescriptorScriptPubKeyMan c3bf86b9af
  35. Add LoadDescriptorScriptPubKeyMan and SetActiveScriptPubKeyMan to CWallet 9b99b52ad4
  36. Implement IsMine for DescriptorScriptPubKeyMan
    Adds a set of scriptPubKeys that DescriptorScriptPubKeyMan tracks.
    If the given script is in that set, it is considered ISMINE_SPENDABLE
    25d49c00c1
  37. Implement MarkUnusedAddresses in DescriptorScriptPubKeyMan 172a4eb3d0
  38. Implement IsHDEnabled in DescriptorScriptPubKeyMan 32f97aa7ee
  39. Implement GetID for DescriptorScriptPubKeyMan 632f0f1c5a
  40. Implement SetType in DescriptorScriptPubKeyMan 75be4afd20
  41. Load the descriptor cache from the wallet file 193d96f669
  42. Implement loading of keys for DescriptorScriptPubKeyMan a186fba22d
  43. Implement several simple functions in DescriptorScriptPubKeyMan
    Implements a bunch of one liners: UpgradeKeyMetadata, IsFirstRun, HavePrivateKeys,
    KeypoolCountExternalKeys, GetKeypoolSize, GetTimeFirstKey, CanGetAddresses,
    RewriteDB
    b683600077
  44. Implement writing descriptorkeys, descriptorckeys, and descriptors to wallet file 738e361509
  45. Implement SetupGeneration for DescriptorScriptPubKeyMan a7a85d2ae9
  46. Implement TopUp in DescriptorScriptPubKeyMan e46d3fd5d7
  47. Add IsSingleType to Descriptors
    IsSingleType will return whether the descriptor will give one or multiple scriptPubKeys
    2a0a784aa9
  48. Add a function to determine the OutputType of a scriptPubKey c80e25d874
  49. Implement GetNewDestination for DescriptorScriptPubKeyMan cafb33b3f0
  50. Implement Unlock and Encrypt in DescriptorScriptPubKeyMan 0743ed804f
  51. Implement KeepDestination and ReturnDestination in DescriptorScriptPubKeyMan 5fa5304458
  52. Implement GetReservedDestination in DescriptorScriptPubKeyMan 168dcf6fd9
  53. Implement GetKeypoolOldestTime and only display it if greater than 0 7fa74bad12
  54. Implement GetSigningProvider for descriptor wallets 7e0a7bc0af
  55. Change GetMetadata to use unique_ptr<CKeyMetadata> d3819b681f
  56. Implement GetMetadata in DescriptorScriptPubKeyMan 19715e2af6
  57. Be able to create new wallets with DescriptorScriptPubKeyMans as backing d050347076
  58. Generate new descriptors when encrypting b3d3684cf9
  59. Add IsLegacy to CWallet so that the GUI knows whether to show watchonly 0fc666f32f
  60. add importdescriptors RPC and tests for native descriptor wallets
    Co-authored-by: Andrew Chow <achow101-github@achow101.com>
    b7cf42ac12
  61. Functional tests for descriptor wallets 2de2414044
  62. Change wallet_encryption.py to use signmessage instead of dumpprivkey aef2a5cbb9
  63. Add a --descriptors option to various tests
    Adds the option to use a descriptor wallet to:
    * wallet_basic.py
    * wallet_encryption.py
    * wallet_keypool.py
    * wallet_keypool_topup.py
    * wallet_labels.py
    
    Also runs these tests with --descriptors in test_runner
    eaa391d98f
  64. [depends] update to Boost 1.72 cc443d69fe
  65. configure: add ax_boost_process
    Co-authored-by: Luke Dashjr <luke-jr+git@utopios.org>
    c1e9630ae5
  66. [build] msvc: add boost::process
    * AppVeyor boost-process vcpkg package.
    * Tell Boost linter to ignore it
    * Add HAVE_BOOST_PROCESS for MSVC build (bitcoin_config.h)
    8414896182
  67. [doc] include Doxygen comments for HAVE_BOOST_PROCESS e169a0fa6f
  68. [util] add runCommandParseJSON 6ecbcfab81
  69. configure: add --disable-external-signer
    This prepares external signer support to be enabled by default
    if Boost::Process is present. It adds a configure option to
    disable this feature.
    
    It can also be disabled using --without-boost-process
    
    This also exposes ENABLE_EXTERNAL_SIGNER to the test suite via test/config.ini
    3a2949ce54
  70. Sjors force-pushed on Jan 30, 2020
  71. Sjors force-pushed on Jan 30, 2020
  72. Sjors force-pushed on Jan 30, 2020
  73. [build] msvc: define ENABLE_EXTERNAL_SIGNER e0d2020920
  74. [doc] include Doxygen comments for ENABLE_EXTERNAL_SIGNER 75c0889287
  75. [test] framework: add skip_if_no_external_signer 678668bb69
  76. [build] add IO support for Boost::Optional af62337d24
  77. Add AddressType (base58, bech32) f5d349189f
  78. Descriptor: add GetAddressType() e458981d3e
  79. Add IsSegWit() to Descriptor b66635088d
  80. [wallet] add -signer argument for external signer command
    Create basic ExternalSigner class with contructor. A Signer(<cmd>)
    is added to CWallet on load if -signer=<cmd> is set.
    94059d47ea
  81. [test] add external signer test
    Includes a mock to mimick the HWI interace.
    addfc89fea
  82. [rpc] add external signer RPC files 9878c2a1cd
  83. [rpc] signer: add enumeratesigners to list external signers 1add4c77f4
  84. [wallet] add external_signer flag 68b9b132b7
  85. [rpc] add external_signer option to createwallet 835e2e632b
  86. [test] external_signer wallet flag is immutable d0f3a5adf1
  87. [wallet] ExternalSigner: add getDescriptors method 76112ba00e
  88. [wallet] add GetExternalSigner() 1905c6c44d
  89. [wallet] fetch keys from external signer upon creation b114902f4f
  90. Add Fingerprint() to Descriptor 08ffaef4aa
  91. [rpc] signerdisplayaddress 81ca8ab9fa
  92. [rpc] sendtoaddress and sendmany: support external signer afa9aafc0c
  93. [doc] add external-signer.md 0a0d295415
  94. [wallet] CreateMultisigWallet d78939cd3a
  95. [rpc] createmultisigwallet 4dccbcc5f0
  96. [wallet] add getxpub to external signer c1e2c521eb
  97. [rpc] createmultisigwallet: fetch xpub from signer if present f11aadad91
  98. [wallet] CreateTransaction: iterate detected external signers e0deaf5853
  99. [wallet] CreateTransaction return PSBT if incomplete 651ef6b695
  100. [rpc] walletprocesspsbt: use external signers when available 3fda68ed0a
  101. Sjors force-pushed on Jan 30, 2020
  102. Sjors commented at 12:29 pm on February 19, 2020: member
    I’ll look into this again when there’s more progress on a standard for multisig wallet coordination, see #18142.
  103. Sjors closed this on Feb 19, 2020

  104. Rspigler commented at 7:37 am on May 13, 2021: contributor
    Hi @Sjors - see BSMS for a standard for multisig wallet coordination
  105. Rspigler commented at 1:19 am on June 26, 2021: contributor
    Should this be reopened?
  106. MarcoFalke deleted a comment on Jun 26, 2021
  107. Sjors commented at 1:50 pm on June 26, 2021: member
    I have some ideas on how to tackle this, but no need to reopen this PR. First step is #22341
  108. Sjors deleted the branch on Nov 18, 2021
  109. DrahtBot locked this on Nov 18, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-08 22:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me