ESP32 Bitcoin Mining

esp32 bitcoin mining

Inspired by the ESP8266 Bitcoin miner i was curious how much better a ESP32 would perform. So i implemented the mining algorithm on it.

Bitcoin mining in a nutshell

It is simply a double SHA256 hash (hashing the output again) over the block header, a 80 byte sequence containing the version, previous block hash, merkle root (verifies the transactions), time, current difficulty and nonce.

The miner searches for a hash that is smaller than the difficulty value, that is why you can see that all all block hashes in the chain start with multiple zero bytes. To generate different inputs they vary the nonce value (and maybe time).

Demo

As demonstration you can see the double SHA256 in CyberChef, the line breaks in the input indicate the different parts of the header.

The developer reference is a also good resource to get more information.

ESP32 implementation

To make this experiment as realistic as possible i wanted to mine a real block, instead of only doing one hash. Of course with this low expected performance it makes no sense to try to find a new block (more on that later).

So i picked a already mined/known block, my choice was number 56333 from where i calculated the start parameters so that it finds a valid block with a predefined hash/computation amount.

The code uses the mbed TLS library (based on this tutorial) to do the actual hashing, in addition it checks every calucated hash, stops if it is valid or increases the nonce value and tries again… You can play around with it, i have pushed it to this GitHub repo, as PlatformIO project. The rounds variable determines how many hashes (and time) it will take.

After the mining stopped it prints the hash and the hash rate to serial, for example with 10 000 rounds:

Started mining...
Valid Block found!
Hash: 0000000000000000000740ba375bbafbb871e0e201ded9c260a8b6aa1537c3f0
With nonce: 423644052 | 0x19404b94
In 10000 rounds, 831.635000 ms
Hash Rate: 12.024506 kH/s

As you can see it achives about 12 KH/s, that is 10x as much as the ESP8266. This runs also only one core of the ESP32, utilizing both cores that means theoretically 24 KH/s!

I have implemented the FreeRTOS tasks to use both cores and in practice it is closer to 20 KH/s:

Starting Worker[0] successful!
Starting Worker[1] successful!
Starting Worker[2] successful!
Running Worker[0] on core 0
Starting Worker[3] successful!
Running Worker[1] on core 0
Running Worker[3] on core 1
Running Worker[2] on core 0

>>> Completed 0 share(s), 0 hashes, avg. hashrate nan KH/s
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[0] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[3] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[2] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
>>> Completed 5 share(s), 100000 hashes, avg. hashrate 19.650 KH/s
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[0] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[3] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[2] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
>>> Completed 10 share(s), 200000 hashes, avg. hashrate 19.722 KH/s
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[0] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
Worker[1] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[3] on core 0: Share completed with nonce: 423624052 | 0x193ffd74
Worker[2] on core 1: Share completed with nonce: 423624052 | 0x193ffd74
>>> Completed 15 share(s), 300000 hashes, avg. hashrate 19.814 KH/s
[...]
>>> Completed 271 share(s), 5420000 hashes, avg. hashrate 20.064 KH/s
[...]
>>> Completed 747 share(s), 14940000 hashes, avg. hashrate 20.185 KH/s

Here are 4 tasks running, that produces the best performance in my testing. Obviously there is some overhead from the context switching and also the Arduino logging task. Only one task per core seems to not fully utilize the CPU and six or even more tasks decrease the performance, at some point it also fails to start because the RAM is not large enough.

Note about Hardware Acceleration

The ESP32 has hardware acceleration for SHA256 but it is currently not enabled in the Arduino Framework (GitHub issue). So i changed the sdkconfig and recompiled it. like described here, just replacing libmbedtls.a. But it has actually slightly lower performance… Espressif writes also in the docs that it could be slower, so i guess this is not unusual.

Let’s get rich!

Now what can we expect from mining on the real Bitcoin blockchain?

Currently a block takes about 600s with 40 EH/s, that means 24 ZH (Zetta Hashes, 1021) total. We can do 24 KH/s (103), so on average it would take 1018 seconds or 277 777 billion hours or 11 574 billion days or 31 billion years for one block!

The age of our universe is about 13.8 billion years, so i would recommend to use more than one ESP, to waste not too many universes ;)

One block gives about 12.7 BTC (12.5 + transaction fees) = 50 000$, so that makes 0.0000015$ per year. Not much and obviously not worth it as individual.

Even if you had 100 million devices (that would be more than 3 times the size of Bredolab, the largest known botnet to date with 30 mio. infected computers) it would produce still only bitcoin fractions worth 150$ per year.

Update 2021: The network parameters changed quite a bit, so a recalculation is necessary. The total hashrate more than quadrupled to about 150 EH/s and therefore also the difficulty, because the block time is kept constant. That is bad news, increasing the time needed to find just one block to about 120 billion years…

We had a “bitcoin halving” in early 2020, the reduces the miner reward to 6.25 BTC + currently 0.7 BTC transaction fees. But at the same time the price increased, one block is now worth 250 000$! Overall with the huge imaged botnet it would be still BTC fractions worth just over 200$ per year, so after all pretty similar.