Now I understand, why there was no answer - it gets really long :-)
So I answer it by myself. I am with bitcoin core (getinfo) version 150100, on OpenBSD (ksh) and OSX (bash v3):
I solved it on testnet, and got the tx to go through. Some information from @nick here:
Does OP_HASH160 consume the top stack element?
I was wondering, if this holds true:
For this to work, the <OP_HASH160>
opcode would have to know, that the
pubkey and the <OP_CHECKSIG>
would need to be hashed together
Obviously it does. Here is the whole cycle... First I try to have a look at the stack with input and output scripts (as per link above):
sigscript: <sig> <redeem script>
pubkey script: OP_HASH160 <RedeemScriptHash> OP_EQUAL
Based on the link above and looking at the stack, it would run through these steps:
Input SigScript (push data on stack) STACK:
Execute pubkey script a. this would first push first OPCODE of pubkey script on stack and execute STACK:
OP_HASH160
b. this command consumes top stack element, and replaces with hash
STACK:
c. the next elements of the pubkey script is pushed to stack STACK:
OP_EQUAL
OP_Equal verifies top two stack elements, if untrue --> invalid
If true, script ends with "true" on top of stack STACK:
verify if script is P2SH (... ok, it is P2SH ...)
clean the stack, and run sigscript again STACK:
pop top stack element, and run it as script a. the top element of the redeem script is OP_CHECKSIG STACK: OP_CHECKSIG
b. CHECKSIG would verify pubkey and sig, and return true ...
To see if this is correct, assemble a funding tx on testnet/regtest. When using coinbase tx (mined block), need >100 confirmations! Start with creation of a redeemscript and address for this tx:
NEWADDRESS=$( bitcoin-cli -regtest getnewaddress )
echo $NEWADDRESS
PUBKEY=$( bitcoin-cli -regtest validateaddress $NEWADDRESS | awk -F '\"' '/pubkey/ { print $4 }' )
REDEEMSCRIPT=$( printf "21%sac" $PUBKEY )
# creating the hash of the REDEEMSCRIPT
printf $( echo $REDEEMSCRIPT | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_fn.hex
openssl dgst -sha256 -binary <tmp_fn.hex >tmp_sha256.hex
REDEEMSCRIPTHASH=$( openssl dgst -ripemd160 <tmp_sha256.hex | cut -d " " -f2 )
# convert redeemscripthash to bitcoin address (testnet!), with "C4" Prefix
PRFX_REDEEMSCRIPT=$( printf "c4%s" $REDEEMSCRIPTHASH )
# double sha256 the hex value
printf $( echo $PRFX_REDEEMSCRIPT | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_fn.hex
openssl dgst -sha256 -binary <tmp_fn.hex >tmp_sha256.hex
openssl dgst -sha256 <tmp_sha256.hex | cut -d " " -f2 >tmp_dsha256.txt
# checksum and append
result=$( cat tmp_dsha256.txt | cut -b 1-8 )
result=$( printf "%s%s" $PRFX_REDEEMSCRIPT $result | tr "[:lower:]" "[:upper:]" )
# and base58
base58str="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
REDEEMSCRIPTADDR=$( dc -e "16i $result [3A ~r d0<x]dsxx +f" | while read -r n; do
j=$(( n + 1 ))
echo $base58str | cut -b $j
done | tr -d '\n' )
bitcoin-cli -regtest importaddress "$REDEEMSCRIPTADDR" p2sh
bitcoin-cli -regtest importaddress "$REDEEMSCRIPTADDR" rescan
bitcoin-cli -regtest validateaddress "$REDEEMSCRIPTADDR"
bitcoin-cli -regtest listunspent
The redeemscript's address would start with a "2" on testnet. Now create the funding tx. Search for an UTXO, that we can use, and note down tx and vout.
UTXO_TXID=d260e120647360dcfc8606e242c6389acece3ee585d5e0d76a26b87b08b322e0
UTXO_VOUT=0
VALUE=49.9997
RAW_TX=$( bitcoin-cli -regtest createrawtransaction '''[{"txid":"'$UTXO_TXID'","vout":'$UTXO_VOUT'}]''' '''{"'$REDEEMSCRIPTADDR'":'$VALUE'}''' )
bitcoin-cli -regtest decoderawtransaction $RAW_TX
SIGNED_TX=$( bitcoin-cli -regtest signrawtransaction $RAW_TX | awk -F '\"' '{ print $4 }' )
bitcoin-cli -regtest decoderawtransaction $SIGNED_TX
UTXO_TXID=$( bitcoin-cli -regtest sendrawtransaction $SIGNED_TX )
bitcoin-cli -regtest getrawmempool
bitcoin-cli -regtest generate 1
# verify new address has funds:
bitcoin-cli -regtest validateaddress "$REDEEMSCRIPTADDR"
bitcoin-cli -regtest getreceivedbyaddress "$REDEEMSCRIPTADDR"
At this point, the funding transaction is sent. Now the spending tx, we need a new address to receive the funds from the P2SH address:
RCVADDRESS=$( bitcoin-cli -regtest getnewaddress )
echo $RCVADDRESS
# verify that tx from $REDEEMSCRIPTADDR has funds
RAW_TX=$( bitcoin-cli -regtest getrawtransaction $UTXO_TXID )
bitcoin-cli -regtest decoderawtransaction $RAW_TX
# to send funds from $REDEEMSCRIPTADDR to a new address, need the privkey:
NEWADDRESS_PRIVKEY=$( bitcoin-cli -regtest dumpprivkey $NEWADDRESS )
create the raw tx, sign it, and send it (maybe the amount needs to be updated):
UTXO_VOUT=0
UTXO_OUTPUT_SCRIPT=$( bitcoin-cli -regtest validateaddress "$REDEEMSCRIPTADDR" | awk -F '\"' '/scriptPubKey/ { print $4 }' )
VALUE=7.7699
RAW_TX=$( bitcoin-cli -regtest createrawtransaction '''[{"txid":"'$UTXO_TXID'","vout":'$UTXO_VOUT'}]''' '''{"'$RCVADDRESS'":'$VALUE'}''' )
bitcoin-cli -regtest decoderawtransaction $RAW_TX
SIGNED_TX=$( bitcoin-cli -regtest signrawtransaction $RAW_TX '''[{"txid": "'$UTXO_TXID'","vout": '$UTXO_VOUT',"scriptPubKey": "'$UTXO_OUTPUT_SCRIPT'","redeemScript": "'$REDEEMSCRIPT'"}]''' '''["'$NEWADDRESS_PRIVKEY'"]''' | awk -F '\"' '{ print $4 }' )
UTXO_TXID=$( bitcoin-cli -regtest sendrawtransaction $SIGNED_TX )
bitcoin-cli -regtest getrawmempool
bitcoin-cli -regtest generate 1
At this point I could see, that my newly generated RCVADDRESS contained the value (bitcoin-cli -regtest listunspent | grep -A5 -B5 $RCVADDRESS):
... "amount": 7.76990000
I had one smaller observation, which is not yet fully clear to me: the scriptsig was changed in the final tx. It had the signature, and behind should follow the redeemscript. This redeemscript was "extended" in this way:
23210355ef94c6e097752f303d685e4011b9dba8c1cd1382f8fa68bf2de0d523f18fffac
The 23 at the beginning would be the length indicator for the following pubkey, but this would include "ac"... Not sure, why bitcoin core extends it this way.
Now that I got it to work with simple P2SH, I can try SegWit-P2SH :-)