Message Boards Message Boards

Bitcoin tipping machine with Raspberry Pi and chain.com

Posted 9 years ago

The idea

A friend came up with the fun idea to build a Bitcoin tipping machine for pubs and restaurants. The idea is that it should be possible to tip with Bitcoin, and hear the traditional sound of coins falling into a jar.

The setup

  • Raspberry Pi
  • Speakers, for the coin sound
  • LCD display to show the amount tipped
  • Chain.com API to retrieve transactions to the restaurant's public Bitcoin address.
  • Wolfram Language, to tie everything together.

This is what it looks like with everything assembled: Picture of the Raspberry Pi running the Bitcoin tipping software

How it works

After signing up for Chain's API I create a query to check for transactions:

str = "https://api.chain.com/v2/bitcoin/addresses/"<>myadr<>"/transactions?api-key-id="<>chainapikey<>"&limit=10";

To retrieve this as JSON data is then as easy as:

ImportString[URLFetch[str],"JSON"]]

And to filter out all the outputs (bitcoin transactions to our selected address) we can use Cases:

Cases[outputs,{__,HoldPattern["value" -> y_],__, Verbatim["addresses" -> {myadr}], __}:> y],Infinity];

I know have all the transactions to our restaurants public address and how big they are. I can now go ahead and play the coin sound. I constructed a RunScheduledTask that checks for new transactions to the selected address every minute. This is where my initial version of the project stopped. It worked and it was fun.

LCD

The next step was to setup a LCD so that restaurant visitors could see how generous the Bitcoin guests were. I bought the Adafruit 16x2 LCD. Luckily for me, fellow Wolfram Community member BoB LeSeur had already built a library to write to the display from the Wolfram Language on the Raspberry Pi with his rpi-lcdlink. Displaying how much had been tipped could now be performed with a call to lcdPuts:

lcdPuts[transaction]

So if there's a new transaction, a sound of falling coins is played and the amount tipped is displayed on the LCD display.

Result

To see the machine in action, watch this clip on YouTube: Bitcoin tipping Machine

Future work

There are many potential expansions to this project, such as more platforms and more interactivity. And maybe display witch table has tipped the most during the night, to make it a competition? Another idea is to include onename.io name resolving to see the name of the Bitcoin tipper. Oh, and a convenient way to divvy up the tipped amount to the employees after a night of tipping...

All of the code is available on GitHub HERE or just take a look below:

(* ::Package:: *)

(*Constants*)
(*myadr = " "; *)(*Example: "1HxhvPBGuUTiu9n1sV78epGrcGTPujdDB3";*)
(*chainapikey = " ";*) (*Insert API key from Chain.com*)
(*Or store them in a credentials file*)
Get["~/bitcointipping/credentials.m"];

(*Load the lcdlink*)
<<"!gpio load i2c"
SetDirectory["~/rpi-lcdlink"]
lcdlink = Install["lcdlink"];
lcdClear[];
lcdPuts["Bitcoin tipping starting..."];
SetDirectory["~/bitcointipping"];

str = "https://api.chain.com/v2/bitcoin/addresses/"<>myadr<>"/transactions?api-key-id="<>chainapikey<>"&limit=10";
sndfile = "~/bitcointipping/assets/coins-drop-1.wav";
(*Let all previous transactions be new*)
oldhashes={};
pattern=If[$OperatingSystem==="MacOSX",
    {__,Verbatim["addresses"->{myadr}],__,HoldPattern["value"->y_],__}:> y,
    (*Raspberry Pi / UNIX*)
    {__,HoldPattern["value" -> y_],__, Verbatim["addresses" -> {myadr}], __}:> y];

(*Run loop*)
RunScheduledTask[
 data = Quiet[ImportString[URLFetch[str],"JSON"]];
 hashes = "hash" /. data;
 nrNewTransactions = Length[Complement[hashes, oldhashes]];
 If[nrNewTransactions > 0, 
  outputs = "outputs" /. data[[1 ;; nrNewTransactions]]; 
  newtransactions = 
   Cases[outputs, pattern, Infinity];
  (*Play coin sound*)
  Quiet@Run["aplay "<> sndfile];
    lcdClear[];
  If[nrNewTransactions == 1,
    onetransactionstr=ToString[First[newtransactions]] <> " satoshis tippped at " <>
      DateString[{"Hour",":","Minute"},TimeZone->$TimeZone];
    Print[onetransactionstr];
    lcdPuts[onetransactionstr],
    manytransstr=StringJoin[Riffle[ToString /@ newtransactions, " and "]] <> 
     " satoshis tipped at " <> DateString[{"Hour",":","Minute"},TimeZone->$TimeZone];
    Print[manytransstr];
    lcdPuts[manytransstr];
    ]
 ];
 (*Set the old hashes to include new hashes*)
 oldhashes = hashes;
 ,60
 ];
POSTED BY: Johan Rhodin
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract