Blockchain Control Flow
This is the first in hopefully a series of posts about the current state of bitcoin and blockchain platforms. There are many widely-held but incorrect ideas about what blockchains are, how they work, what they're actually good for, and where we go from here.
Much of the original foundation of the cryptocurrency community - decentralisation and self-sovereign computing systems, has pretty much vanished in newer projects in the ecosystem. What we're seeing now are fundamentally different systems that flip the switch back again by moving control into the network, creating networks that empower those in control.
Although it's not the only project to that's moved in this direction, much of the blame for this lies on ethereum, because its design reduces the power of the user in favour of the network, which inherently increases the minimum level of trust required, removing sovereignty - or control - from the individual.
Jude from Blockstack wrote a good article a while back which touched on the topic, but I want to think a bit more in depth about the way that ethereum works and compare it to Bitcoin, as they are two fundamentally different approaches. Ethereum is a serial virtual machine complete with control flow, while Bitcoin just handles dataflow, with external (or client-side) control flow. When we compare the two systems, it's clear that the peer-to-peer, trustless nature of Bitcoin is crucial to its future outlook.
I think the best way to do this is to go back to ethereum's whitepaper, and think about Vitalik's initial motivations in our current context. Then we can determine whether removing certain protections in ethereum's model actually made sense.
Private vs. Public
Blockchains are inherently systems for managing the verification of publication events. Every publication has two lives - pre-publication and post-publication. Prior to being published, a transaction is authored. In a peer-to-peer system, this phase is private. As long as a valid transaction has not been published, control over any future action that may come about as a result of publishing that message is held by those with the ability to transform it into a valid transaction (like signing it with a private key).
We can model this relationship over time, and a typical transaction output has a basic binary state transition when it is signed by a valid private key. The message transitions from private to public / invalid to valid / unpublished to published. Before the transaction is published, all the control over how the money is spent is held by the user, or more simply, the rights holder of the unspent output in question.
Here it is laid out - on the left we've got the private individual, and the right side is the public network of validators - miners or peers. When a transaction is signed, it's in a Schroedinger state - where it's a valid transaction, and so the money has been spent, but if the message isn't published, it could still be double spent. It's important to distinguish between the two, because you could be hacked, or a conflicting transaction could be published at the same stage. Either way, as soon as the transaction is signed, control over the acceptance of the transaction is accepted is up to the network.
For a peer-to-peer network to be politically decentralised, it needs to have decentralised control, so we should at all times try to keep control completely in the private section, typically known as the principle of least authority. In a p2p email network, only the sender and receiver should ever see the message, and the influence of any intermediary should be minimised. In financial systems, completely privatised control is not possible, since transactions must always be validated by at least one third party as the recipient of a transaction needs to know that the money wasn't double spent.
Usually when we consider the differences between ethereum and Bitcoin, the discussion focuses on 'smart contracts'. I think that's really strange.
Nick Szabo's definition is great, because it's pretty explicit about the fact that contracts require delegating execution and validation of code to third parties. Here's his definition:
a computerized transaction protocol that executes the terms of a contract. The general objectives are to satisfy common contractual conditions (such as payment terms, liens, confidentiality, and even enforcement), minimize exceptions both malicious and accidental, and minimize the need for trusted intermediaries. Related economic goals include lowering fraud loss, arbitrations and enforcement costs, and other transaction costs.
If we take a step back think about it, we realise that blockchains are actually themselves smart contracts. Completely open ones. When people say that money is a social contract, they really mean it. The protocol that clients run to collaboratively build the block chain is "a computerized transaction protocol" that "minimises the need for trusted intermediaries". What's special about it is that it minimises trust by including the whole world as a counterparty.
Which means that there is really nothing 'autonomous' about a smart contract. They should be automated, but they're still explicitly being executed within a remote (often hostile) environment - and you've got to trust that environment collectively to execute it as you expected. Again, a big argument for keeping things at the edge of the network and out of the protocol. Because a 'smart contract' is code that is run by someone else, we should avoid giving them control without question.
If Bitcoin is a smart contract, and ethereum is a smart contract, then what's the difference in complexity? Well, really nothing, just that separation between the division of labour between network and individual. Although Bitcoin transactions only have three states - spent, unspent or invalid - an 'invalid' state is all that is needed to represent all intermediates, since a valid transaction output has not been created yet. This is a key difference between the two protocols - since you're encouraged to delegate validation of those intermediate steps into the public part of the relationship. When you do that, you move the trust relationship of the logic you used to determine creating a transaction to untrusted parties and out of your own control. If the miners (or stakers in the future) decide they don't like the behaviour of your code, they can still come together to change it.
With this in mind, looking back again at the spectrum, we can forget the idea of an ethereum contract account, and simply see the user and the network. A contract is a network-controlled account. Just by laying it out, it's plain as day that users sacrifice control over their money by moving them into a contract, since they literally delegate control over creating transactions into the network and away from the user, such that a request is signed before an output is determined. If we want to have protocols that empower our users, are resistant to attack and scale efficiently, we really need to make sure that the core protocol is as universal as possible.
Obviously in practice, Private and Public aren't binary choices but just extremes - I can share information with people I trust without relying on decentralised anonymous game-theoretical trust. We can represent this really simply with a secret sharing scheme, or a typical multisig transaction. These explicitly transfer partial control to identified individuals, rather than simply moving it into the public space, but can easily rely on a secondary consensus logic. Because of its decentralised nature, there are no dependencies on this logic by the public network, enabling the process of producing a transaction to have an enormous amount of complexity before an output is signed, in the same way that a proof of work hash is simple to verify, but hard to reproduce.
Because almost all useful smart contracts deployed on ethereum rely on 'oracles', we don't even get a very strong trust benefit from deploying them to the public as they simply introduce trusted third parties anyway who become the deciders over what transactions get generated. If you can come to consensus over external state then the same mechanism can simply produce a transaction output, if given that authority. The only part of smart contract's behaviour that actually matters to the public network is its resulting state transition. Any intermediate step is unnecessary to be made public as the only thing we need to validate is the output in and of itself.
Innovation at the edge
In networks the least authority principle fits really nicely with what's called the network edge. Decentralised systems empower users when sovereignty over their stake lies in the hands of the individual and all trust in authorities is minimised, but new, experimental, and risky endevours can also be done in a way where any fallout is minimised to the people directly involved.
Looking back at ethereum's whitepaper, we can interpret the 'limitations' of Bitcoin script as protections instead.
Lack of Turing-completeness - that is to say, while there is a large subset of computation that the Bitcoin scripting language supports, it does not nearly support everything. The main category that is missing is loops. This is done to avoid infinite loops during transaction verification; theoretically it is a surmountable obstacle for script programmers, since any loop can be simulated by simply repeating the underlying code many times with an if statement, but it does lead to scripts that are very space-inefficient. For example, implementing an alternative elliptic curve signature algorithm would likely require 256 repeated multiplication rounds all individually included in the code.
Value-blindness - there is no way for a UTXO script to provide fine-grained control over the amount that can be withdrawn. For example, one powerful use case of an oracle contract would be a hedging contract, where A and B put in $1000 worth of BTC and after 30 days the script sends $1000 worth of BTC to A and the rest to B. This would require an oracle to determine the value of 1 BTC in USD, but even then it is a massive improvement in terms of trust and infrastructure requirement over the fully centralized solutions that are available now. However, because UTXO are all-or-nothing, the only way to achieve this is through the very inefficient hack of having many UTXO of varying denominations (eg. one UTXO of 2k for every k up to 30) and having O pick which UTXO to send to A and which to B.
Lack of state - UTXO can either be spent or unspent; there is no opportunity for multi-stage contracts or scripts which keep any other internal state beyond that. This makes it hard to make multi-stage options contracts, decentralized exchange offers or two-stage cryptographic commitment protocols (necessary for secure computational bounties). It also means that UTXO can only be used to build simple, one-off contracts and not more complex "stateful" contracts such as decentralized organizations, and makes meta-protocols difficult to implement. Binary state combined with value-blindness also mean that another important application, withdrawal limits, is impossible.
Blockchain-blindness - UTXO are blind to certain blockchain data such as the nonce and previous block hash. This severely limits applications in gambling, and several other categories, by depriving the scripting language of a potentially valuable source of randomness.
These together operate on the assumption that you want the network to have control over your money - even though the example given puts control in the hands of a trusted third party data feed.
Another way of looking at the earlier continuum is as a distinction between control and data. Those familiar with computer science will understand that computer programs have two main components: control flow and data flow. Let's relabel our earlier diagram:
If blockchains are really just smart contracts, and smart contracts are just multiparty programs, then we should just think about them in terms of software, with multiple control flows and a single shared dataflow state. The shared dataflow is the blockchain, and the control flows are each individual client.
When it comes to dealing with money, we definitely want control flow to be performed on the client, not the network, since you should get to decide when you spend your own money. That means that once a transaction is published, its behaviour should already have been determined. Any dependencies required to produce a valid state transition should already have been executed on the client by the time you publish. Whereas an ethereum smart contract has been delegated control over money, the control flow is now public, and open to attack. Only the input and the resulting state transition is dataflow.
Bitcoin's 'limitations' force you to do these prior to signing the release of the transaction, protecting yourself from attack, and protecting the network from a tragedy of the commons. If you want to authorise delegating control over funds, you don't need a fancy turing-complete scripting language, with full view of the rest of the state. You simply need to transfer to them a permission or access right that represents an additional role in the authorship of a transaction, which could be as simple as m-of-n parties must agree, and if they sign, they inherently agreed. Whatever protocol you needed to come to between yourself was able to happen without bothering the rest of the network.
The important thing about separating control flow and data flow is pruned dependencies. By placing transactions into valid-or-invalid buckets, making transactions blind to the rest of the state, and being explicit about the value of a transaction is that the whole graph becomes extremely parallelisable and scalable, simply by only submitting signed outputs to the network as opposed to inputs. You can remove all complex dependent logic to only happen once at the edge, and the fact that it produced a valid output was all that the network needed to accept the entire computation.
That leads us into the scalability conversation, but I'll get into that in a future post.
Thanks to Taulant Ramabaja and Tim Pastoor for giving me feedback earlier versions of this post.