Friday, January 23, 2009

P2P Money with App Engine, OAuth, and QR Codes

In honor of National Service Day, I decided to take a day off from my regularly scheduled Ringlight hacking and work on some community service hacking. In Austin we have a complimentary currency called the Austin Time Exchange Network (ATEN). There's a lot to say about complimentary currency and its role in helping economies during a downturn. However, I want to delve mainly into the technical details of my hack, so if you're interested I recommend Bernard Lietaer. The basic idea is that you can pay people for their time in ATEN currency, denominated in hours, rather than dollars. This is quite good for situations where no one has dollars they want to spend, but they do have work they want to do and get done, such as the current economy. There's no shortage of needs or workers, only a shortage of money. So let's make our own money! Problem solved! You'll still use dollars to pay taxes, your mortgage, and Wal-Mart, but you can use ATEN hours to buy local goods and services from people in Austin that accept this currency.

The goal of this project, named Austin Time Machine (ATM) is to provide a means to withdraw electronic currency into a physical paper form (cash) and later deposit paper to an electronic account. This is particularly useful for the sorts of situations which are normally "cash only", for instance festivals where it's unreasonable to expect all of the booths to have computers and Internet. Since the paper currency is backed by a separate online currency (in this case OpenSourceCurrency.org), the ATM service doesn't need to manage things like account balance. It only needs to keep track of bill serial numbers and manage authentication to the "bank" so that it can transfer credits to and from user accounts.

So on to the technical details. The first interesting bit is that OpenSourceCurrency.org supports OAuth for authenticating users. Additionally, I implemented the whole service on App Engine, which is wonderful because I don't have to run it on my server or manage uptime. However, this meant that I had to port the python OAuth library to use the App Engine API. In particular, I had to replace all of the use of httplib with App Engine's urlfetch service. This code will be useful to anyone attempting to authenticate to external services from inside an App Engine application. This app also provides a handy example of how to write an OAuth client. It's a little bit more complicated than it needs to be, but it's not that bad if you use an OAuth library to generate the signatures and such. It's basically involves just POSTing some fields to a few URLs and providing callback URLs that the website will POST back to. You pass some tokens around this way and end up with a token which, when included in a call to whatever web service you're trying to access, will serve to authenticate you as acting on the behalf of the user.

The next component of the app is the storage of serial numbers when you withdraw bills and verification of serial numbers when you deposit. Nothing particularly exciting here. I created an App Engine Model for each bill and save and access them using the standard App Engine ORM API. This is worth checking out if you haven't used App Engine before though because it's a simple example of how it works, and it's very different than SQL. Basically you need to assign a unique (string) key to each object and this is how you access them. The mechanisms you might except from SQL such as the UNIQUE keyword are absent.

With all of the nitty gritty storage and OAuth stuff taken care of, the bulk of the application is very simple. OpenSourceCurrency.org is a Rails app and so exposes a simple REST and JSON (or XML) API to do transactions. There are a couple of gaps in the API (from the perspective of this particular app) which I work around in this code. The API only lets you transfer money from the current user to a specified destination user, and you need the userid of the destination user. For withdrawl it's easy, I transfer money from the authenticated user to my own account, since I happen to know my userid. For deposit, I perform a tricky manuever. I charge the user a 0.1 hour fee, transferring it from their account to mine just like in a withdrawl. The result of that call includes their userid in the JSON output. I then take that userid and have the ATM service log into my own account (specifying credential via HTTP Auth, not OAuth) and transfer from my account to the account of the user, specified by their userid. A bit complicated! However, I'm working with Tom Brown, creator of the OpenSourceCurrency.org API, to create a simpler API.

Finally, once you've made a withdrawl, the bill needs to be generated so you can print it. This is currently done with just a little bit of HTML. A PDF export would be nice for printing multiple bills on one page, but for the prototype HTML was of course the fastest. The QR code generation turned out to be extremely simple because the Google Chart API recently added QR code support. So the QR code is just a single HTML img tag with a URL which will automatically generate a QR code. Nice!

Feel free to play this all this stuff. Check out Tom's screencast on using the ATM, the live ATM site, and of course the source code (also available as a zip).