The person who is creating the physical Bitcoin card creates a transaction with an output like this:
OP_DROP OP_DUP OP_HASH256 OP_EQUALVERIFY OP_CHECKSIG
Then to redeem this transaction, the person who receives the card creates a transaction to himself with an input containing the code and signature. The code and the rest of the private key are on the card.
I imagine that a Bitcoin scratch-off would have the full transaction hash on the front and the code/key under the scratch-off portion in base58. To redeem, start typing the hash into your Bitcoin client until it tells you that it has enough to identify a single transaction (only 4-8 bytes are necessary). Then type the code/key. The money is instantly yours, with no central server necessary. If you have a computer handy while buying the card, you can verify that a card is still valid by looking at the hash on the front (the code could be fake, of course).
The first few bytes of the private key can be used as a salt.
Without the public/private keys, it would be easy for any man-in-the-middle (including any Bitcoin node) to rewrite your transaction to himself after receiving it. It's still possible for him to do this, but he would have to preemptively brute-force the full private key from the portion in the transaction, and then he would have to re-sign his new transaction on-the-fly in less than a few seconds. I think this makes the attack difficult enough for the scheme to be usable.
This can be significantly improved if the mathematical script functions are enabled (alternatively, I believe OP_SUBSTR could do the same thing):
- The output of the first transaction contains the full private key, but it requires that the provided signature start/end with some number of zeroes.
- To redeem, you need to modify and re-sign your transaction (using a nonce value with OP_DROP) many times to get a signature that meets the requirement. The number of zeroes required should be set so that this calculation takes only 5-10 minutes on most computers.
- To modify your transaction, the attacker needs to re-sign the transaction. However, he can't do it in less than the 5 seconds or so required because of the proof-of-work.
An 8-byte code would probably be sufficient. Each byte has 256 different possible combinations instead of the 96 with standard ASCII, so this would be stronger than a 16-character totally-random password. I'm unsure about the security of giving away a partial private key; if it's only possible to brute-force, 16 bytes would probably be enough, though I'd probably err on the side of caution with 32 bytes.
So if the arithmetic functions are enabled in Bitcoin, that's less than 20 characters you'd have to type: 8-10 characters for the transaction hash and 8-10 characters for the code. Anyone could generate these codes. It might be a useful cash-alternative among people who already trust each other, and it'd be very convenient for selling bitcoins at physical shops.
(Edit: realized how to use a salt without OP_CAT.)