What are NFC tags?Writable NFC tags like the
Mifare 4k are interesting because they are cheap, approximately the thickness of a credit card and offer unpowered read/write data storage. This makes them ideal for building a super cheap Bitcoin "tip jar" that offers good privacy for the tipee and can be integrated into a poster or drinks mat, just with some sticky tape. The user would tip by simply touching their phone to the NFC tag ... and that's it. No further interaction is necessary. It would be as easy to send money this way as putting coins into a charity box is today.
The problemNFC tags have no battery and no CPU. We can embed a bitcoin URI into a tag such that it'll open up your Android wallet app very easily, nothing special is required for that (there are tag writer apps in the Play Store). The problem is that you can only embed one public key/address into the tag, which means you lose a lot of privacy - anyone can see how much you've received and when, also they can see when you move the funds and so on. All the same problems that putting an address into your forum sig has, so does this.
I think we have consensus that we need to move the Bitcoin world away from just throwing up static addresses globally linkable to users identities. It inevitably can cause surprising and unintuitive privacy leaks. I've been pushing the idea of an HTTP based payment protocol for a long time now, it's an obvious idea and Pieters discussion of it at the conference is a great next step.
Unfortunately because NFC tags are just dumb storage, you can't have them take part in a payment protocol. It appears you can choose between private and cheap - pick one.
The solutionFortunately we can improve things in the following way. Write to the NFC tag a header packet containing a public key and an offset counter, which is initialized to a random number. The header can also contain other data you might find in a payment URI like a message and a suggested amount. Now fill the rest of the tags storage with random numbers too.
When the user wakes up their phone and touches it to the tag, it reads the header packet and inserts a new private key into the wallet. It crafts a transaction that spends the suggested amount of Bitcoin to the newly created private key and stashes it away for later. The private key is then encrypted under the public key found in the tags header and written to the part of the tag indicated by the offset counter. The offset counter is then itself incremented and if necessary, wrapped around to zero.
The app puts a notification icon in the users notification bar, makes a sound, vibrates etc but
does not request any confirmation. Instead the transaction is kept around for 10 minutes or so and if the user doesn't explicitly cancel it, broadcasts it at that time. The user can also adjust the value being sent to the new private key if they aren't happy with the default suggested amount. Even once the transaction is broadcast, it can still be revoked until the next step, which is why it's safe to just have the act of touching trigger payment - the user can undo unexpected payments easily.
Every so often the tip collector comes past with a dedicated app running on his phone and touches the tag. This loads all the private keys that were written to the tag, decrypts them and inserts them into a fresh wallet that is then synced with the chain. The app then proceeds to spend each donation to a newly generated key (per donation) thus preventing the user from reclaiming it and locking in the payment.
This scheme has the following useful features:
- Users who touch the tag cannot find out how many donations there were/when they were made/how big they were, because the offset counter was initialized to a random value and wraps around, so the value is meaningless.
- They can't read the data to figure out how many keys there are because encrypted private keys are just random numbers too so you can't tell the difference.
- Because the transaction isn't actually committed until some time after the touch, the act of tipping can be just switching on the phones screen with the hardware button and then touching it to the tag. It's a 3 second job. If the user donates accidentally they can just undo the action.
- The only expensive part of this is the smartphones, which many people have already. Because NFC tags are so cheap and the software would be free, absolutely anyone could use this scheme without any technical knowledge being required. They'd just have to "empty the jar" every so often.
Example applications- Sticky-tape a few tags to the back of a project poster at a fair and then print suggested tip amounts over them, so you donate by touching the phone to the part of the poster that has the amount you want to tip.
- Whilst doing a live show/speech/whatever give out a smartcard that contains an NFC tag. The crowd can pass it around and put money in whilst you're performing. You collect it and empty it at the end.
- At a restaurant or bar the waitress can put their personal tipping card on the table when they first come over and collect it at the end. This is probably simpler than trying to integrate tipping directly with the payment for the meal itself.
Other notesYou might wonder why I'm focusing on tips and donations here. The reason is the revocability - to get the one-touch experience you have to allow the user to undo it for a short while afterwards. Also, nothing stops somebody from erasing the contents of the card or otherwise screwing with it, so there needs to be a bit of pre-existing trust for it to work.
There's one other attack that can cause problems - an evil person could swap out the legit tag for their own, or just rewrite the existing tag. Because tags don't have any kind of verified identity you could end up donating to the wrong person by mistake. If people wanted protection from that, a lightweight kind of certificate authority setup could be made. The header would include a signature from a trusted authority over the public key/suggested amount and message. The authority would only sign if the message wasn't confusing and matched the identity of the tipee they are verifying. It's probably not required for v1.