We just launched our first version of the Chialisp language and on-chain programming environment, which introduces a new and much better approach to building smart transactions. This post will give an overview of what the new innovations are and how they’re better.
The two general approaches to smart transaction environments so far have been from Bitcoin and Ethereum, which I’ll be referring to as ‘the UTXO model’ and ‘the Solidity model’. In the UTXO model the only data which needs to be kept by servers is the current set of unspent coins (and their birthdates, but that’s a minor addition) and transactions only spend some coins and create others and are not allowed to depend on any external data so the only way for them to go from good to bad is for an input to be spend (or to be reorged into never existing or having a different birthdate, again a minor gotcha). The Solidity model by contrast has huge amounts of on-chain state including running programs and the effects of a transaction can’t always be determined before it actually runs. The UTXO approach is much simpler, easier to implement, has lower overhead on full nodes, and results in much more reliable, secure, and succinct smart transactions. The Solidity model is much more dangerous, expensive, and unreliable, but has more expressive power.
What we’ve figured out with Chialisp (and the surrounding CLVM) is how to keep the UTXO model but add in the general power of Solidity. This is done with a set of simple cleanups which individually don’t do much but combined add up to something very powerful:
- Coins are first class objects and transactions are ephemeral justifications of destroying some of them and creating others, unlike in Bitcoin where transactions are first class objects and coins (UTXOs) are represented as a transaction id and an output number.
- The format of coins (UTXOs) is dramatically simplified. It’s just a primary input, puzzle hash, and amount.
- Transactions happen simultaneously rather than sequentially.
- Signatures are done using BLS, which is a non-interactively aggregatable format, and aggregation is always done.
- The language used has no side effects. This allows delegation and partial delegation in a much more general and powerful way than is added by Bitcoins current taproot proposal.
- The requirements of all puzzle (scriptpubkey in Bitcoin parlance) solutions (scriptsigs) are expressed by their return value.
- The language is turing complete. This adds a lot less complexity than people make it out to because execution is ephemeral. It’s the complex persistent state which causes complexity in Solidity.
- The language has the necessary primitives to calculate coin ids and coins are able to assert their own ids, which allows explicit self-reference and avoids the need for quines.
In addition to the language and environment extensions there are also some programmatic tricks which allow much more functionality than you’d expect:
- Covenants can be implemented by making statements about the puzzle hashes of outputs which apply recursively. It’s been pointed out that this could in principle be done in Bitcoin Script but it lacks sufficient string mangling capabilities and ‘check signature from stack’, which was the inspiration for using it here.
- Capabilities can be implemented using backwards pointing covenants which talk about ancestors rather than descendants.
- Coins can communicate with each other using ephemeral coins which are consumed in the same transaction they’re created and are declared as inputs by the receiving coin.
- State can be kept in unreachable parts of the code in the puzzle, which can then be accessed by getting a reveal in a solution and asserting the coin id which is calculated based on the puzzle hash.
Together these techniques allow for arbitrarily complex functionality without requiring any new opcodes. New functionality can simply be written and deployed.
As a taste of what can be done with this we’re making available several reference smart transactions and the wallets which use them, including:
- A wallet which can only send its funds to authorized recipients.
- A wallet which can only spend money at a set rate, including being able to send payments to it non-interactively. This turns out to require a capability or the wallet software could make multiple funds-holding coins and spend from all of them at once.
- A wallet with deposit recovery information like a paper wallet but with a lower attack surface. It can be used to recover the funds in a wallet whose secure hardware has failed but unlike a usual paper wallet, instead of summarily gaining control of the coins the deposit recovery information can be used to initiate a process for gaining control which takes some time during which the hardware wallet (if it’s still online) can claw the funds back. It can also support requiring a deposit to start the recovery process that the person being attacked can “steal.”
We’ve also made implementations of some basic functionality which already exists in Bitcoin but is important:
- Multisig. We’re starting with the simplest approach which is the same as in Bitcoin and will be implementing the alternative approaches which make good use of signature aggregation in the future.
- Atomic swaps. We have a smart wallet which does the swap and handles all the edge cases on chain.
In the future we’ll build more reference smart transactions, and the Chialisp functionality will be added to our testnet followed by our mainnet. There will be incompatible changes before final mainnet launch, but the fundamental concepts won’t change. We have some additional exciting reference transactions to add to this list over the coming months including light client verifiable colored coins that inherit full Chialisp functionality and distributed identity wallets with sophisticated recovery options.
Documentation is available online Github repo.
Questions about installation, LedgerSim, smart wallets and our smart transactions should be addressed to our keybase channel #dev.