The DAO and Second System Syndrome
A few days ago a lot of money was stolen — or maybe not, it depends on who you ask — from the DAO. The DAO is (well, was) a $150M pool of digital currency managed by a new kind of smart contract.
This heist is a fascinating event if you are interested in distributed programming environments, digital currencies, or computer security.
The people who programmed the DAO’s smart contracts were, like a lot of us who make new things, very optimistic about their work! They launched in spite of credible warnings about potential flaws in their contract code. As the amount of money contributed into the DAO grew, there was a lot of cheerleading about the success of the project.
With the benefit of hindsight, this looks naive, at best, and fraudulent, at worst.
Digital currency boosterism tends to overlap pretty strongly with a libertarian world view. The most vocal proponents of Bitcoin, Ethereum, and the DAO are explicitly interested in decreasing the power of national governments, central banks, and large financial institutions. These arguments for “money without government” are essentially political in nature. They have very little to do with engineering qua engineering.
But to me, personally, the engineering aspects of the DAO’s failure are much more interesting than the political ones. And, relatedly, I think it’s possible to use engineering as a way to talk about about fundamental issues surrounding digital currencies with people who don’t always share my political assumptions.
So, as a software engineer with twenty years of experience building distributed systems, here are three things that the failure of the DAO highlights, for me.
The DAO’s smart contracts had no external specification.
There is no formal specification for the DAO’s smart contracts. The implicit assumption is that the code itself is all that’s needed. Descriptions of what the smart contracts are supposed to do — and how the code is supposed to work — are only for marketing the DAO or explaining it to lay people.
That’s not an approach that any professional developer of mission critical systems would endorse. People who write code for medical devices, industrial equipment, telecoms equipment, traditional banking back ends, and other “must always work” systems spend a lot of time and care on specifying what they need their code to do.
Writing complete specifications is hard. But writing bug-free code without specifications is impossible.
Ethereum contracts are written in general purpose programming languages.
When I first heard about Ethereum, my initial thought was, “oh, cool, a great opportunity to use formal verification techniques in the context of a big, interesting, real-world platform that lots of developers will use.”
But the Ethereum Virtual Machine wasn’t designed with formal verification in mind. In fact, rather the opposite. The Ethereum creators have focused on making the platform accessible to programmers who normally work in languages like Python and Javascript — languages that are great for application development but not at all suitable for designing complicated state machines that are fully analyzable and auditable.
It’s certainly possible that I’m recapitulating the “worse is better” argument. And that, historically speaking, I’m on the wrong side of it. But financial systems are serious business, in every sense, and it’s worth thinking about whether the Ethereum platform as currently designed is suitable for handling large amounts of money.
The DAOs conception of smart contracts is an (interesting) example of second system syndrome.
When in possession of a crufty old code base, the engineer’s natural inclination is to rewrite it. To fix all the bugs. To start from scratch with the benefit of modern tools and current experience.
That’s never the right thing to do. Joel Spolsky’s story about the Netscape rewrite is a great blog post. Fred Brooks’s book The Mythical Man-Month is the great long form meditation on software engineering.
Both Spolsky and Brooks describe, in detail, why old code bases are better than new ones. Engineers always — always — underestimate the risk of rewriting existing code. Old code bases accumulate important “knowledge” over time in the form of bug fixes, subtle handling of corner cases, and feedback from real-world use. And this critical accumulation of knowledge is much less easy to see than the complexity and “ugliness” of old code.
The DAO website says that the operation of the DAO is governed not by traditional contract law but only by the smart contracts code:
“The terms of The DAO Creation are set forth in the smart contract code existing on the Ethereum blockchain at 0xbb9bc244d798123fde783fcc1c72d3bb8c189413. Nothing in this explanation of terms or in any other document or communication may modify or add any additional obligations or guarantees beyond those set forth in The DAO’s code. Any and all explanatory terms or descriptions are merely offered for educational purposes and do not supercede or modify the express terms of The DAO’s code set forth on the blockchain; to the extent you believe there to be any conflict or discrepancy between the descriptions offered here and the functionality of The DAO’s code at 0xbb9bc244d798123fde783fcc1c72d3bb8c189413, The DAO’s code controls and sets forth all terms of The DAO Creation.”
This language is an attempt to make the smart contract code be the legal contract that governs the operation of the DAO. It’s an attempt to rewrite contract law. From scratch! No messy legalese. No pesky lawyers. Just the code.
It’s a classic example of second system risk, but with a twist. The DAO authors aren’t just attempting to replace some computer code with newer code. They are attempting to replace the huge, messy, complicated operation of the civil legal system with their tiny, self-contained, smart contracts code.
The problem is that the legal system is messy and complicated for the same reason that old computer code bases are messy and complicated, but even more so! The law is messy because the real world is messy. It’s complicated because it is, in a civil society, our last resort in dealing with real-world messiness.
And the DAO has run into a brick wall of real-world messiness. The obvious interpretation of the DAO’s language, above, is that the attacker who siphoned out a third of the funds in the DAO was operating fully within his or her rights. There was no “attack,” no “hack,” no “theft.” Just someone executing the smart contract code.
But this is clearly not how the creators of the DAO interpreted the siphoning. The inventor of Ethereum has proposed that the Ethereum platform itself be modified to reclaim the “stolen” money.
As Albert Wenger wrote recently, the failure of the DAO is an opportunity to learn some useful lessons about digital currencies and distributed systems.
Perhaps the most important of these lessons is that digital currencies have great potential and are of enormous interest, but they’re not separate from other human and institutional means of managing money, trust, accountability, and legality. To be useful systems, rather than simply experiments, platforms like Bitcoin and Ethereum need to build on, not seek to replace, our existing engineering, legal, and political frameworks.