3
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:
- Create unsigned transactions with all scriptSigs empty
- For each input to sign, set its scriptSig to redeemScript:
21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC, keeping other scriptSigs to empty. - Serialize the new tx and append SIGHASHALL bytes (0x01) in little endian 4 bytes
Double Sha256 above and sign resulting value. Add one byte 0x01 to signature to indicate SIGHASH_ALL. Let
sigbe the resulting value.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:
Set the
redeemScriptas[{pubKeySize, pubKey}] [OP_CHECKSIG]Set the
scriptSigas[{sigSize, sig}] [{redeemScriptSize, redeemScript}]
2It's worth to note that the
0x00value left on the stack does not invalidate the transaction, rather it will not be caught before relay by local policy as it doesn't adhere to thecleanstackrule. – arubi – 2017-12-22T18:51:02.373If some node mines the tx with the leading
0x00, will be be considered valid? – Jus12 – 2017-12-28T18:03:10.953Yes, I think it will be valid as the
OP_CHECKSIGwhich executes last will push a value that evaluates to True (0x01in this case) to the top of the stack. The stack will be :Making the whole script evaluate to True. – arubi – 2017-12-30T09:00:58.920