RetroMiner

tl;dr: In taking an offhanded challenge far too seriously, I made a 1985 NES mine bitcoins

*About the RetroMiner Project

A few weeks ago, friends of mine were joking about my recent interests and how they don't understand the point of them.  I asked if they would like to hear more about the awesomeness of 8-bit videogame consoles or about the awesomeness of the technical details behind bitcoin mining.  One of them joked that they wanted to hear about how to mine bitcoins on an 8-bit game console.

Challenge Accepted.

A brilliantly useless project such as this cannot be ignored.  While the all the buzz in bitcoin mining is about dedicated ASIC silicon, I was going take inspiration from the Mushroom Kingdom.  A few late nights later, this is what I put together.

*Goal

While the challenge is to 'mine bitcoins on an 8-bit game console', lets break that down a bit.

Bitcoin mining is a process of getting recent bitcoin transaction data from the global bitcoin p2p network, concatenating a random nonce value, SHA256 hashing it twice, checking to see if the resultant hash has a more than a particular number of leading zeros, and relaying positive results back out to the bitcoin network.

So I need to:

1.  Talk to the live bitcoin network and pull recent transaction data

2.  Get the data into the NES

3.  Make the NES perform SHA256 hashing

4.  Get result data out of the NES

5.  Relay positive results back out to the bitcoin network

*Communication with the Bitcoin network

This part is pretty simple.  I'm using bitcoind to do the network communication.  This is pretty standard for bitcoin mining, the mining software focuses on doing the hashing and lets bitcoind do the p2p network stuff.  There's a few standard protocols for those two pieces to communicate with varying levels of efficiency, but I'm using the most basic 'getwork' protocol because, heh, this isn't going to be the bottleneck in this operation.

For the portions of computing that do not happen on the NES, I've got a raspberry pi housed in a Makerbot Replicator2 3D printed case.  I believe I am now fully 2013 Hack Project compliant.

Raspian's repos were serving some crusty version of arm bitcoind, so I compiled my own from the latest source.  This is not hard, except that my rpi has 256MB of RAM and g++ just gives up when its all filled up.  I'm sure there's a more elegant cross-compilation environment available, but adding a 2GB swap and letting it crank all night worked for me.

*Data in

There are a couple pieces involved in getting data into the NES, many of which I'm just pasting together from other people's code.  They deserve the credit for their respective projects.

First, I'm using a python implementation of the mining protocol by jgarzik (https://github.com/jgarzik/pyminer) to do the jsonrpc communication out to bitcoind and basic structure.

Next, I'm using a NES that I modified with a USB CopyNES (http://www.retrousb.com/product_info.php?cPath=24&products_id=36).  Inserting this board inbetween the NES's mainboard and processor adds a USB port to an NES that affords for lots of development capability, including the ability to write to RAM carts.  The RAM cart I'm using is a PowerPak Lite, also from retrousb.com (http://www.retrousb.com/product_info.php?products_id=35)

For the USB serial communications to the NES I've gutted and hacked up mstrand's script (https://github.com/mstrand/copynes)

So the rpi getworks a chunk of data, wraps it up into a ROM (detailed below), and sends it to the console using via USB CopyNES.

*Doing the hashing

SHA256 hashing uses many 32-bit operations, and the 6502 in the NES is an 8-bit CPU.  Initially I thought this would be a significant challenge, but with some modifications, I got an open implementation of SHA256 to compile to a 6502 target using the cc65 compiler (cc65.org)

The rpi getworks a chunk of data, compiles it into a ROM that includes the SHA256 algo and current target data, and sends it to the console via USB CopyNES.

Each ROM computes and tests a single hash.

*Data Out

After the NES computes and tests the hash against the target value, the NES knows if this iteration was a success.  But we need to pass successes back out to the bitcoin network.

If the generated hash is less than the target value, the background color of the screen will be green, otherwise it will be red.  A Playstation Eye camera pointed at the screen takes a picture and, using OpenCV, checks for the predominant color in the image.

If there's more green than red in the picture that the webcam snaps then it gets reported out to the bitcoin network as a success.  If not, then we start the process over again with a freshly grabbed chunk of getwork data.

*Summary

It works! My NES is chugging along, searching for blocks.  He's actually getting workunits from slush's pool (http://mining.bitcoin.cz/) so there's a chance that he'll get some credit for hitting a proof-of-work slice (rather than only going for whole blocks)

While I have made an NES mine for bitcoins, there's room for possible improvements:

*Test more than once per iteration.  Currently its only testing once static nonce per iteration, 0x000000269.  I would need to improve the method for getting data back out the NES beyond red/green pass/fail.  I attempted to do OCR with the webcam pointed at the screen, but the capture was not clear and many characters looked too similar.  Replacing the webcam with a video capture card would be an improvement, but is just an incremental improvement.

*Better methods for data in and out of the NES.  What I'm doing now is very slow, and I admit, pretty lame.  The EXT port on the bottom of the NES affords DMA access to the NES's memoryspace (I believe), and would let the console process hashes a much larger percentage of the runtime.  This could also remove the need for the USB CopyNES.

*Machine code hash implementation.  While compiling the C implementation works, reimplementing in 6502 ASM would be more efficient and lead to a faster hash rate

*Move more parts of the process to the NES, and fewer parts in python on the raspberry pi.  I don't know of any tcp/ip stacks for the NES, and ENIO project (http://enio.chykn.com/wiki/index.php/Main_Page) hasn't had any recent updates.  It would be cool to create a cart that contained everything necessary to start hashing without a tether to an intermediary computer.  Pop in cart, hit power,

Hit me up on twitter @__gbg__ , or via email at gbgbgbg ((at)) rocketmail ((dot)) com

Or comment here http://www.retrominer.com/blog

Mining on my NES isnt going to make me rich.  If you like the hack, Send donations to 196Hk6Qmxwv7PwpeyhpyNZaTiuSbPAdC3A