I accidentally wrote a book about programmable dog-themed money: Dogecoin Tricks. (You can buy Dogecoin Tricks on Amazon too). I didn’t intend to write a book, but I had one good idea and everything snowballed from that. Because I knew the book had to have a hundred interesting ideas in it, I had to come up with a few more.
One of those ideas started with “why not do something in the physical world”, like light up a lava lamp, play a song or sound, or flash a notification across an electronic ticker.
Then I looked around my office and saw a Lord of the Rings pinball machine. (Why is that in my office? It’s a long story.) I thought “I wonder how that accepts coins” and one thing led to another.
“Wouldn’t it be cool to have an entire arcade powered by cryptocurrency?” I asked myself. I’ve been to a few restaurants, arcades, and entertainment centers where you load up a card with credits and swipe it to play games. However, that proprietary system ends up with a lot of cards with small balances. I end up with a handful of cards from places I may never return and the vague sense of unease that there are germs everywhere (probably because the last place I went featured a small army of schoolchildren sneezing on everything).
“Self,” I told myself, “surely all you have to do is close a circuit to make the pinball machine think it’s accepted a coin. How hard could that be? In fact, if you figure that out, you could make any arcade machine like one of those 1Up replicas or a cocktail cabinet or a jukebox accept cryptocurrency payments.”
While it’s not that easy, it’s not that difficult either.
How a Pinball Coin Mechanism Works
Every pinball machine is similar in some ways, but many models have important differences. I was right that the coin mechanism is a simple switch. When you add a coin, if the coin is correct (whatever that means), the mech closes a circuit just long enough to register a new credit with the machine. Then the circuit opens again as the coin drops into the lockbox inside.
All I had to do to enable Dogecoin payments was to figure out how to close that circuit temporarily. That’s simple to describe but trickier in practice.
For me to control that circuit, I either have to replace the existing coin mech or augment it. The latter seemed like less work, especially if I want to do something I can undo later. I asked for advice and ended up buying a programmable relay board–specifically the ESP8266. This board has one or more programmable relays (switches) and a wifi connection. It also has multiple power inputs, so I can power it from the pinball machine’s power supply.
Even better, there’s [Tasmota firmware])https://tasmota.github.io/docs/) for the specific board I bought, which made it much easier to program–essentially a little bit of configuration and then I could control the relay by sending a simple HTTP GET.
Sure, that’s not exactly RESTful, but it worked for my purposes.
Controlling a switch from a wifi-connected board is one thing. I needed to connect it to my pinball machine in two places. One, to get power for the board. Two, to close the circuit for the coin mech.
To do this for an arbitrary machine, I recommend reading its service manual to learn how the coin mech gets its power and how the machine’s CPU scans all potential inputs. I discovered the latter was important: a lot of things can happen at the same time (you insert a coin, push a button, pull a plunger or the ball hits a bumper or drains), so any new input from the coin mech has to hang around long enough for the CPU to notice it.
In practice, a little bit of experimenting will get you there; I ended up deciding to close the circuit for somewhere between 200 and 500 milliseconds. 300 milliseconds was enough with my setup.
Finding the right power inside the pinball machine was more difficult. I eventually discovered a 5V line with a Molex connector that I could connect to the ESP8266 board. You can see the wiring mess in the video at the end of this post. As well, there’s a better circuit diagram in my book.
How a Dogecoin Payment Works
A Dogecoin payment is as simple or as difficult as you want to make it. At the highest level, this system needs to know that someone has sent a payment to a specific address. That means I needed to create a new address for my machine (it’s insecure to reuse addresses), to publish that address where someone could find it later, and to monitor that address for new incoming transactions.
This means a few pieces of software:
-
something to generate an address (I used a loop around some Perl code using Bitcoin::Crypto
-
something to monitor the Dogecoin blockchain for transactions (I used a Dogecoin Core node)
-
some custom code to toggle the relay (I used a shell script and more Perl code)
After generating my address (storing the private key securely in a safe place), I set up a Dogecoin Core node and added the vanity address as a “watch-only” address in the Core node. This means that the Core wallet knows about this address but does not know about its private key. I also enabled a walletnotify script in my dogecoin.conf file.
Whenever this node receives a new block containing a transaction affecting the fresh address, the Core will launch the walletnotify script, which allows me to do something. In this case, that’s making a Curl request to the API on the ERC board (to prove the point) and then making an API request to a small persistent server in Perl to do things right.
That was the software configured and written.
Here’s the just-do-something shell script, balrog.sh
:
#!/bin/bash
TRANSACTION=$1
HEIGHT=$2
notify-send \
-i "$HOME/Media/arcade/balrog.jpg" \
-a "Dogecoin" \
-t 2000 \
"Balrog coin inserted from block at height ${HEIGHT} for ${TRANSACTION}"
curl http://balrog/cm?cmnd=Power1%20On
This takes two arguments, the transaction ID and the block height of the
transaction. It sends a notification to pop up on a Linux desktop, then makes a
single HTTP GET request to the relay board, which is listening on its network
as a machine named balrog
. The relay board has multiple switches; switch
number 1 is connected to the coin mech. This command tells the relay to toggle
on. I’ve already configured the toggle delay for 300 milliseconds, so after
that long the relay toggles off and the virtual quarter has passed through the
coin mech and it’s up to the pinball machine to register the credit.
You Didn’t Think It Would be That Easy, Did You?
Of course the real world is more complicated. If you’re going to do this, you’re going to need how to get power to the programmable relay. I was fortunate to find a +5V power line with a Molex connector free inside the pinball machine without electrocuting myself or ruining anything. Thank goodness for the service manual.
However, I did accidentally clear the relay’s memory at least once, which meant I had to reprogram it.
Finally, if you’re doing this in a production capacity and not proving a silly point to yourself, you need to think about what a network transaction means. Even though a blockchain like Dogecoin is generally immutable, the network has a whole can discard a transaction you’ve seen. You do get notifications about it, but you have to handle them appropriately for your business rules. Furthermore, depending on the network you use, transaction settlement time may vary between about a minute (Dogecoin, Pepecoin) and ten minutes (Bitcoin), or even more for networks without lots of hashing power. If you want to wait for several block confirmations to avoid a transaction being rolled back, you could be waiting for hours.
That’s why I used the shell script for the proof of concept, then immediately pivoted to a more robust solution. I go into a lot more detail about how to make this system better in my book, but the short version is that you want to think about a few things:
- how long you want to wait for a transaction to confirm and stay confirmed (because it may be rolled back!)
- if you want to switch machine addresses periodically if you want to sell
- credits in a batch with Dogecoin (wait for one transaction to arrive and settle) and then debit credits as users play (can happen instantly)
- if you want to track metrics on plays and machines and transactions
- if you want to handle multiple cryptocurrencies
The latter point was important; the developer named Zordiak who forked Pepecoin from Dogecoin in 2023 challenged me to accept payments with Pepecoin as well, so I went through the entire loop there (by which I mean I generated a vanity Pepecoin address, launched a Pepecoin Core, and integrated the walletnotify script).
See It in Action
Why take my word for it? Try it yourself! I used a Python script to generate attractive QR codes for both networks (that’s explained in my book too, of course), so grab your phone and scan either or both codes.
Conclusion
It’s important to remember that money is a tool, that programmable money can be programmed to do many things, and that as silly as this project was (I have my own quarters but I can put this machine on free play anytime), it meant learning a lot of things and building a few.
In a world that’s focused on building ever-more-arcane financial instruments, where rugpulls and scams abound, isn’t it time to build something fun and useless? Besides, today’s useless may spark some imagination to build something not only useful but essential tomorrow.
I’m working on an article for Perl.com to show off more of the Perl code; stay tuned!
Thanks to Brett Warden for Tasmota programming advice and helping me decode the service manual timing.