4

I understand that prior to taproot activation, m-of-n multisig addresses had an "n" max limit of 20 keys. I also saw the 998/999 tapscript multisig transaction that recently caused issues with LND, so this tells me that the 20 max key limit may no longer be in play.

If this is correct, how can I create a multisig address using 210 keys, and requiring 21 of them to spend?

I'd like to do this using nothing other than Bitcoin Core 0.22 QT Console and a text editor (I use notepad++).

Right now I use this command to create a multisig address in the QT Console

createmultisig mKeysRequired "[\"pubKey1\",\"pubKey2\",\"pubKey3\",...]"

What would be the proper format to allow me to create a tapscript 21/210 multisig address?

Thanks!

1 Answer 1

7

This will be possible in the upcoming Bitcoin Core 24.0 release, using RPCs like deriveaddresses and importdescriptors, which take as input specifications in the output descriptor language.

RPCs like createmultisig, addmultisigaddress, etc. only work in the older legacy wallets. Since version 0.21.0 a new type of wallets, called descriptor wallets, are supported by Bitcoin Core. These new wallets operate around the descriptor language, which precisely describes which addresses/outputs belong to the wallet.

In the descriptor language, for example one can write:

  • pkh(PUBKEY) for a traditional P2PKH single-key output
  • sh(multi(2,PUBKEY1,PUBKEY2,PUBKEY3)) for P2SH-embedded 2-of-3 multisig over the provided keys.
  • sh(wsh(multi(1,PUBKEY1,PUBKEY2)) for P2SH-embedded P2WSH with 1-of-2 multisig in it.

In Bitcoin Core 22.0 support was added for tr() in the descriptor language, though without multisig support (as the OP_CHECKMULTISIG opcode which the multi() descriptor language feature maps to does not exist in taproot scripts). In the upcoming Bitcoin Core 24.0 release, multi_a is added which works like multi(), but using a taproot-compatible script. It supports up to 999 keys. The way to use it would be:

  • tr(KI,multi_a(21,K1,K2,K3,K4,...,K210))

where KI is the internal public key you want to use (which will need to be unspendable unless you want it to implement an (1-of-1)-or-(21-of-210) policy. BIP341 gives an example of an unspendable key, namely 50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0. K1 through K210 would be the public keys you want to use. They can be in 66-character hexadecimal notation (starting with 02 or 03), 64-character hexadecimal notation (for x-only pubkeys), or xpubs or xprvs. See the linked document above for more details.

4
  • Thank you very much for this answer! I was able to use 24.0rc2 to create a quick 2-of-3 taproot multisig address, by following your directions. Now I am trying to spend from the address, but I don't know how to sign the transaction. For a normal miltisig, I use this command to sign the multisig raw tx hex. signrawtransactionwithkey "hexstring" [\"privatekey\",...] '[{"txid":"hex","vout":n,"scriptPubKey":"hex","redeemScript":"hex"}]' But when I created the address I didn't get a redeemScript. I tried to sign w/o it and got; "error": "Witness program was passed an empty witness" Oct 27, 2022 at 15:58
  • 1
    You need to use PSBT RPCs for everything related to descriptor wallets, and certainly taproot. They supplant the raw transaction RPCs. Oct 27, 2022 at 17:02
  • Your solution worked perfectly, thanks. Now I have a question about your reply. Can you please explain why the unspendable key must be used UNLESS I want it to implement a 1-of-1 or 21-210 policy? (and what is the other option? 1 of 210?) Nov 20, 2022 at 14:08
  • 1
    If the inner public key were spendable, whoever knows it would be able to make a P2TR keypath spend using the inner public key and the hash of the taptree. Thus, the policy would be either keypath or scriptpath, i.e. 1-of-1 or 21-of-210. This can be sidestepped by explicitly making the inner public key unspendable.
    – Murch
    Nov 23, 2022 at 14:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.