Radix Engine v2: An Asset-Oriented Smart Contract Environment | The Radix Blog | Radix DLT
In the previous article, I described how the development paradigm used by Ethereum and virtually every other existing smart contract platform fails to provide what developers need to take DeFi from experimental to mainstream.
To take even the first real bite out of traditional finance, developers need to be able to write smart contract code that is easy, safe, reusable, and composable. Instead, on Ethereum today the learning curve to “DeFi ready” expertise is years long, and smart contract code for DeFi dapps is unwieldy and nearly impossible to make safe.
For example, a smart contract that allows users to automatically swap one token for another from a pool (ie. Uniswap) sounds pretty simple, and you would expect a functional diagram of its implementation to look something like this:
However, with the tools the Ethereum platform provides for creating smart contract logic, Uniswap’s developers are forced to build it like this:
And as DeFi grows, the development challenges and opportunities for failure caused by this sort of code rapidly multiply as dApps become more complex, and are combined together. DeFi simply cannot grow, or expand its base of developers, much further with this approach.
The root cause is that there is something fundamentally missing at the platform level: assets. Even though all finance is built around assets, Ethereum, Polkadot, Avalanche, Solana, Cosmos and virtually all other smart contract platforms lack any built-in concept of assets for developers to work with natively.
As we’ll see later in this article, working around this shortcoming is at the heart of the problems with smart contracts today. The only solution to finally let developers rapidly build safe finance dapps in the way they expect is to reconsider the design of the platform and smart contract language.
Assets must be part of the fabric of the platform rather than an afterthought. Everything about the development experience must be designed to let developers create and control assets with ease, while still providing the power and expressiveness that developers need to build mature, feature-rich dApps.
For example: Look at the simpler “Uniswap as we imagine it” diagram above. Those actions shown in green – “send”, “put”, and “take” – must be real features of the platform and its smart contract language that the developer can use and rely on, not behavior they have to simulate with messages passed between smart contracts. Tokens and other assets must be real things that the platform understands natively and correctly handles globally.
We call this asset-oriented programming and it’s exactly what Radix is delivering with Radix Engine v2 and Scrypto.
Let’s get into a little more depth about the implications of Ethereum’s lack of assets and what makes the asset-oriented paradigm so different and powerful at a platform level. In the following article, we’ll talk about how developers on Radix will access these new platform capabilities with the Scrypto smart contract language.
Today’s Smart Contract Application Environment
The fundamental notion of a smart contract is simply that a blockchain network provides a shared environment that can perform computation using code that a developer deploys to the network. Each smart contract has its own little space where it can store some data that the smart contract logic can update, like this:
In this model, all functionality must be implemented as a smart contract. A token? That’s a smart contract that keeps track of a list of balances associated with a list of public keys. A multi-sig account? That’s a smart contract that requires signatures by a list of public keys in order to take action. DeFi dApp? That’s definitely a big smart contract as we saw in my last article.
Smart contracts aren’t very useful, however, if they are completely isolated from each other. For example, if we want a DeFi smart contract to be able to do something as simple as hold some tokens, it must be able to communicate with an ERC-20 contract that separately implements that token via a list of balances and methods to adjust those balances.
So the real application environment provided by Ethereum, called the Ethereum Virtual Machine (EVM), also allows smart contracts to send messages to each other. If you imagine the application environment as a little city full of smart contract buildings, the EVM application environment includes a telephone grid that lets smart contracts communicate.
This now not only makes token smart contracts useful, but enables the basic concept of DeFi composability where dApps can be connected together to do more complex things in a coordinated fashion.
However, while these platform features are sufficient for basic smart contract functionality, we can now see the root cause of the problem shown in the Uniswap diagram at the top of this article. On Ethereum, because absolutely everything is implemented in little smart contract silos, doing just about anything rapidly becomes a very complex set of messages being passed around, complex logic to ensure the right actions are taken in response to those messages, and lots of data inside each smart contract silo to keep track of everything.
Specifically, let’s consider assets like tokens. Developers have no choice but to create each token as its own independent smart contract. That means that any time a user or smart contract needs to interact with tokens, it must do so by sending messages to those separate master smart contracts that control the internal balance sheets. Now, remember that every DeFi app is constantly interacting with many types of tokens, performing complex movements of tokens between users and often other smart contracts. This is how you very rapidly get to complex systems like the Uniswap shown earlier – and much much worse.
It works, and some very clever people have cobbled together the first DeFi functionality atop this architecture, but it’s terrible for the developer and perilous for the user (just see the number of hacks and exploits listed here).
Interacting with assets isn’t a special case – it’s the primary subject of every single DeFi transaction and DeFi app, so why aren’t assets a feature of the platform rather than pushing that responsibility up to the development environment?
The Radix Engine Way
Radix has taken a different approach where assets are a global feature of the platform itself, rather than implemented over and over again at the smart contract level as closed silos.
Radix calls its application environment Radix Engine. The first version of Radix Engine is already running today on the Olympia release of the Radix public network. With Radix Engine v1, tokens aren’t implemented in smart contracts, but can be created by directly requesting them from the platform with some desired parameters.
Tokens in the Radix Engine environment aren’t entries on a thousand separate balance lists; they are treated by the platform as “physical” objects that must be held in accounts and moved between them. Accounts act like actual vaults of tokens controlled by the user, unlike on Ethereum where a user’s token holdings are spread among separate smart contracts that each hold an entry for their public key. This goes for not only XRD, the Radix network’s utility token, but all tokens created by users.
Radix Engine itself guarantees this “physicality” of behavior, using a well-constrained finite state machine (FSM) model. FSMs are typically used for mission-critical systems where correct results must be guaranteed. This is a good match for enforcing the correct behavior of tokens.
In our platform’s little city, the Tokens FSM is like a delivery service provided by the platform that securely trucks “real” tokens between vaults on request.
In this model, sending tokens isn’t a matter of sending a message to a smart contract and trusting that it will update some balance entries – it is telling the platform itself “I wish to send these tokens that I hold”. Errors like double-accounting aren’t just avoided; they simply aren’t possible.
This is the core of the asset-oriented paradigm. Already Radix Engine v1 offers a vastly more intuitive and easy-to-use model for simple tokens, but that alone isn’t sufficient for DeFi. To enable smart contracts that can serve as the basis for DeFi dApps, we need to add in decentralized computation.
Radix Engine v2 starts with v1’s asset-oriented approach, and adds computation of powerful smart contract logic written in Radix’s asset-oriented programming language, Scrypto, as well as messaging between smart contracts. And it expands v1’s Tokens FSM into a more powerful and general form called Resources (more on this in the following article about Scrypto).
Compared to the EVM model, this drastically shifts the character of smart contract logic that the developer creates. Because the Resources FSM can be used to transact tokens (and more!) much more easily and intuitively, smart contract code complexity drops. As with double-accounting errors, many issues with reentrancy in dApp transactions involving resources become simply impossible. And the amount of message-passing required becomes minimal, only needed to convey actual information between smart contracts rather than orchestrate movements of assets.
In short, the developer can lean heavily on REv2’s resources to handle the great majority of what makes smart contracts today fail to be easy, safe, reusable, and composable. REv2 accomplishes this not by forcing the developer to use specialized code, but by letting them rely on resources to create code that is simpler and safer at the same time.
Use resources for as much as possible in your application, and Radix Engine always has your back.
Because the result is so much different from today’s style of smart contract, Radix smart contracts have a new name: components. Compared to today’s smart contracts, components should have clearer function, be more modular and composable, and work more like reliable machinery. And as we’ll see in a future article, Radix Engine and Scrypto further encourage modularity and reusability by introducing blueprints that are on-ledger templates of useful functionality that can be instantiated over and over into components.
In the next article, I’ll discuss how developers will access these Radix Engine v2 capabilities with a new asset-oriented smart contract language: Scrypto.
Early access to Scrypto and Radix Engine v2 are coming this year as part of Radix Alexandria. Alexandria will let developers experiment with creating, compiling, and interacting with Scrypto-based blueprints and components in a simulator environment running on their local machine. Deployment of blueprints and components to the Radix Public Network will follow in Radix Babylon, coming in 2023.
Enjoy the article? Why not continue the journey!
Previous: The Problem with Smart Contracts Today