The only security concern of P2PKH is that it only requires 1 key to spend coins paid to it. P2SH just lets you be even more secure by easily putting more conditions on the redemption of your coins, like requiring more than 1 key to spend.
So, let's say I'm a person that wants to keep my bitcoins really safe, and the way I want to do that is by requiring 3 out of a set of 5 keys to spend my coins. So, the scriptPubKey
that I would like everyone to use when they send coins to me is:
OP_3 {pubkey1} {pubkey2} {pubkey3} {pubkey4} {pubkey5} OP_5 OP_CHECKMULTISIG
But each pubkey is 33 bytes and so this makes a script that is ~170 bytes, which is a bit much to encode in a QR code. And it is definitely is too much data for a human to process.
But if I use P2SH, the scriptPubKey
is just 23 bytes and the sender doesn't have to worry about what exactly the redeem condition I am setting on my coins is. P2SH works like this. I take the script that I want to be my scriptPubKey
and I serialize it (I'll use {} to denote serialization):
redeemScript = {OP_3 {pubkey1} {pubkey2} {pubkey3} {pubkey4} {pubkey5} OP_5 OP_CHECKMULTISIG}
redeemScript_hash = hash160(sha256(redeemScript))
And then the scriptPubKey
that the sender actually uses is:
OP_HASH160 {redeemScript_hash} OP_EQUAL
Which is just 23 bytes in total. The nice thing is that it provides a layer of abstraction. The person who is sending me coins doesn't need to know how I am keeping my coins secure. All they see is a hash of a redeemScript
, but they don't know what conditions that redeemScript
actually puts on redeeming the coins.
Basically, P2SH itself is not inherently more secure because the redeem script can be anything. But what it does is enable coin-receivers to easily communicate how coin-senders should send them coins, while letting the coin-receivers dictate the conditions of how/when those coins can be spent.