Kaffe med Bitcoin

(This article was originally published by Datormagazin. Republished with permission)

Kaffeautomat med bitcoin

Den krypto-anarkiska valutan Bitcoin är i ropet i media. Nästan varje dag kan man numera läsa artiklar i dagspressen om Bitcoins för och nackdelar.

I den här artikeln presenterar vi en enkel tillämpning av Bitcoin för handel, exemplifierat med en kaffeautomat. Under resans gång får vi inblick i praktiska för och nackdelar med den nya valutan.

Det är enkelt att komma igång med Bitcoin om man jämför med andra digitala betalningsformer som SMS-betalningar, kortbetalningar, etc.

SMS-betalningar, som ligger närmast tillhands i vårt exempel med betalautomat för kaffe, kräver i allmänhet en startavgift till operatören, samt provision för varje transaktion. Provisionen varierar, men på fem kronor som din kund betalar, får du själv strax under tre kronor.

Med Bitcoin betalar du en försumbar provision, och tar istället hem hela vinsten själv. Detta är självklart väldigt lockande. Visserligen är Bitcoin idag inte en lika användbar valuta som Svenska Kronan, men det kan komma att förändras.

Det här behöver du som handlare:

  • En Bitcoin-adress, som du som skapar själv med en Bitcoin-klient.

Du använder kontot för att ta emot betalningar från kunder.

I vårt fall kommer vi att använda bitcoind, som stödjer ett JSON-API, och därför är lämplig för att implementera automatiserade betalningsflöden.

  • En QR (Quick Response) kod som beskriver ditt konto och din önskade betalning.

Vi kommer att visa hur man kan genererar en QR kod, dels manuellt, dels programmatiskt.

Det här behöver du som kund:

  • Ett Bitcoin konto, på samma sätt som handlaren.

  • En bekväm Bitcoin-klient, till exempel för Android, som kan avläsa QR koder. På så sätt får kunden kontoinformation och belopp.

  • Fylla på Bitcoin kontot på något sätt. Det enklaste är antagligen att köpa Bitcoin av någon leverantör.

Kaffeautomat, nivå 0

Det enklaste sättet att realisera betalningar är självklart att ställa ut en spargris där kunderna får lägga sin kontanta betalning och där handlaren sedan får lita på det sociala kontraktet och utgå från kunderna betalar för sig.

Kaffeautomat, nivå 1

Vi skall se att det går att införa Bitcoin-betalningar nästan lika enkelt som spargrismetoden. För detta behöver vi en QR kod, som vi skriver ut på ett papper, som placeras i närheten av kaffeautomaten.

På samma sätt som i spargrisfallet får vi lita på kundernas ärlighet.

Det första vi behöver är som sagt ett Bitcoin-adress. Det enklaste är att installera bitcoind och skapa konton i den grafiska klienten bitcoin-qt. Funktionen finns under Receive/New Address. Skapa en adress med namnet "coffee".

En person kan ha många adresser. Vår coffee-adress kommer bara att användas för att ta emot kaffebetalningar. Detta innebär att vi får en tydlig bokföring på köpet, eftersom vi kan följa alla transaktioner på kaffekontot, skilt från andra konton.

Nu skall vi ta fram en QR kod som representerar vårt önskade pris.

QR koder togs först fram inom bilindustrin och är lätta och tillförlitliga att avkoda maskinellt. De kan användas för att koda text, ofta en Uniform Resource Identifier(URI). Bitcoin-valutan har ett eget URI-schema, som definieras här:

https://en.bitcoin.it/wiki/URI_Scheme

Vi bestämmer först ett pris, tex 5 kr per kopp.

Med den i skrivande stund rådande växlingskursen mellan Bitcoin och svenska kronor blir det ungefär 0.0054 BTC. Det är relativt få valutakonverterare på nätet som stödjer bitcoin, men https://openexchangerates.org/ gör det, och de har även ett API vi senare skall använda för att konvertera automatiskt mellan valutorna.

Här uppstår ett problem: Växlingskursen mellan BTC och SEK kan variera kraftigt bland annat för att valutan ännu är liten och känslig för spekulation. Vi har det i åtanke, men går vidare med vår första enkla lösning.

