Guest Post by Barbara Liau, James Prestwich, Conner Swann
Blockchains are isolated. Their state lives in a walled garden, at the top of an ivory tower, protected from easy access by the rest of the world. Within its domain, the chain’s execution environment manages running smart contracts, moving money and tokens between accounts, and updating the state store. The garden’s gates are controlled by public key authentication: signing a string with an account’s private key lets you initiate a transaction from that account. Messages are sent from an account once it’s established that the transaction originates from an authorized signer. Once execution starts, the environment manages passing messages between smart contracts and ensuring that execution eventually halts.
Authentication vs Authorization
Unfortunately, cryptography isn’t very expressive. It can handle authentication, but doesn’t give many tools for granular authorization. In Ethereum, a lot of research and discussion has gone into more complex authorization of access to externally-owned accounts (EOAs). “Account abstraction” aims to allow users to set arbitrary programs that control access to their account, so that tokens in the account can be moved by anyone so long as the movement follows specific rules. Newer designs like EIP-3074 provide many of the benefits of account abstraction at a much lower complexity cost.
Access Control List
Tools for controlling access to blockchain resources are usually standardized at the boundary between the chain’s domain and the rest of the world. At its most complex, available authorization schemes consist of the humble Access Control List (ACL) — access to a resource (ex: the mint function on an ERC-20 Smart Contract) is gated to specific externally-facing accounts. However, messages within a chain’s domain need authentication and strong authorization as well.
Even the simplest Ethereum smart contracts share the same point of tension: access to their capabilities are controlled by lists of addresses. Token contracts grant control over a balance to its owner. Decentralized exchange (DEX) contracts need to ensure they have received value before giving value away. While the Ethereum Virtual Machine (EVM) handles internal authentication (each message contains the address of its sender in the `msg.sender` field), it has no standard pattern for checking authorization. Each smart contract developer needs to make a bespoke access list system to track permissions on specific things. Mis-implemented authentication systems are at the root of a number of complex DeFi bugs, and have caused millions of dollars in damages.
The fatal flaw is shared by any system built with ACLs at its core. To quote the great blog post “What are Capabilities?” by Chip Morningstar:
When you run an application, as far as the OS is concerned, everything the application does is done by you. Another way to put this is, an application you run can do anything you can do.
These problems have been around since Operating Systems were young, and blockchains inherited them because ACLs are a well-documented, established, and relatively intuitive way of understanding access in a system. Newer blockchains, however, are rethinking this design choice in favor of a (relatively) newer permissions model known broadly as “Object Capabilities” (OCAP).
OCAPs, ERTP, and Zoe
The Agoric Blockchain has OCAPs at the core of its Electronic Rights Transfer Protocol (ERTP) (Agoric’s token standard for digital assets). Similar to ERC-20 and ERC-721, ERTP is a standard that implements an API for creating digital assets. Unlike ERC-20 and ERC-721, ERTP is written in a familiar language, JavaScript, and capitalizes on some of JavaScript’s language features to allow more granular authorization. Rather than a contract holding a list of addresses, ERTP uses OCAPs to enforce access control, and plays by a basic rule:
“If your program has a reference to an object, it can call methods on that object. If it doesn’t have a reference, it can’t.”
In other words, unless you have access to the actual object, you can’t use it. Simply knowing the name of a variable or public class doesn’t give you a reference to an object. You can only get it if you 1) create it, 2) construct it, or 3) get introduced to it.
If you are familiar with JavaScript, this idea of access by reference can be illustrated by the concept of closures. “A closure is a combination of a function bundled together (enclosed) with references to its surrounding state(the lexical environment).” [MDN]
Even after a function is executed, it can contain a reference to its outer scope. Using closures, developers can create private methods and data, that are only accessible if you have a reference to the object. This means outside parties can’t access it, even if they can see it. This concept of authorization by reference makes writing secure contracts a whole lot easier. (One caveat here is that smart contracts using ERTP need to be executed in a secure subset of JavaScript, as some language features in JavaScript make it less secure for writing smart contracts).
To help developers write smart contracts using OCAPs and ERTP, Agoric has also developed a smart contract framework known as Zoe. Zoe contracts are written in a secure subset of JavaScript, and automatically escrows all user digital assets and handles their subsequent payout. This means that even a buggy contract won’t result in users losing their assets.
Complexity can often lead to unintentional and costly mistakes. The ability to write smart contracts in a well-known language that has been around for decades can help reduce the number of those mistakes. By capitalizing on JavaScript’s OCAP capabilities, Agoric is able to provide developers with more granular authorization and helps solve for access in walled gardens.