Fuelmint: Sovereign FuelVM rollups on Celestia using Rollkit and ABCI
Preface
Modular Fellows is a program by Celestia to empower builders in the modular stack by providing guidance, engineering support, and a stipend over three months to build a project of their choice. As part of the program's first cohort, I built "Fuelmint" as my project. This piece explains the components that go into Fuelmint and how they work together.
If you want more specific details on how it works or plan on building with Rollkit (execution environments, apps, etc.), don't hesitate to reach out!
Intro
So what exactly is "Fuelmint"? Glad you asked! Named after the Fuel network and the pattern of using "mint" as a suffix (tendermint, ethermint, etc.), Fuelmint is an experiment on using the FuelVM as an execution environment for sovereign rollups on top of Celestia.
To better understand what that all means, let's briefly go over the different components that make Fuelmint possible.
Celestia
Current blockchains are monoliths since they typically handle all the primary services we associate with a blockchain (execution, settlement, consensus, and data availability). In contrast, Celestia is a modular blockchain that focuses on a specific set of services (data availability and consensus) while letting other blockchains concentrate on the rest (execution and settlement).
Fuel
Since the creation of the EVM, other execution environments have risen to serve developers' needs. The FuelVM is a new contender with many differentiating aspects, such as its easy parallelization thanks to its use of the UTXO model, its vast list of EIP that it implements, a blockchain-optimized DSL based on Rust (Sway), and a seamless developer experience.
One of its main differentiators lies in the way it classifies itself. Fuel calls itself a modular execution layer, defined as "A verifiable computation system designed for the modular blockchain stack." Meaning that Fuel can be deployed under different configurations across the modular stack.
Sovereign Rollups
Rollups are blockchains that post their blocks to another chain that provides consensus and ensures data availability. Since Celestia only focuses on consensus and data availability, it's a natural fit for rollups, as it allows rollups to choose how they handle execution and settlement.
Sovereign rollups are a type of rollup that doesn't rely on another blockchain for settlement but instead determines its canonical chain through the nodes in its p2p network. The latter means that a sovereign rollup is self-settling, thus having more freedom over the execution environment it runs, unlike traditional rollups (or governance rollups), which are usually constrained by their settlement as to which types of execution environments they can run.
Fuelmint
As described during the introduction, Fuelmint is an experiment using the FuelVM as an execution environment for sovereign rollups on top of Celestia, meaning that Fuelmint uses the FuelVM for execution, Celestia for data availability and consensus, while taking care of its settlement thanks to Rollkit. So if you want the benefits of having a sovereign rollup (freedom to fork, dedicated blockspace, etc.) while leveraging all the tooling that Fuel offers to write smart contracts, you could deploy such a construct with Fuelmint.
Rollkit + ABCI
To understand how Fuelmint works, we first need to talk about Rollkit, how it communicates with our FuelVM instance through ABCI, and how it helps us build a sovereign rollup on top of Celestia.
Rollkit is a modular rollup framework that allows developers to deploy rollups throughout the modular stack. Rollkit provides an ABCI client implementation for rollups, meaning that it handles requests and forwards them to its local app instance through the Application Blockchain Interface (ABCI). As an interface, ABCI allows a replication engine (blockchain) to communicate with the state machine (the application) by providing a set of methods with defined requests and responses. In other words, ABCI allows a blockchain client and an application to communicate with one another, even if they are written in entirely different languages. This works by having the blockchain client call the ABCI methods on the application by sending requests to it, which the application receives and performs, thus generating a response that is returned to the client, and so on for every subsequent request.
Tendermint
Tendermint Core (now CometBFT) is the most well-known ABCI client implementation and the most adopted, thanks to its use in the cosmos-sdk. It provides consensus and a set of RPC endpoints for transaction submission and querying, and it communicates with the application through ABCI. Here's a diagram to show how a Cosmos chain usually works:
This is how most Cosmos chains work today, but there are no requirements to use the cosmos-sdk to benefit from ABCI. For example, some chains like Penumbra use a custom stack while still using tendermint for consensus. It's also possible to swap out tendermint for another blockchain client as long as it can make ABCI requests, as shown in a Paradigm post. However, although the software is modular, the resulting chains are not because every cosmos chain has to take care of its own execution, settlement, data availability, and consensus. Here, Rollkit does things differently by providing an ABCI rollup client that can be used with cosmos-sdk or by itself.
Rollkit
Instead of having blocks go through a consensus process like Tendermint, Rollkit uses a sequencer to order transactions, communicates with an application through ABCI, and provides Tendermint-like RPC endpoints. By publishing blocks to Celestia and running the ABCI application, Rollkit takes care of execution and settlement while leaving the job of consensus and data availability to Celestia.
How Fuelmint Works
Thanks to Rollkit and ABCI, using the FuelVM as an execution environment for a rollup sounds straightforward; after all, it only requires creating an ABCI wrapper for the FuelVM and hooking that to Rollkit. However, there were some challenges:
Most tooling for building ABCI applications is specific to cosmos-sdk and thus requires Golang, while all of Fuel's stack is written in Rust.
The only VM that has been ABCI wrapped before is the EVM, ethermint relies on the cosmos-sdk, and the only other example of an ABCI-wrapped EVM is found in Paradigm's N/B repo.
Out of all the live cosmos chains, testnets, and projects, there are only two examples for an ABCI app written in Rust, one being the repo mentioned above and the other being Penumbra.
Given the difference in languages between Rollkit (Golang) and the FuelVM (Rust), the simplest way to have them interact through ABCI would be to use socket connections. However, Rollkit does not have a native capability for communicating with an app using sockets as of the time of this writing.
So how exactly does Fuelmint work? First, its non-conventional, as Fuelmint does not use the cosmos-sdk; it instead uses Penumbra's tower-abci, an interface for ABCI built on Tower's Service abstraction and a simple Golang app that defines an ABCIRelayer application that Rollkit runs.
With tower-abci handling all the logic of receiving requests and sending responses, all that has to be taken care of is defining the Fuelmint application and some ABCI methods to communicate with it. The application has multiple components, the main ones being a transaction pool service and a block producer, responsible for processing transactions from the transaction pool and executing them with the FuelVM to produce a block.
The other component of Fuelmint is the ABCIRelayer, which allows Rollkit to communicate with our tower-abci server where the application logic lives. An instantiated rollkit sequencing node will begin communicating with a given ABCI application, but as mentioned before, rollkit does not support socket connections to an application. This is where the relayer comes in; by wrapping an ABCI socket client as an ABCI application, a node can pass requests to it, which in turn passes it to the app (in this case, the tower-abci server), which then sends the response back to the client through the relayer.
Now that we have a Rollkit sequencer and an application capable of processing FuelVM bytecode, we have a FuelVM sovereign rollup ourselves! But, wow, not so fast; we still need a vital component of any blockchain, and that is an RPC service. A Fuel RPC service is necessary since the RPC service provided by Rollkit uses tendermint RPC methods, meaning that it expects tendermint RPC requests. So, for example, without a Fuel RPC service, the only way to deploy a Sway smart contract would be to serialize the contract deployment transaction as a hex string or as raw bytes and pass it to Rollkit through a tendermint RPC method such as broadcast_tx_commit, which is not a fun experience.
Thankfully this was taken into consideration. Similar to Fuel, Fuelmint runs a modified Fuel GraphQL client, with the only difference being that the Fuelmint’s client sends transactions to Rollkit for sequencing. Thanks to this slightly modified Fuel RPC service, is possible to use Fuel tools, such as forc, to quickly compile and deploy Sway smart contracts straight out of the box!
Conclusion
During Celestia's Modular Fellows program, I ran a sovereign rollup that uses the FuelVM as an execution environment by leveraging Rollkit, ABCI, and Fuel's core library.
Writing an ABCI wrapper for a new execution environment sounded daunting. While it wasn't simple either, I learned that it was simpler than I imagined, but the problem is that there are few examples out there. As such, I hope that by writing this article and sharing the code for Fuelmint, I can inspire more people to build modular.
As for Fuelmint, it is important to note that it is not production-level code and is all experimental.