Minimal Bitcoin Miner in C#
Bitcoin was introduced in 2009 as a digital, decentralized currency. In the Bitcoin network there’s no central authority. Instead a public ledger of every transaction is validated and shared using peer-to-peer technology. Recently there was a surprising spike in the value of Bitcoins, making me curious to find out more of the system behind.
Bitcoin transactions are grouped and confirmed by encoding them in a block and adding it to a blockchain that is protected by strong cryptography. The cryptographic calculations aren’t provided by a central authority – instead anyone with capable hardware and mining software installed can provide computational labor to help solve the next block.
When a block is solved the successful miner (or mining pool) earns a reward in Bitcoins. (Currently 25 BTC – worth about 2500€) This is quite an incentive and so Bitcoin mining evolved into a very competitive market. Advanced mining software uses GPU’s to compute hashes a hundred times faster then possible on CPUs and there is even dedicated hardware with hashrates in the Giga-range and a better Hashrate/power-consumption ratio. Nonetheless incredible amounts of electricity (~1 GW/h) are wasted on mining Bitcoins which is basically spend calculating zillion’s of SHA256 hashes. Currently the combined network of miners calculates roughly 80.000.000.000.000 Hashes per second. Crazy stuff.
Miniminer
If you are trying to understand how Bitcoin mining software works but can’t find a reference implementation that is minimal and easy to understand (like me, 2 days ago) here’s my contribution:
Miniminer is a simple CPU based Bitcoin Miner in C#. Only about 300 lines of code but fully functional, open source and uploaded on Github.
It uses the basic GETWORK protocol to connect to pools and mines at ~400Kh/s a second. That’s not fast enough for serious mining but enough to find a valid share eventually, submit it to the pool server and be happy about the fact that you understand every single line of code that made it happen!
Hey Arno!
The jobs that clients get from mining pools to solve are a lot easier than (and independent of) the current Bitcoin difficulty. With the GETWORK protocol you seem to always get a target of difficulty 1. Difficulty 1 means a valid share requires 32 zero-bits which is easy and fast to test for. So I chose to hardcode that difficulty. A higher Bitcoin difficulty just means it takes more shares (on average) until a new Bitcoin Header is found, not that the shares are more difficult to solve.
Whenever a new header is found (approximately every 10 minutes) the current job your miner is trying to solve is obsolete. With the GETWORK protocol the only way to detect that is to ask for new work and see if the reply has changed. So both an interval of 10s or 100s would technically work. But 10s instead of 20s would double the bandwith consumption for a minimal efficiency gain. And 100s instead of 20s would mean that you’d waste 10% of your cycles solving stale problems. I just felt like 20s is a good tradeoff.
I hope that answers both of your questions!
Glad I could help!
My research was powered by google mostly. There’s a lot of good info on the bitcoin wiki (https://en.bitcoin.it), the official page or burried in threads on https://bitcointalk.org and I also looked into the sourcecode of cgminer and Diablo Miner.
Have you managed to get valid share? My one was keep failing.
Sending Share to Pool…
Server declined the Share!
Cheers!
Yeah I got a couple of valid shares myself and meanwhile there are 24 when I log into BTC Guild with the default user so it has worked for at least a couple of other’s, too.
But the pool server has to accept the GETWORK protocol and afaik that was (at least temporarily) disabled due to some denial of service attacks.
Hi i tried your miner but i get always the same
Error: “Die zugrunde liegende Verbindung wurde geschlossen: Die Verbindung wurde unerwartet getrennt..”
Translation: ” The underlying connection was closed: The connection was closed unexpectedly”
Pool:http://eu-stratum.btcguild.com:3333
So do you know how to fix this Error?
Just a hint before you hit your own facepalm: you’re connecting to a stratum server (which expects “stratum” protocol, not “getwork”… but you could use a local stratum proxy program to bridge that gap.)
yet another interesting bitcoin article http://www.businessweek.com/printer/articles/176685-the-bitcoin-mining-arms-race-heats-up
Great project, thank you very much for it.
Just a quick question to be sure:
1) The pool gives you a range of bytes to elaborate
2) You split those bytes in batches
3) for each batches you calculate the double SHA-256
4) if one of those contains 4 zeros then it is a “good result”
5) you share those results with the pool
but what exactly is the “good result”? it is a bitcoin? a part of it? I don’t quite get that part
The “good result” is a possible bitcoin. The goal is that no matter how many computing power is spend on hashing the amount of bitcoins found per timeframe (e.g. day) doesn’t vary. So the difficulty e.g. amount of zero bits required varies. All agents share the work of searching for a new Bitcoin by looking for all candidates in a specific range. You get a share of the next found Bitcoin depending on how much work you did for the pool measured by the amount of valid candidates (32 zero bits or better) you’ve found.