If this were easy then surely Satoshi would have implemented it from the start; after all the address is one step removed from the public key presumably to prevent offline attacks trying to find the private key. It seems like you're looking to be another step removed. Is there much point?
Satoshi has a bunch of features that he 'figured out from the start' that are not implemented yet; I'll ask him if this is one of them after I figure out exactly what feature I want and convince myself it is possible to do securely. So I'm going to try to gather my thoughts and see if there is much point:
This is the main problem I was trying to solve:
- A merchant's website should give the customer a unique payment address during the chekcout process. Ideally, generating that unique address would be done entirely on the web server without requiring a RPC call to a bitcoind process running somewhere.
Communicating with bitcoin or some merchant-services website during the checkout process adds another possible point of payment failure-- it is better for the merchant if their customers can continue to pay them even if their bitcoin daemon (or MyBitcoin or MtGox merchant services) is temporarily down for maintenance.
OP_OVER OP_ADD solves that problem, and, thinking about it, has some other very nice properties. Here's how it would work in practice:
1. Merchant gets one or more public keys to use for payments. They're stored in the web server's database.
2. Customer checks out: web server computes HASH160(public_key+order_id), and converts the result to a
bitcoin address version#2 (first byte is not base58-encoded-0, but something else).
3. That bitcoin address makes its way to bitcoin software running on the customer's machine (or at an online wallet service). Since it is a version#2 address, bitcoin creates an OP_OVER OP_ADD.... transaction for it instead of an OP_DUP ... transaction.
4. Merchant's web server software tells a bitcoind running somewhere "if you see payments to HASH160(public_key+order_id), that's one of mine."
5. When the merchant want's to
spend the bitcoins it got from the customer, it has to tell a bitcoind running somewhere the public_key,order_id pair.
If the merchant doesn't completely trust the payment processor then keeping steps (4) and (5) separate is very nice-- the payment processor can't spend the merchant's bitcoins until the merchant tells them the order_ids (merchant would have to use truly random order_ids to be completely safe, of course).
And, as noted before, this is a little more private than standard bitcoin transactions because the public key isn't revealed until the coins are spent.
I was answering a different question and came up with the following:
Here’s a use case: The client creates a special kind of transaction that you could attach to the email. This transaction transfers a certain amount of Bitcoin from your public key to the recipients public key. This transaction is not published and therefore not yet final. Furthermore, it has a time to live, say 48 hours.
At the receiver the software checks the validity of the transaction. If it is valid and the money is there in Bitcoin it presents the email to you. If you like the email you do nothing and the transaction expires. No funds transfer. After the transaction expires the sending wallet deletes its copy of the transaction and credits the sender with the coin.
If you don’t like the email you click the button and the coin is collected. (The transaction is published and bundled into the next Bitcoin block.) The sending wallet sees the transaction and makes the deduction of funds from the wallet permanent.
This is like a check in the mail. It’s safe because only the recipient public key can collect it and it can’t be lost because of the expiration date.
It’s a form of check in bitcoin. The key idea is that the receiver adds a well formed transaction to the block chain, not the sender. This can be made to solve the merchant problem as well without having to add a new transaction type to the block chain. It would work as follows:
Define a well formed Transaction as
Tw.
Define a covered transaction,
Tc, as one where a field in the transaction is “covered” redering the transaction invalid as far as the normal client is concerned.
Assume the sender uses the receiver’s public key to generate the cover in such a manner that only the receiver (using his private key) can uncover it.
So, the sender starts by creating a well formed transaction
Tw. He then covers it using the receivers public key producing
Tc. He sends
Tc to the receiver out of band (it’s exported from the client and sent in some other transaction, encoded for pasting in an email for example.) Only the receiver can uncover
Tc to produce
Tw which he can check and submit to the network if he wants to cash the check.
One detail. The sender should put the amount of the check into a single public key he owns before creating the check. The sender can effectively cancel the check by sending himself the amount of the check from that key. If his cancel went in before the merchant’s cashing of the check then the check is canceled. If the merchant got
Tw published first then the cancel is too late. This mechanism allows an effective expiration time limit on the check.