bitcoin-qt har en inbyggd funktion för att generera QR koder.

Välj funktionen "Show QR Code" och för in värdena från ovan. QR koden visas, samt den Bitcoin-URI som QR koden representerar.

Spara QR koden som bildfil, och skriv ut den, till exempel med Gimp eller webbläsaren. Sätt upp den vid kaffemaskinen och invänta dina första kunder!

Kunden behöver en Bitcoin-plånbok, exempelvis "Bitcoin Wallet" på Google Play.

Plånboken har stöd för att scanna QR koder och utföra transaktioner.

Nu märker vi dock nästa problem: Det kan ta en lång stund för köparens Bitcoin att dyka upp på handlaren Bitcoin-konto. Det beror på att Bitcoin-nätverket behöver tid på sig för att granska och godkänna transaktioner.

Det är knappast rimligt att låta kunden vänta, så även av den anledningen tillämpar vi det sociala kontraktet, och litar på att våra kunder faktiskt betalar för sig.

Sammanfattningsvis, för version ett av kaffeförsäljning:

  • Det är mycket enkelt att sätta upp för handlaren, vi behöver bara en utskriven QR kod samt tillit till våra kunder.
  • Kunderna har även de relativt lätt att komma igång, men att köpa Bitcoin kan upplevas besvärligt.

Kaffeautomat, nivå 2

Vår första variant av Bitcoin-betalning är föredömligt enkel att sätta upp, men har som vi lagt märke till några problem.

Om man till exempel studerar de historiska växlingskurserna mellan BTC och USD kan man se att de periodvis har varierat väldigt kraftigt. Våren 2013 var en sådan period.

Vår utskrivna QR kod kommer alltså snabbt att representera något annat än vad vi tänkt oss. För att slippa ta antingen under eller överpris för kaffekoppen, kan vi generera QR koden dynamiskt och visa den på en skärm. Kunden scannar sedan koden från skärmen istället för från ett papper. Detta kan vi lösa med en webbsida som uppdateras automatiskt.

För att åstadkomma detta behöver vi några verktyg:

  • En metod att konvertera mellan svenska kronor och Bitcoin, så vi kan ha ett uppdaterat bitcoinpris på kaffekoppen i vår QR kod.
  • En metod att skapa en bildfil med QR koden dynamiskt, så att en webserver kan läsa den och vidarebefodra den till en klient.

Vi har publicerat en färdig lösning på https://github.com/jave/btc-coffee, men innan vi går närmare in på hur den fungerar i detalj, går vi igenom alternativen och principerna steg för steg.

https://openexchangerates.org/ tillhandahåller ett ganska enkelt Json baserat API för att konvertera mellan valutor. Vi tar inte ställning till kvalitén på växlingskurserna, men API:t är hur som helst relativt bekvämt att använda och stödjer Bitcoin, vilket flertalet konkurrerande tjänster inte gör.

För att använda openexchangerates API behöver man ansöka om en api-nyckel, som man sedan använder för att identifiera sig vid anrop till tjänsten.

Ett exempel på resultatet återfinns i kodruta ett.

Man får hämta växlingskurserna ur Json strukturen med det programmeringsspråk man använder. Vårt eget exempel är gjort med Clojure, som är en Lispdialekt ovanpå Javas virtuella maskin. Det är en bekväm utvecklingsmiljö, och vår exempelkod är tillräckligt enkel för att kunna konverteras till någon annan miljö om man föredrar det.

Kodruta två innehåller ett exempel på valutakonvertering.

Nästa steg är att skapa QR koden. I version ett av vårt system skapade vi koden manuellt med hjälp av bitcoind-qt. Vi kan inte använda den metoden längre, när vi nu skall generera QR koden automatiskt.

Eftersom QR koder är en etablerad standardteknik finns en uppsjö lösningar.

Zxing är ett beprövat bibliotek som används i många applikationer. Koden finns på https://code.google.com/p/zxing/. Det finns även en möjlighet att direkt testa biblioteket via en webtjänst.

Prova att genera en QR kod via gränsnittet, genom att välja alternativet Text och ange en Bitcoin-URI. Du skall kunna scanna QR koden direkt från websidan.

