I'm trying to fully understand how P2SH (BIP16) works, and I thought I did. For fun and to check my understanding, I disabled BIP16 in Bitcoin Core (setting BIP16Height in chainparams to a high value) and tried to "sign" a transaction spending a P2SH output by just providing the redeem script. According to my understanding, this should be enough pre-BIP16, since it will make the "OP_HASH160
OP_EQUAL" script of the P2SH output succeed, right? But that seems to be not the case.
In regtest mode, I created the following P2SH address:
$ addmultisigaddress 1 '["03c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e", "0221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad570"]'
2MwCrk6S9UEeFujacKe7m4uDCzu25F3VAeM
$ validateaddress 2MwCrk6S9UEeFujacKe7m4uDCzu25F3VAeM
{
"isvalid": true,
"address": "2MwCrk6S9UEeFujacKe7m4uDCzu25F3VAeM",
"scriptPubKey": "a9142b6defe41aa3aa47795b702c893c73e716d485ab87",
"ismine": false,
"iswatchonly": false,
"isscript": true,
"script": "multisig",
"hex": "512103c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e210221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad57052ae",
"addresses": [
"mg41i3DBptiWbQ9PQ59ykdbc8T85gEqWdK",
"muC6tdGQrYXSqghPZziyvZwu1KSwL49ioy"
],
"sigsrequired": 1,
"account": ""
}
And funded it:
$ sendtoaddress 2MwCrk6S9UEeFujacKe7m4uDCzu25F3VAeM 10
14e8f61534b9a0b6110655dc153d41cc90f64b8104b820e1f4534fd14a732df0
$ generate 1
$ gettxout 14e8f61534b9a0b6110655dc153d41cc90f64b8104b820e1f4534fd14a732df0 0
{
"bestblock": "40d573ebb78bdab760d6659b8ad9d91c46633144d25084eaf3de1f7411040305",
"confirmations": 1,
"value": 10.00000000,
"scriptPubKey": {
"asm": "OP_HASH160 2b6defe41aa3aa47795b702c893c73e716d485ab OP_EQUAL",
"hex": "a9142b6defe41aa3aa47795b702c893c73e716d485ab87",
"reqSigs": 1,
"type": "scripthash",
"addresses": [
"2MwCrk6S9UEeFujacKe7m4uDCzu25F3VAeM"
]
},
"coinbase": false
}
Then, I tried to spend it by providing just the serialised redeem script as scriptSig, but this fails:
$ decoderawtransaction 0100000001f02d734ad14f53f4e120b804814bf690cc413d15dc550611b6a0b93415f6e814000000004847512103c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e210221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad57052aeffffffff0100e1f505000000001976a914cf112b41997697caa3eee9e308ad9b2b917b4e4c88ac00000000
{
"txid": "1971750cd655c7f93627354c380595e3e3434b69c3b6e788eecfb9c685eba703",
"hash": "1971750cd655c7f93627354c380595e3e3434b69c3b6e788eecfb9c685eba703",
"version": 1,
"size": 157,
"vsize": 157,
"locktime": 0,
"vin": [
{
"txid": "14e8f61534b9a0b6110655dc153d41cc90f64b8104b820e1f4534fd14a732df0",
"vout": 0,
"scriptSig": {
"asm": "512103c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e210221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad57052ae",
"hex": "47512103c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e210221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad57052ae"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 1.00000000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 cf112b41997697caa3eee9e308ad9b2b917b4e4c OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914cf112b41997697caa3eee9e308ad9b2b917b4e4c88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"mzPpjgciTo6DMGpE3Lkb4ZLBSn8A239aDZ"
]
}
}
]
}
$ sendrawtransaction 0100000001f02d734ad14f53f4e120b804814bf690cc413d15dc550611b6a0b93415f6e814000000004847512103c278d06b977e67b8ea45ef24e3c96a9258c47bc4cce3d0b497b690d672497b6e210221ac9dc97fe12a98374344d08b458a9c2c1df9afb29dd6089b94a3b4dc9ad57052aeffffffff0100e1f505000000001976a914cf112b41997697caa3eee9e308ad9b2b917b4e4c88ac00000000 true
error code: -26
error message:
16: mandatory-script-verify-flag-failed (Operation not valid with the current stack size)
As you can see, the scriptSig of the raw transaction I try to send matches the hex of the P2SH address. (A very similar script is sent for a correctly signed spending of the P2SH output, except prepended by the actual signatures as mandated by BIP16.) From my understanding of how P2SH works, this should be a valid script pre-fork. Can someone please explain to me what I'm missing here?