0

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:

01000000000102a34c065d1e389dbcb3edc34f611b719b7d3b691438dc915622f9e91652fd33b001000000220020384e512d8897924df63814aa332ee71a3600635268ecb3d984acf87a9e6141ecffffffff6fa82857ccb85ee4b48c00c11cfd59442a612cd8733741b11a70823301a2bf7e0000000022002095032074938de75c626ce882f6bf8ef48eec88d621772eee2de4996662ce9baeffffffff0300b4c4040000000017a9142a702b38c86db7d3bddf61f233af88aa2f0482b887801d2c040000000017a91428fe391e1ea27877bed496146a990bfcbbf0f50987df69f9020000000017a9145caf8cd6b560c11f6801e370333ed693764c8e4f8704004730440220491dcd2ef56238c45caace982bb6a8546172d622f5b9565fc6d4b044b96536e5022069ca7dae081c515d53cbf2366f258b224618a1e13921769686a26e070e3c4b4e01473044022039f3fda390f73f00c9f5d2ae358c915d291a239d13c84c1fcbd2f5fc9f3b0916022051e83a3d0154255907153d76888e977510821640258f39fe87282dc54a34a893016952210245c1385d4870baee4d5597654019e89930d9e8f42783fe5c57e1551bf81456442102cb3be5420ea834bce0b4e71ca717c199b315eb97c8e60a32f368e0d10af1023a21034abc8a0a8f62e8201f67796a2da3dc616609b82b246a1db4daba237354ce407e53ae0400483045022100e9184b1d52edec1e46162093406bcb73510254b222cb1ee04e20756c870b58e1022078127ec954ada7bf65403abac670b36dbdbba784ccde3a38ea435766f8c9c08d0147304402200678d5e35a599d73b15becba0935c60237a0b0a052736e3becf8ee975f15689d0220374b84b7842d698ba4379d12f98f10fd3141d4a4983ee136ad04cc527d35e1f9016952210208f65530fed9457996ac9bf6c3747fad3f1a362a64685378b81b4d1fa45653c62102fd0bcce6190272fd49a28b585ebec2b9fe02b5905c69260edfaaec098908ea4e2103f14ff5e9415a56e2249ef28902f0fbfd03d969f42dfdcc2f7f58adb45dbc62b453ae00000000

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.