Ett exempel på att anropa biblioteket från kod återfinns i kodruta tre.

Återigen, det finns en uppsjö av exempel på hur man använder Zxing om man föredrar någon annan plattform.

Nu har vi alla byggstenar vi behöver för att generera QR koden och leverera den till en hemsida! Det kvarstår självklart en hel del klister för att binda ihop det hela, och för detta refererar vi till det färdiga kodexemplet.

Sammanfattningsvis, för version två av kaffeförsäljning:

  • Det är mer komplext för handlaren att sätta upp. Vi behöver någon form av skärm som kan visa en dynamisk webbsida. Vi behöver även en webbserver som kan leverera webbsidan. Handlaren måste även fortsatt hysa tillit till sina kunders ärlighet.

  • Kunderna har oförändrad komplexitet.

Kaffeautomat, nivå 3

Nästa steg i vår vidareutveckling av vår tjänst är att kontrollera att vi faktiskt mottagit en betalning från vår kund.

Som vi konstaterade i nivå ett kan det ta lång tid innan en transaktion godkänns av bitcoin-nätverket. För att förhindra ett antal potentiella attacker önskar nätverket att varje transaktion skall godkännas av ett antal noder i nätverket. Det är detta som garanterar att vi får in våra bitcoin på vårt konto, och även detta som gör att det tar tid.

Transaktionerna går egentligen direkt ut på bitcoin-nätverket, och det är möjligt att upptäcka inkommande transaktioner relativt omgående, om man är villig att tumma på säkerheten. Det kan man göra genom att sänka kraven på verifiering av transaktioner.

För att gå vidare behöver vi något sätt att programmatiskt kommunicera med vår bitcoin-demon. Både bitcoin-qt och demonen bitcoind tillhandahåller ett Json API. Bitcoind är bättre att köra i serversammanhang, medans bitcoin-qt kan vara bättre när man laborerar.

Bitcoind fungerar också som klient, vilket kan vara förvirrande.

Starta bitcoind i demonläge:

1bitcoind -daemon

Sedan, för att lista transaktioner på vårt kaffekonto:

1bitcoind listtransactions coffee

Bitcoind används alltså i det senare fallet som en klient som skickar Json kommandon till bitcoin demonen som kör i backgrunden.

För att få en översikt över tillgängliga kommandon kör man:

1bitcoind help

Eftersom protokollet är nätverksbaserat kan man i princip köra bitcoin demonen på en maskin, och klientprogrammvara på en annan maskin. Det kräver naturligtvis att man säkrar upp nätverket mellan maskinerna. För enkelhets skull utgår vi från att klient och demon körs på samma maskin och med samma användare, men det är relativt enkelt att ändra.

Det vi nu vill åstadkomma är att ge kunden någon form av återkoppling via vårt webgränsnitt att transaktionen är accepterad. En metod är att periodiskt kontrollera kontobalansen på kaffekontot och se om det kommit in några bitcoin:

1bitcoind getbalance coffee 0

Det numeriska argumentet anger hur många valideringar man önskar, noll betyder alltså att vi inte kräver några valideringar. Vi kan alltså i princip bli lurade på fem kronor, även om risken egentligen är liten. Vi bör alltså inte använda denna uppsnabbade metod för att sälja hus eller bilar.

En annan metod som är möjlig från och med bitcoind version 0.8.3 är flaggan -walletnotify.

Vi kan alltså ange ett kommando som körs när vår plånbok nås av en transaktion. Kommandot kan till exempel göra ett RPC anrop mot en webbtjänst.

Eftersom vi notifieras för varje transaktion som involverar vår plånbok, och dessutom kan få samma notifiering flera gånger, behöver vi kunna se vad transaktionen innehåller:

1bitcoind gettransaction <trtansactionsID>

Vi får då en Json-struktur som innehåller ett antal fält, bland annat antal Bitcoin, och kontonamnet.

I vårt program använder vi en enkel wrapper ovanpå bitcoind, Pawnshop, som är publicerat på Github.

Först skapar man ett proxy-objekt. När man har proxyn kan man utföra kommandon mot bitcoind. Koden för detta finns i kodruta fyra.

