What made the core developers choose C++ as the main programming language for implementing bitcoin? Was this because of their personal preference? Or another reason?
2 Answers
The most important reason is that the original Satoshi codebase was written in C++. A system like Bitcoin has extremely strong requirements about consistency in behaviour: all nodes on the network must accept and reject the exact same blocks, or we risk a fork. The first choice to avoid bugs that risk introducing inconsistency is to not rewrite the code from scratch.
Although all programming languages have flaws, and C++ is no exception, there are various reasons that make it an appropriate choice. An easily-overlooked one is that it provides very tight control over memory usage. Many modern languages (especially those that rely on garbage collection) make it hard if not impossible to reason about tight bounds of memory usage. Since Bitcoin Core is a security-critical application that is directly exposed to the Internet, it is nontrivial to guarantee that there is no way to trigger it to allocate large amounts of memory, thrashing the machine's swap space, or worse, killing the process.
This is in addition to a good balance between high-level where desired but also many avenues for performance optimization. Performance may be more important than is immediately obvious, as the convergence of the network relies on quick validation and propagation of blocks. If blocks take too long to validate compared to their creation frequency, economic factors start to unfairly advantage larger/faster miners (see the Selfish Mining attack, for example). Under extreme conditions, if blocks would take ~minutes to validate, the network may fail to converge at all, as nodes simply don't hear about blocks in time anymore.
-
5"A system like Bitcoin has extremely strong requirements about consistency in behaviour" which is exactly why Ethereum promotes a diversity of implementations. The Satoshi codebase formed a de facto standard, to write a competing implementation is to stress-test the specification.– spraffCommented Sep 5, 2016 at 13:42
-
8"make it hard if not impossible to reason about tight bounds of memory usage" Right, because having tight control over memory usage has never caused security issues... heartbleed.com– NPSF3000Commented Sep 5, 2016 at 14:27
-
1@spraff And everyone runs the same one, because they're afraid of differences. In consensus systems, variety simply doesn't work. Even the satoshi client cannot just change rules of the network. Commented Sep 5, 2016 at 14:32
-
@NPSF3000 Fair point, but modern C++ hardly ever needs manual memory management (as opposed to C), though it does become harder when you want to avoid relying on over-eager copying. Commented Sep 5, 2016 at 14:33
-
1Sure, and Bitcoin also has a variety of clients (even Bitcoin Core's unit tests are reimplemented in Python), which helps with finding problems. But it's not a guarantee, and you shouldn't use reimplementations in production. That's just asking for problems. N different implementations means ~N^2 combinations of sources of possible inconsistencies. Commented Sep 6, 2016 at 9:12
I gave a keynote address at cppcon 2016 about almost this exact issue. There are a variety of reasons why C++ is an excellent language choice for blockchain applications like Bitcoin.
Blockchain applications have a large attack surface. They're meant to interoperate with a large number of untrusted endpoints while still providing reliable service to local clients. This requires keeping tight control over resources like memory and CPU usage.
Modern CPUs have lots of cores. Some parts of blockchain applications parallelize perfectly (like checking digital signatures) while some parts don't parallelize at all (like executing transactions in order). Modern C++ has a very good mix of effective inter-thread communication and optimization of single-thread performance.
C++ doesn't have a run time that stops the world or manages memory, giving your application consistent control over this behavior. Move semantics allow you to get objects that behave like values (a=b; a+=1;
does not change b
) but perform like references (deep copies are avoided except where needed).
Smart pointers allow you to avoid the costs of GC without the tedium of manual memory management. Design patterns like RAII makes code easier to maintain. Template metaprogramming facilitates independence between APIs and implementations.
C++'s inheritance scheme makes the design of complex type hierarchies easier.
The language is both mature and maintained. The compiler technology is extremely solid, yet new features are still being added. And the new features are aimed at solving real issues. Debuggers and analytical tools of all kinds are available for everything from performance profiling to automatic detection of issues of all kinds.
-
4Upvoted. This goes into more detail than my own answer. Commented Sep 6, 2016 at 8:58
-
But to summarize, there's no mandatory point why it has to be C++ right?– IniCommented Mar 25, 2018 at 16:19
-
1No. Other languages have advantages and disadvantages, but I think performance would have suffered with any other choice (but C). Commented Mar 26, 2018 at 8:00
-
1C is not the only language that compiles to machine code Commented Jul 25, 2018 at 4:20
-
"C++ doesn't have a run time that stops the world or manages memory, giving your application consistent control over this behavior."-> but it does! C++'s runtime is the one taking care of freeing memory when you don't do it explicitly. So you're actually pitting your ad-hoc, unnoticed memory management with a purposefully developed GC – which would have saved you from a whole class of bugs. And, according to C++11's memory model author Hans Boehm, you are possibly causing worse pauses than those caused by a GC.– hmijailCommented Jul 31, 2018 at 2:24