I've managed to build a P2SH 2-of-3 multisig contract that works, ie I can create addresses, send coins to them, and spend the outputs. Now I'd like to transition that solution to a P2SH-P2WSH, but I'm hitting a snag.

Here's the HEX of a transaction:


The error I'm getting when trying to use the RPC client's sendrawtransaction is this:

{"result":null,"error":{"code":-26,"message":"bad-witness-nonstandard (code 64)"},"id":"1"}

What I tried to do was:

  • In the address generation, I generated a P2SWH output script by putting an OP_0 + Sha256/Ripe160 of the multisig <2 pubkey1 pubkey2 pubkey3 3 OP_CHECKMULTISIG>. This seems to work as the address that comes out looks right and can be sent to. (Might still be wrong but I'm guessing not).

  • When it comes to spending this output, I'm putting that OP_0 < sha256ripe160 > in the scriptSig

  • The signatures are signing slightly differently to P2SH, they are modified to have the coin amounts signed over.

  • For the witness part, I'm putting the data parts of what would have been the old P2SH sig into the witness. Basically a 4 to say how many witness parts to expect, then a 0 for the baked in multisig bug, then the two signatures, then the <2 pubkey1 pubkey2 pubkey3 3 OP_CHECKMULTISIG> as a big piece of data. I think it looks like the one in this example: https://github.com/libbitcoin/libbitcoin-system/wiki/P2SH(P2WSH)-Transactions. And I can at least see in the output that there's a 040047 and then the first sig.

What have I missed here? How is the witness malformed? Are there other changes needed to turn a working P2SH to a P2SH-P2WSH?

  • The redeemScript should be OP_0 + SHA256(script). No RIPEMD160, and the result is a 32-byte hash. – Pieter Wuille Apr 11 at 21:18
  • Thanks Pieter, I will have a look at that. Is the witness otherwise correct? – Carlos Apr 12 at 11:16
  • @PieterWuille actually I just checked, the scriptSig is in fact just OP_0 and the SHA256 of the unsigned multisig script – Carlos Apr 12 at 11:32
  • 1
    The RedeemScript should be OP_0+<32byte> but the SignatureScript should be <34bytes> (anything between <> is a data push). That makes your SignatureScript 220020384e512d8897924df63814aa332ee71a3600635268ecb3d984acf87a9e6141ec. – Coding Enthusiast Apr 12 at 14:28
  • Aaaah, the 34 bytes of the sig are not the 32 plus 2? – Carlos Apr 12 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.