Nu börjar det bli mycket att hålla reda på så vi går summariskt igenom processen:

  • Kunden scannar QR koden från vår skärm med sin bitcoin applikation
  • transaktionen når bitcoin nätverket, och vår bitcoind
  • vår bitcoind anropar ett kommando som vi angivit via -walletnotify.

Detta kommando anropar i sin tur vår webbtjänst

  • Webbtjänsten kontrollerar att transaktionen är relevant och notifierar sedan kunden.

Kaffeautomat, nivå 4

Nu har vi skapat ett system för att hantera Bitcoin betalningar, och kan känna oss ganska nöjda!

Som ytterligare en förbättring kan vi automatiskt slå på kaffemaskinen när vi fått in en betalning.

I vårt exempel använder vi en Tellstick Net som kontrollerar en trådlös fjärrströmbrytare. Vår webtjänst skickar ett kommando vid inkommande betalning till vår Tellstick, som sedan slår på kaffemaskinen.

Tellstick Net har ett Json baserat API som kallas Telldus Live. Man registrerar sin Tellstick Net i Telldus Live, sedan kan man fjärrstyra sina enheter dels via web, dels via API. För att kunna använda API:et måste man begära nycklar via Telldus live. API:et använder autentiseringsstandarden OAuth.

För att experimentera med automatisering med Tellstick använde vi https://github.com/auno/telldus-live-cli som är en Ruby-baserad kommandoradsklient.

För att slå på och av en enhet:

1ruby telldus-live.rb  turnon <enhets-id>
2ruby telldus-live.rb  turnoff <enhets-id>

Vi kan anropa dessa kommandon från vår webbtjänst.

Nu har vi alltså uppnått att kunna slå av och på kaffemaskinen med hjälp av Bitcoin!

Summering

Vi har nu ett fullständigt system för att praktiskt kunna handla med Bitcoin. Systemet vi beskriver är enkelt att komma igång med, men vi kan nog inte i vårt fall räkna med att få tillbaka investeringen i utrustning på kaffeförsäljning. Vårt exempel skall ses som en illustration av möjligheterna. Lycka till med ditt eget experimenterande!

kodrutor

kodruta 1 : respons från openexchangerates

1{
2  "timestamp": 1378029660,
3  "base": "USD",
4  "rates": {
5    "BTC": 0.00712043,
6    "SEK": 6.622343,
7  }
8}

kodruta 2 : Funktion för valutakonvertering

1(defn curconv "convert between currencies"
2  [amount from to oxc-key]
3  (let [rates (get (get (client/get (format  "http://openexchangerates.org/api/latest.json?app_id=%s"
4					     oxc-key) {:as :json}) :body) :rates)]
5    (* (* amount  (get rates to)
6	  (/ 1  (get rates from))))))

kodruta 3 : Funktion för QR kodgenerering

1(defn qr-encode-to-file
2  "qr encode to file"
3  [uri filename & {:keys [size] :or {size 1000}}]
4  (com.google.zxing.client.j2se.MatrixToImageWriter/writeToFile
5   (let [mw  (new com.google.zxing.MultiFormatWriter)] (.encode mw uri com.google.zxing.BarcodeFormat/QR_CODE size size ))
6   "png"
7   (new java.io.File  filename)))

kodruta 4 : Kod för att kommunicera med bitcoind

1(def bitcoin (bitcoin-proxy "http://127.0.0.1:8332/" "yourlogin" "yourpassword"))
2(bitcoin :getreceivedbyaccount "coffee" 0)

faktarutor

Mer om e-handel med Bitcoin

Besök gärna http://www.btching.com där vi beskriver Kaffeautomaten och andra Bitcoinbaserade e-handelsprojekt i detalj!

bildtexter

1_cofee_btc_qr.png Ett exempel på en skarp QR kod för en Bitcoin-betalning

2_level_1.jpg Kaffeautomat version ett, utskriven QR kod

3_level_2.jpg Kaffeautomat version två, dynamisk QR kod på skärm

4_switch.jpg Kaffeautomat version fyra, Tellstick NET

5_tellsticknet.jpg Kaffeautomat version fyra, Fjärrströmbrytare