CosmWasm for CTOs IV: Native Integrations
How to add CosmWasm to your blockchain
The number of blockchains running CosmWasm has steadily increased over the last six months to now include more than a dozen mainnets. At the same time, developers are hard at work on new projects, adding superpowers to any Cosmos blockchain that enables such contracts. Maybe you also want to add CosmWasm to your blockchain? If so, this is the place to come.
Prerequisites
Before we get to the fun stuff, there are a few requirements for this. CosmWasm is deeply integrated with the Cosmos SDK, and the latest release of wasmd (v0.27) requires the chain to be built with Cosmos SDK v0.45 and IBC-Go v3. If your chain is not using the Cosmos SDK or you aren’t using the latest stable release of the SDK, you may not be eligible.
The validator requirements (RAM and CPU) don’t change much by adding smart contracts; they run almost as fast as native code with small memory overhead. They do take up some disk space, but this is usually far smaller than the actual blocks themselves, only making a slight impact there. In fact, the actual usage of the chain (tx/s) is a much better metric of how beefy machine validators need to run, and the only way CosmWasm will force you to upgrade all those nodes is if it really boosts the usage of your chain.
The only other significant constraint is the CPU architecture. All nodes should run on Intel or AMD64 chips. We have developer support for running CosmWasm on arm64 (e.g., the new MacBook M1), but it has not been heavily tested and may fall out of consensus, so we don’t recommend using that outside of a dev environment.
No problems there? Then let’s dig into how you integrate CosmWasm.
Application Wiring
All Cosmos SDK blockchains wire up the various modules in a file called app.go
. In that file, they import and connect the various modules that make up the system, such as a bank, staking, and governance. In order to “add CosmWasm” to your blockchain, you really just need to import the x/wasm module and wire it up in app.go
. We also added two extra AnteHandlers to provide some extra security, which should also be enabled in your application.
One approach is to look at the most recent wasmd app.go
and search for all the lines with “wasm” in them, and port those over to your application. You will also want to look at the ICA integration (interchain accounts) in particular, as we used a “demo” ICA auth controller in the absence of any standard one. After a lot of side-by-side comparisons, you should be able to see what is needed.
Oh, and then make sure you add these two ante handlers; one of them prevents an “infinite gas” query. In fact, you better make sure you block gas limit is something reasonable, or you just might make 10-minute blocks legal for whoever wants to pay for it. We recommend something like 50 million as a reasonable limit. Definitely do not hit 1 billion; that could take minutes.
Once you have done this, just create a new genesis file, start a local chain, and start uploading contracts and calling them.
Quick Start Guide
If you know the SDK relatively well and can port all the wasm-related code to your app, the above guide should be plenty for you. However, it can be hard to figure out the real diff needed.
If you have a fresh project, you could just copy over the app directory from wasmd
(please do not copy over the whole x/wasm package, import it). But usually, you have some chain already and want to just add this.
A great way to start is by looking at examples. You can see how we added CosmWasm to Osmosis here (along with the cleanup PR). This is an older version of wasmd (0.23) but still a great overview of the steps, and you can then just tease out the last ones (like ICA) by hand.
Please use these PRs as a “quick start” guide while looking at the most recent app.go
as the reference manual.
Custom Integrations
So, you figured that out and got CosmWasm contracts live on your testnet? Congratulations! But there is one more step you can take.
Already the contracts can move native tokens, stake, vote on governance, and even send IBC packets. However, they know nothing about those custom modules that make your chain special. They cannot interact with that social network you built as native Cosmos SDK modules. But before you resign to having two parallel universes on your chain, unable to build your “buy alike” smart contract, we can help.
Since 0.8, CosmWasm has supported opt-in extensions for blockchain-specific modules. This is described in the integration docs, but let me explain the pieces. The goal is to add custom messages and queries that can be imported by chain-specific contracts, that allow them to call into your custom module.
You start by defining the Rust interfaces you want to expose to the contract. Both any new Message types as well as new Query types. Any contract that wants to make these calls can simply import those types and return them insideCosmosMsg::Custom
or QueryRequest::Custom
. However, those calls will fail if called on other chains, so we need to protect against that. By adding a requires_xyz
export, you ensure that any chain that doesn’t declare its support for xyz
will reject such a contract on upload.
Now a contract can use these custom types and return them to your chain. But what happens when these calls arrive on your chain? You have to add a parser in your Cosmos SDK app that understands them and can handle them. If you want full access to keepers, you need to create a “message decorator” that can call anything directly. There is also a slightly simpler version called a “message handler” if you just want to convert incoming contract messages to standard sdk messages. You follow a similar process to add support for custom queries, by defining a “query plugin” that calls into the keepers to answer any CosmWasm queries.
Once you have defined the custom querier and message handler, you just need to wire them into the wasm keeper contructor and ensure you add your custom codename to the “supported features” list to show you support these custom messages and queries.
Then you can build a sample contract to use those new bindings and test them out. You can get some inspiration from the unit tests we wrote for the Osmosis callbacks, as well as the integration tests that call into a real contract to execute those messages and queries. Now that you are satisfied this all works as planned, cut a release and let those devs extend your custom modules in a thousand different ways.
Get Involved
Like what you see? Let the world know on Twitter or join the discussion on Discord. And remember to follow us on medium to be informed about the upcoming CosmWasm Academy, where you can level up your skills.
Remember, this is advanced stuff and only needs to be done once per blockchain if you want to tie in custom Go logic. If you develop CosmWasm contracts, you just need to be aware this exists, so you can import the proper bindings when you want to leverage some chain-specific feature.
If you are going to dig into customizations, please do join our Discord and engage with the supportive community to answer your questions.