Skip to main content
2 of 3
deleted 360 characters in body
Jus12
  • 1.4k
  • 1
  • 14
  • 25

Step by step example to redeem a P2SH output required

I have been following BIP16 in creating a P2SH transaction. I want to create a simple (one signature) P2SH. I am getting an error when trying to broadcast the tx. Error is 16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)

To be clear, I am not trying multisig. What I am doing can be best described as P2SH-P2PK, though I have not seen this term. This is the only example given in BIP16, so this should work.

Here is what I have tried (testnet):

private key: BB2AC60BC518C0E239D5AF9D8D051A6BDFD0D931268DCA70C59E5992 
public key: 039f53e45f8f18b8ed294378bda342eff69b2053debf27fbede7d2d6bd84be6235 
(compressed)

redeemScript: [{pubKeySize,pubKey}] [OP_CHECKSIG]
21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC 

redeemScriptHash: RIPEMD160(SHA256(redeemScript))  
323D0E8A083E98010299109337850D05DD6157F7

p2shAddress: Base58Check(0xC4 + redeemScriptHash) (C4 for testnet)
2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7

The above address has two UTOXs on testnet:

UTXO1: e434a13cac79dc3d26e7279bff05c0f071a2df03e2ba6ca13c88f0e82dca9998:0
UTXO2: 9b4943e7ab5f4512e42c94254eb6aab4c6823ce06d4ff816b7ce4fda155a2571:0

I now want to spent both UTXOs and keep following outputs:

Out1: 2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7 34000000 Satoshis
Out2: 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF 100000000 Satoshis   

I created the tx as follows:

  1. Create unsigned transactions with all scriptSigs empty

  2. For each input to sign, set its scriptSig to redeemScript: 21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC, keeping other scriptSigs to empty.

  3. Serialize the new tx and append SIGHASHALL bytes (0x01) in little endian 4 bytes

  4. Double Sha256 above and sign resulting value. Add one byte 0x01 to signature to indicate SIGHASH_ALL. Let sig be the resulting value.

  5. Set the scriptSig as:

[0x00] [{sigSize, sig}] [{pubKeySize, pubKey}] [OP_CHECKSIG]

I am assuming that the following scriptPubKey will be used:

[OP_HASH160] [{scriptHashSize, scriptHash}] [OP_EQUAL]

The following are the k, r and s values for each input's signature:

Input 1:

k = 98790447509501799195296257240616657470656053786701275200434341714298778299820  
r = 96398386359095408146340664941016369169423137684113382189227162443480418477689
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129

Input 2:

k = 109372172176680138721552873719725202562296645126925021083510279924852033069204  
r = 105162394984132461723584277789901247831150698039237112243693144757926439529504
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129

After this, I am getting the following error in bitcoind for sending the tx:

error code: -26
error message:
16: mandatory-script-verify-flag-failed 
(Signature must be zero for failed CHECK(MULTI)SIG operation)

What am I doing wrong?

EDIT: Thanks to the answer by arubi, I found there were two issues with the above steps. First thing, I was doing wrong was not encoding the redeemScript as stack data. Second thing, I was doing wrong was putting [0x00] in scriptSig. After fixing that, Step 5 should be:

  1. Set the redeemScript as [{pubKeySize, pubKey}] [OP_CHECKSIG]

  2. Set the scriptSig as [{sigSize, sig}] [{redeemScriptSize, redeemScript}]

Jus12
  • 1.4k
  • 1
  • 14
  • 25