How we built a generalized CosmWasm VM
To allow DeFi developers the ease of orchestrating cross-chain smart contracts from our parachains, a virtual machine (VM) is required. In line with our mission of promoting a trustless and cohesive experience for web3, we had to choose a VM that is the most portable and robust solution available in the market. This is in tandem with how we adopted the Inter Blockchain Communication Protocol (IBC) as the basis of our transport layer.
Among the alternatives, the CosmWasm VM proved to be the best VM for our needs. However, it was not compatible with Substrate and has never been leveraged outside of Cosmos, thereby necessitating our decision to build an alternative CosmWasm VM from scratch. With this being the first implementation of a CosmWasm VM outside the Cosmos ecosystem, this blog offers insights into what our CosmWasm VM portends for the broader Substrate (and, more generally, Rust) community.
To ink! or not to ink!?
Before selecting a smart contract layer, we carefully reviewed the existing solutions. Polkadot adopts the Substrate smart contracts pallet which utilizes ink!. Although considering that the smart contracts pallet can be plugged into any Substrate blockchain to support smart contracts, developers still face difficulties. We found that the pallet was both an interface (a pallet specifies transactions users can submit) and the virtual machine implementation (actual execution semantic).
From a design perspective, this leads to different issues:
- Testing contracts requires using the pallet, which itself requires a Substrate blockchain.
- The execution semantic of the VM is difficult to understand as it is hardcoded in the pallet (melted with Substrate specific types/operations) rather than being an abstract library on its own.
- The ink! framework is heavily based on Rust macros, and we think that macros must not be the foundations of a framework.
Moreso, we had other goals to fulfill when selecting the appropriate VM. Firstly, we wanted to radically impact the developer experience by creating tools around the smart contract framework. An early iteration of our first developer tool allows developers to create protocols and test contracts without the need to deploy them on a local blockchain.
Hence, the VM must be a library that can be used by anything.
Our second goal was the XCVM. We envisioned a VM that allows us to integrate XCVM without friction, and the CosmWasm actor model execution is close to XCVM programs execution. Architecturally speaking, it makes more sense to use CosmWasm for XCVM.
Finally, I suspect the smart contracts pallet has been developed with Solidity in mind. Which I believe, has been inefficiently designed.
CosmWasm before us
CosmWasm, short for Cosmos Webassembly, is a smart contract framework designed for use in the Cosmos ecosystem. Originally built as a Cosmos SDK module, CosmWasm allows plug-and-play functionality on any Tendermint-based chain. By allowing L1 developers to add smart contract functionality to their blockchain without changing any existing logic, CosmWasm has become the de facto smart contract framework in the Cosmos ecosystem.
CosmWasm was written in half Rust and half Golang (Go), with low-level calls in Rust and high-level dispatching logic, handled in Go. The actor model is implemented in Go which then calls the low-level Rust library to execute contracts effectively.
The final library is a Cosmos SDK module that links with the Rust library. This solution has different drawbacks:
- It is not self-contained (different parts written in different programming languages) and is more challenging to maintain and reason about, as developers must be aware of both the Rust and Go ecosystems to follow the implementation.
- By using Go, the VM is not embeddable in constrained environments such as the runtime module of a Substrate blockchain.
From the onset, CosmWasm was not designed with an abstract implementation in mind. Rather, it requires the standard library, hence it is impossible to embed it into a Substrate pallet. Therefore, when rewriting the CosmWasm VM we did so as a single, highly abstract library. This ensures that our CosmWasm VM is highly portable with consistent execution semantics regardless of its host. As a result, this enables developers to integrate our CosmWasm VM as a pallet, within a frontend app, or inside a CLI tool.
Building the VM
CosmWasm offers a high degree of customization as part of its design philosophy. When designing CosmWasm, Ethan Frey, the Father of CosmWasm, realized that baking design decisions into the infrastructure of CosmWasm would make it harder to adapt in the future. Frey instead opted to ensure developers were offered a high degree of customization to extend CosmWasm while maintaining compatibility.
The official CosmWasm VM is Wasmd. It ensures that developers follow the same execution semantics, thus, all CosmWasm contracts will function the same irrespective of the Cosmos blockchain they are executed on. We utilized the Wasmd reference material to rewrite the Go portions of CosmWasm in Rust for implementation on our parachains. Hence, our CosmWasm VM can handle both low-level and high-level calls in Rust. In addition, we ensured that our implementation was fully abstract, with no dependencies on the standard library and no assumptions on the host it is executing on.
Having no dependencies makes our CosmWasm VM implementation highly portable. We have tested this implementation in the following environments:
- A parachain embedded as a Substrate pallet
- In a frontend Webassembly application
- An in-memory integration testing library for CosmWasm contracts
- A CLI tool for the VM
Initially, we thought it would be a time-consuming task to rewrite all of these. But we had a working PoC in a week. While we are still fine-tuning the VM, improving its interface, and integrating more features, we are confident that it will be delivered on Picasso in early Q1. In fact, Halborn is currently auditing the library.
IBC implementation
CosmWasm was built with the IBC Protocol in mind, therefore, provides support for IBC out of the box (also known as the stargate feature). By following the Wasmd reference material along with the IBC specification, we were able to add optional IBC support to our CosmWasm VM implementation (also named stargate). This IBC implementation is fully abstract and has no assumption of the host. We completed the IBC extension in November.
Converging with the reference implementation (CosmWasm 2.0)
Now that our CosmWasm VM implementation is complete, the final step was to make the official CosmWasm std package `no_std` compatible. We have spoken to CosmWasm’s founders, Confio, about adding this feature to the official CosmWasm specification and are now working closely to get this feature added. It introduces a breaking change that naturally lands in CosmWasm 2.0. In the meantime, we use a fork of the CosmWasm std package.
Benefits of our implementation
Overall, our CosmWasm VM not only marks the first expansion to a blockchain outside of Cosmos but will also bring a ton of extended functionality for existing CosmWasm developers. There are some key benefits to building without the usage of a standard library. Some examples include:
- A CLI that can be created to deal with contracts without the need for a blockchain.
- End-to-end in-memory tests can be conducted on contracts with IBC capabilities through the utilization of a fake, in-memory relayer that can relay packets between two VM instances.
- Embed the CosmWasm VM into contracts on any Rust-based chain. This opens up many opportunities to innovate, one example could be calling a CosmWasm VM in a NEAR smart contract.
- Interactive front-end apps can be made without the need for a blockchain to execute contracts. Examples include:
- Interactive tutorials to learn how smart contracts work
- Games without blockchain, solely based on smart contracts
- Embed the VM in any app and use it as a plugin engine, such as a game with smart contracts plugins that would allow users to write their game extension in CosmWasm
Overall, these developments allowed our team to build an orchestration framework (cw-orchestrate) that we will be releasing on Wednesday, the 21st of December. These tools enable developers to instantiate multiple VMs (acting as different chains) and deploy a set of contracts on each VM. We have conducted end-to-end tests using these tools for executing XCVM cross-chain programs via IBC. This allows two VMs with XCVM contracts deployed separately, and a fake in-memory IBC relayer that would forward IBC packets back and forth between the VMs. Consequently, developers will no longer have to run multiple chains locally and an IBC relayer to test cross-chain IBC communication.
On Wednesday, the 21st of December, we will be going live on Twitter Spaces with 0xbrainjar, Karel Kubat, 0xc0dejug, Ethan Frey, and Larry0x to discuss CosmWasm in general and the future of smart contract languages.
In conclusion, Composable Finance chose to use the CosmWasm virtual machine (VM) for cross-chain smart contracts because it is the most portable and robust solution available, but it was not compatible with the Substrate platform. As a result, a new CosmWasm VM had to be built from scratch. The main reasons for this decision included the difficulties faced by developers when using the ink! smart contract framework, the desire to create intuitive developer tools, and the need to integrate with the XCVM. The original CosmWasm VM was written in both Rust and Go, but had several drawbacks, including being difficult to maintain and not being embeddable in constrained environments. The new Composable-built CosmWasm VM aims to be a self-contained Rust library that is easy to use and maintain.
For more information about Composable and how it is architecting the unified DeFi landscape of the future, check out our socials:
Twitter | Telegram | Discord | Website | GitHub | LinkedIn | Youtube