Exploring Bitcoin: signing P2SH input

Jul 9, 2018 · 3 min read

This article is a detailed description of how P2SH output works in bitcoin transactions and the step-by-step algorithm for signing this type of output inside transaction input. In the enclosed part is an example of a signing P2SH input using the Python.

OP_HASH160 <hash160> OP_EQUAL

Pay to Script Hash output script allow transactions to be sent to script (redeem script) hash. This means that from any script serialized to a byte string, you can take a hash and use this hash as a unique identifier. The address of P2SH output is a hash160 from redeem script converted into base58 encoding with the addition of a byte version and a checksum.

Mainnet address example: 3NVBnDRBUsdnfVb77DYGwEfwSt7kVCrv8s
Testnet address example: 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF

To create a spending transaction from this type of output, must provide a signature script (unlocking script) for this output. The signature script consists of a redeem script and other elements that depend on the content of the redeem script.

Signature script: <sig> ... <redeem script>
P2SH script: OP_HASH160 <hash160> OP_EQUAL

Script execution P2SH with redeem script 1of 2 multisig script step by step:

Step 1 verify redeem script

First step execution completed in case top stack element is True (not 00 or empty) execution continue with redeem script (top stack element removed)
redeem script for this example is:

OP_1 <pub_key_1> <pub_key_2> OP_2 OP_CHECKMULTISIG

Step 2 execute redeem script

Execution completed if top stack item in case of the signature was valid in stack pushed 01 this means True, and transaction input validation is passed.

Bitcoin testnet signing P2SH with nested MULTISIG 1 of 2 step by step example:

We have 1.3 tBTC locked on P2SH with nested multisig output for address 2MwYC4w4xucVYqTRk89u7V2FaBSdrpjmk15. Want to transfer to mwJMtn5hW54pJC748EExvhRm6FRVmUZXQt

Private Key 1: cPBuqn4ZsddXunx6EEev6khbfUzFnh3xxdEUPCrm5uy9qGcmbBEt
Private Key 2: cVgShyj2q4YKFX8VzCffuQcrJVYhp522NFozNi7ih2KgNVbnysKX
Redeem Script: 512103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443e3810483d5dbcf671512d9999f9c9772b0ce9da47a52aeRedeem Script opcodes: OP_1 [33] [33] OP_2 OP_CHECKMULTISIG
P2SH address: 2MwYC4w4xucVYqTRk89u7V2FaBSdrpjmk15
Input transaction: ae0df7bd689026e13fe7d71333a8fda2c7d3f5998644a8a96f60364bb7dfd62f

Input transaction output: 0
Input amount: 1.3000000

Step 1: create unsigned transaction with empty Signature script

{ version: 1
vIn: {0: {scriptSig: ,
sequence: 4294967295,
vOut: 0}},
vOut: {0: {address:
value: 130000000}},
lockTime: 0}
Transaction hex:0100000001857aff3abca2353193397a7d2eea61b25d8be381cabe5a1935868b74fa4c24ad0000000000ffffffff014062b007000000001976a914ad204de226b3d11a70dc53b4998f4603e138ff3f88ac00000000Explained:01000000 [version]01 [inputs count]
[input transaction hash in little endian byte order]
00000000 [input transaction output]
00 [signature script len]
ffffffff [sequence]
01 [outputs count]
4062b00700000000 [output amount]
[locking script]
00000000 [locktime]

Step 2: we should get signature hash from this transaction. ( we will use SIGHASH_ALL type of sighash)

Input 0 sighash preimage:0100000001857aff3abca2353193397a7d2eea61b25d8be381cabe5a1935868b74fa4c24ad0000000047512103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443e3810483d5dbcf671512d9999f9c9772b0ce9da47a52aeffffffff014062b007000000001976a914ad204de226b3d11a70dc53b4998f4603e138ff3f88ac0000000001000000Sighash: bd412a2ba475b9f0cb16e58de11a6d4ddbe52a12f76c0e2a056887f2dcc8bf08

Step 3: sign sighash with private keys

Signature 1:3044022051c7546ff919248badd1012317066cc0edd3e5f49050ac54ef52b66a8e80e17b02201dd65963551e0dc7d8ce5721fbd3125fa9272a98bad1ed5df91488a462eac123

Step 4: insert signature to transaction signature script and insert serialized redeem script into transaction signature script. For each signature add sighash type byte

Transaction hex:0100000001857aff3abca2353193397a7d2eea61b25d8be381cabe5a1935868b74fa4c24ad000000009100473044022051c7546ff919248badd1012317066cc0edd3e5f49050ac54ef52b66a8e80e17b02201dd65963551e0dc7d8ce5721fbd3125fa9272a98bad1ed5df91488a462eac1230147512103b4603330291721c0a8e9cae65124a7099ecf0df3b46921d0e30c4220597702cb2102b2ec7de7e811c05aaf8443e3810483d5dbcf671512d9999f9c9772b0ce9da47a52aeffffffff014062b007000000001976a914ad204de226b3d11a70dc53b4998f4603e138ff3f88ac00000000Explained:01000000 [version]01 [inputs count]
[input transaction hash in littile endian byte order]
00000000 [input transaction output]
91 [signature script len]
00 [Due to a bug, one extra unused value is removed from the
47 [signature push len]
5df91488a462eac12301 [signature]
01 [sighash type SIGHASH_ALL]
47 [redeem script len]
9772b0ce9da47a52ae [redeem script]
[signature script]
ffffffff [sequence]
01 [outputs count]
4062b00700000000 [output amount]
[locking script]
00000000 [lock time]

Example with python bitcoin library pybtc:



Written by

Bitcoin, because fuck the banks.

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade