Why can't [the unlocking script] be shortened to just one opcode — OP_CHECKSIG?
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...
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...
To spend this output, you would then need the following unlock script...
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