Pay To Script Hash
P2SH was introduced as a standard script in April 2012. It allows you to lock bitcoins to the hash of a script, and you then provide that original script when you come unlock those bitcoins.
It basically allows you to create your own custom “redeem scripts”, but still be able to share them easily with other people.
BIP 16: Pay to Script Hash (03 January 2012)
How does P2SH work?
The locking script contains the hash of another locking script (the “
script hash”), surrounded by the
|hex | opcodes||inline | stack|
The unlocking script then contains your original custom locking script (the “
redeem script”), preceded by the data/opcodes needed to unlock it:
|hex | opcodes||inline | stack|
So in the unlocking script above, the
redeem script is a P2MS locking script itself, and the preceding signature is what’s needed to unlock it.
Special Form: The P2SH locking script pattern is recognized as a “special” form, so it gets executed slightly differently to “normal” scripts.
A P2SH script is executed in two parts:
- Standard Execution - The
redeem scriptis hashed, and is then checked that it is equal the
script hashin the locking script.
- Redeem Script Execution - This is the special part. The
redeem scriptis deserialized and ran as if it were a locking script.
1. Standard Execution
First of all, the entire script is executed as normal:
Normally, this is where the script execution would end. However, because of the changes made to bitcoin thanks to BIP 16, we move on to the second step of P2SH script execution…
2. Redeem Script Execution
The second part of the script execution is only concerned with the original scriptSig. The
redeem script (which is a data push) is deserialized in to its component parts (of opcodes and data).
You could think of the redeem script as becoming the new locking script:
Anyway, after the redeem script has been deserialized, the whole script is run like any standard script. Seeing as the
redeem script in the example above contains a P2MS, here’s how the whole script would run:
Why do we have P2SH?
Because it makes it easier to share complex locking scripts with other people.
Before P2SH, if you wanted a complex locking script (e.g. P2MS) placed on your bitcoins, you would have to give the person “sending” you those bitcoins the entire locking script:
But with P2SH, instead of giving someone an entire locking script, you can essentially just give them a hash of your script instead:
As a result, the sender is no longer burdened with the size (or the details) of your locking script.
What are the benefits of P2SH?
There are a few benefits that come with P2SH:
1. Cheaper transaction costs for the sender.
If you want a custom locking script on your bitcoins, the person sending you the bitcoins has to put this script in to the transaction they create:
However, with P2SH they can create a lock using the hash of your script instead, which is much smaller than the full script:
As a result, the burden of large locking scripts is no longer on the sender (and is therefore moved to the receiver instead). This helps to avoid a situation where a sender would be complacent about “sending” bitcoins to a locking script that isn’t one of the simplest and cheapest (e.g. P2PKH).
2. We can use addresses for P2SH locking scripts.
Due to the fact that every P2SH locking script has a uniform structure (thanks to the fixed-size hash, we can easily have a standard
address format for it (similar to the P2PKH address format).
So instead of having to pass the actual P2SH locking script around, we can shorten it (again) and make it easier to share by converting it to an address.
3. P2SH has a little more privacy.
Seeing as a P2SH locking script just contains the hash of another locking script, it’s impossible to know what kind of locking script that hash came from by just looking at it:
As a result, nobody would know if an output “belongs” to one person’s public key, or if it belongs to multiple people.
That’s until someone spends it and reveals the redeem script, of course.
4. A smaller UTXO set.
To make the bitcoin program itself run as fast as possible, all of the unspent outputs from transactions (UTXOs) are stored in RAM on your computer.
These UTXOs also contain the locking scripts (scriptPubKeys), so by using smaller P2SH scripts instead of larger P2MS scripts, you save on the amount of RAM needed to hold the UTXO set.
If you couldn’t fit the entire UTXO set in RAM, nodes would become slower at validating transactions.
Where can you find P2SH scripts?
Look for the outputs with a
3address. You can tell what kind of lock it is (e.g. multisig) by looking at the contents of the
redeem script in the scriptSig.
Here’s the first transaction with a P2SH output that has been unlocked: 1
a0f1aaa2fb4582c89e0511df0374a5a2833bf95f7314f4a51b55b7b71e90ce0f- 1-of-2 Multisig
Here are some more examples of P2SH being used for multisig:
40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8- 1-of-1 Multisig
450c309b70fb3f71b63b10ce60af17499bd21b1db39aa47b19bf22166ee67144- 1-of-2 Multisig
d3adb18d5e118bb856fbea4b1af936602454b44a98fc6c823aedc858b491fc13- 2-of-3 Multisig
Here are some examples of P2SH being used for custom (non-standard)
2c6c3a1319c3e42b4801dab62e3d3d59c51c3535b8dad20e9580650f114c7026- Peter Todd SHA1 Hash Collision Script
What kind of scripts can you put in the redeem script?
You can put just about any custom locking script you want as the
Bitcoin 0.10.0 you are no longer limited to using standard scripts only:
The IsStandard() rules have been almost completely removed for P2SH redemption scripts, allowing applications to make use of any valid script type, such as “n-of-m OR y”, hash-locked oracle addresses, etc. While the Bitcoin protocol has always supported these types of script, actually using them on mainnet has been previously inconvenient as standard Bitcoin Core nodes wouldn’t relay them to miners, nor would most miners include them in blocks they mined. – Bitcoin 0.10.0 Release Notes
So if you want some fun with the various
redeem script of a P2SH is where you can have it.
Make sure that your non-standard script will end up leaving a single
OP_1 left on the stack at the end of execution.
I created a script once that left
OP_1 on the stack, and even thought the top element was
OP_1, I got an “
Extra items left on stack after execution” error and the transaction wouldn’t be relayed.
Doesn’t P2SH take up more space in the blockchain overall?
Yes, you’re right.
For example, a complete 2-of-3 multisig script using the simple P2MS pattern takes up 253 bytes in the blockchain:
On the other hand, a complete 2-of-3 multisig script using P2SH takes up 278 bytes in the blockchain:
So the extra step of locking bitcoins to the hash of a script adds an extra 25 bytes to the overall script.
However, there isn’t really any alternative for being able to create addresses for custom locking scripts, so the extra 25 bytes for this convenience is a reasonable price to pay.
Not to mention the other benefits of P2SH.