Did you know that you can navigate the posts by swiping left and right?
In this post we will explain the rationale behind Pay to Script Hash (P2SH) type of addresses and demonstrate with code. This tutorial assumes some understanding of the high-level Bitcoin concepts or at least having gone through the previous technical articles of this tutorial.
To demonstrate the advantages of P2SH we will first go through a simple use case using first the Multisignature standard transaction output type and then implement the same script with the P2SH standard transaction output type.
Consider the scenario where we accept funds in an address that is not controlled by one person. For example it is typical for companies to allow spending from corporate accounts only if, say, 2 people agree. These are called multi-signature accounts. A multi-signature account requires M-of-N signatures in order to spend the funds. An address’ locking script could enforce that. For example a 2-of-3 multi-signature locking script would look like:
2 <Director’s Public Key> <CFO’s Public Key> <COO’s Public Key> 3 CHECKMULTISIG
Indeed, this is the locking script of the multisignature standard transaction output type. If someone needs to send money (lock funds) to that output script then they need to know it! The company would need to send this script to all their customers that wish to pay them.
This is not practical since the whole script is recorded on the blockchain for every transaction and more importantly has privacy issues; the company is revealing the public keys that control the funds.
If you think about it the precise locking/unlocking script of the funds should not concern the customers at all. Only the company should know how to spend them.
P2SH is a type of transaction output (BIP-16) that moves the responsibility for supplying the conditions to redeem a transaction (locking script) from the sender of the funds to the redeemer (receiver).
The locking script of such a transaction is quite simple:
OP_HASH160 [20-byte-hash-value] OP_EQUAL
The 20-byte hash value is the hash of the redeem script:
RIPEMD-160( SHA-256( 2 <Director’s Public Key> <CFO’s Public Key> <COO’s Public Key> 3 CHECKMULTISIG ) )
Using this hash we create a Bitcoin address (same process but instead of OP_HASH160(pubkey) we use OP_HASH160(redeem script)) using the version prefix of 0x05 that creates addresses that start with 3. Consult this code for the details.
We then only need to disseminate this address to the company’s customers. The can send funds oblivious to how these funds are locked. The company knows how they are unlocked so they can prepare the appropriate unlocking script.
As an example, to spend the funds, the company can create the following script:
<Director’s signature> <CFO’s signature> <2 <Director’s Public Key> <CFO’s Public Key> <COO’s Public Key> 3 CHECKMULTISIG>
It has two parts, the redeem script’s unlocking conditions (which in this case are two of the signatures) plus the redeem script. Notice how the redeem script is revealed only when the company spends the funds; and it only reveals the two signatures, not all three.
Validation occurs in 2 steps. First we confirm that the redeem script equals the hash in the locking script. Thus we take the second part of the unlocking script and prepend it to the unlocking script as is typically done:
<2 <Director’s Public Key> <CFO’s Public Key> <COO’s Public Key> 3 CHECKMULTISIG> OP_HASH160 [20-byte-hash-value] OP_EQUAL
If the hashed redeem script is equal to the 20-byte hash value the above script will result OP_TRUE
and it validates that the correct redeem script was passed. We can now proceed in validating the actual redeem script using the first part of the unlocking script:
<Director’s signature> <CFO’s signature> 2 <Director’s Public Key> <CFO’s Public Key> <COO’s Public Key> 3 CHECKMULTISIG
If that also results to OP_TRUE
then the funds can be spend.
P2SH moves the responsibility for supplying the conditions to redeem a transaction (locking script) from the sender of the funds to the redeemer (receiver).