2

For P2PKH, the scriptPubKey is OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG. Why can't it check the signature only? Why can't it be shortened to just one opcode — OP_CHECKSIG?

Why does the public key need to be presented in addition to the signature when unlocking?

1
  • Can you clarify what you mean by "just one opcode OP_CHECKSIG"? If that was the entire scriptPubKey, anyone could spend any output (as the attacker could provide their own public key rather than the coin owner's). – Pieter Wuille Mar 29 '20 at 7:26
0

Why can't [the unlocking script] be shortened to just one opcode — OP_CHECKSIG?

The OP_CHECKSIG function pulls two arguments off of the stack - a public key and a signature. It then verifies that the specified public key was used to generate the provided signature, and that the signature matches the transaction that it is in.

So if you make an output with a locking script that was shortened to only OP_CHECKSIG, then I could could spend that output using this unlock script...

<sig> <my_public_key>

This pushes the signature of the spend transaction that I generate using my private key, and then my public key onto the stack. Next the unlock script would run and the OP_CHECKSIG would pop those and verify that the signature that I generated and my private key match. Note that at no point did I need to know any of your keys to spend your output. This is not what you want. You want only someone who knows your private key to be able to spend your outputs.

So the minimum lock script you can use with bitcoin that will require your private key to unlock is...

<your_public_key> OP_CHECKSIG

To spend this output, you would then need the following unlock script...

<sig>.

Since you know your private key, you can generate a signature that will validate against the public key you put the locking script. This is, in fact, a standard (but rarely used) lock/unlock script.

So if we can use these much simpler locking and unlocking script, why do the standard script have all that extra stuff?

A bitcoin public key is at least 257 bits long, and you'd have to give that long number to anyone who was going to send you bitcoin. The standard script instead includes a 160 bit hash of your public key, which is much shorter.

Why does the public key need to be presented in addition to the signature when unlocking?

The extra stuff in the standard scripts do the work so that only the shorter hash needs to be in the lock script. But the OP_CHECKSIG still needs to know the full public key to be able to check that the signature matches it. So the public key instead shows up in the (now longer) unlock script which you do not need to give out to people. The rest of the code hashes the full public key to check that it was really you that make the locking script, and then gives the full public key to the OP_CHECKSIG.

2
  • Excellent! Could you walk me through a step-by-step execution of OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG? I think that would really help in clearing up all remaining doubt. – Flux Apr 30 at 23:19
  • 1
    I have found a step-by-step execution example on en.bitcoin.it/wiki/Script#Script_examples – Flux Apr 30 at 23:29
1

The script achieves two things:

  1. Ensures the provided public key matches the provided signature
  2. Ensures the provided public key leads to the same address script the utxo was locked with.

A P2PKH script contains the hash of the public key. When you spend the coins, you provide a public key, and a signature.

First, the script duplicates the provided public key, then runs it through hash160, and compares the output to the hash embedded in the locking script.

Once that check passes, it validates the provided signature against the same public key. This ensures that the signature comes from the same key that was used to generate the address.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.