First of all two matching scripts are used in two different transactions, one that transfers funds to an address (Transaction A) and one that spends those funds (Transaction B). The
scriptPubKey is created by the user that creates Transaction A. It basically adds a claiming condition to the output that is being created. A user may only claim and thus spend the bitcoins associated with the output if he can prove that he owns the output.
This is where Transaction B and the
scriptSig comes into play. Assuming a user wants to send some funds somewhere. He creates a new transaction, and adds outputs to it until he has enough to cover the desired amount. Now he has to prove that he owns those outputs, which he does by providing the output that is needed to claim them, i.e., the public key matching the address and the signatures with the matching private key.
The sender of Transaction A does not yet know the public key, but does know a hash of the public key, because he knows the address he wants to send to. The address is nothing more than the hash of the public key. So the sender now knows all he needs to be able to send the funds to the receiver.
When the receiver wants to spend the funds again he provides the input to the
scriptPubKey. As you can see the
scriptPubKey consists of taking the public key that was pushed on the stack, duplicating it, hashing it and comparing it to the hash of the public key the output was destined for. If they match we still have both the signature and the public key on the stack, which are used by
OP_CHECKSIG to see whether the input had a valid signature attached.
Take this transaction for example. It claims one output, by providing the public key and the matching signature. It then creates two new outputs and specifies the conditions for the next user to claim them.