Introducing “The Mask”

Ethan Frey
CosmWasm
Published in
5 min readMar 23, 2020

The Mask is a new CosmWasm contract that aims to demonstrate the potential already available with our new smart contracting system.

Photo by Vlad Hilitanu on Unsplash

CosmWasm runs as a module inside the Cosmos SDK, and can securely run uploaded WebAssembly contracts alongside your native Go modules. The WebAssembly contracts can also move tokens and call other contracts, but one question that often comes up is integration with native SDK modules.

The Mask works as a proxy contract, but for your user account. Or think of it as a 1-of-1 multisig. The Mask has an address and can hold tokens, and interact with other contracts like any normal user account. It has an owner and will re-send any CosmosMsg signed by that owner on behalf of the Mask’s address, and also allows the owner to transfer ownership to another address.

A CosmWasm contract can already (since v0.5) send a message to a native module using the OpaqueMsg type. The one caveat is that since this data format for this message is not held to an immutable spec, these messages may break at anytime during an upgrade of the underlying blockchain. Notably the native Cosmos SDK message format will change radically between 0.38 and 0.39. In general, these OpaqueMsg types are intended to only be re-sent by a contract and originally uploaded by a client, which is just what Mask does. Let’s explore their potential.

Validator Key Rotation

One reoccurring request on Cosmos Hub chats is the ability to change the operator key of a validator without unbonding and rebonding it. Maybe an employee changed, or maybe you just want to maintain good security practices. Until now this has been a “someday” wish for all validators. But today it is real.

Before creating the validator, create a Mask and send your tokens to this contract. Then, when creating the validator, you can create an OpaqueMsg client side. OpaqueMsg is handled by wasmd by parsing the content as the JSON-Amino serialization of any sdk.Msg. This is not good for long-term stability, but is super flexible and gives access to any native module, by pushing the encoding logic to the client rather than the contract.

Once the Mask has created the validator, you can dispatch MsgEditValidator via the Mask. And when you want to do key rotation, you simply transfer ownership of the Mask. The new owner can continue dispatching the needed messages via the Mask, and the staking module is unaware of any change, avoiding the need to modify any code there.

Trading Bonded Atoms

There is also a lot of work on making it possible to trade some sort of derivative based on bonded atom positions. In fact, this was the core proposition of two Hackatom finalists — Chorus One in Berlin and Everett in Seoul. Both involved changes to the staking module, which is difficult and security critical, as it is the key to the control of the entire blockchain.

You can already achieve a limited version of this simply using the mask. Once you transfer some tokens to the Mask, you can use the Mask to delegate those tokens to a chosen validator, with some JavaScript like:

const staking = {
type: "cosmos-sdk/MsgDelegate",
value: {
delegator_address: mask,
validator_address: "cosmosvaloper1e8gslcu2u2p5zp9rgj8alz4q3lt6hvywqppf23",
amount: {
denom: "ustake",
amount: "300000"
}
}
};
client.execute(mask,{ reflectmsg: { msgs: [opaqueMsg(staking)]}});

Later, you could trade those tokens without unbonding them, by transferring the ownership of the Mask. Note this is an all-or-nothing trade, you trade the entire position of the Mask and cannot trade a portion. But you do this atomically on chain, by signing one transaction with both a message transferring ownership from you to the buyer, as well as a message sending native tokens from the buyer to you.

Explore it Yourself

Once you have got the concept, you can start playing with the contract. We have previously introduced the CosmWasm JS library, and given an intro to using the Node.js Shell as an interactive CLI tool. Recently we added some custom helper scripts for @cosmwasm/cli to demonstrate how to easily use the Mask on the demo net.

If you are comfortable with JavaScript, take a look at some tutorial guides. The “Extended Helpers” section in the @cosmwasm/cli README gives a guide to interacting with a blockchain using the CLI. Once you master the basics, we lead you through uploading and using the Mask contract. This example code just walks through both moving native and erc20 tokens via the Mask, as well as delegating stake with it and then trading that stake. Try it out yourself, and invent some more uses for the Mask.

Dev Tools for Contract Developers

I made the warning above that OpaqueMsg could change at any blockchain update and should only be generated client side. That is true for any contract you want to deploy to production. However, it is a great tool for building out prototype contracts. If a contract will only be deployed on a demonet or non-value-bearing / temporary testnet, then it doesn’t matter if it can’t withstand a blockchain upgrade. And it gives you a fast route to sketch out future possibilities. We encourage developers to try out.

How about a contract that works as an index fund for staking derivatives? You could transfer tokens to a contract that an owner/oracle that updates some index of validators to bond to. The contract will bond most funds and issues shares (an ERC20 token). You can then trade these shares, or also use them to collect a dividends (staking rewards) or burn them to unbond a portion of the tokens and get them out (after the unbonding period).

This requires the ability for a contract to intelligently send 3 different types of Cosmos-SDK messages, which we can immediately implement using the OpaqueMsg type. We can define a solid public API for the contract and build out a client for the prototype contract, which should work just as it will when we can upgrade it to a production contract, using standard messages rather than OpaqueMsg, once these native message types are added to the CosmWasm standard library.

Next Steps

While the Mask is a wonderful multi-purpose tool, and you can start using the OpaqueMsg technique demonstrated above to make some demo contracts, in order to produce production code where the Smart Contract actually is aware of the blockchain actions, we need to produce new native message types. These must be added to cosmwasm::types::CosmosMsg enum and then wasmd must support translating these generic types into the native sdk.Msg implementation before dispatching it, in the current and all future versions of the Cosmos SDK.

Actually adding a message is not too difficult, but the concern about providing a forwards compatible interface for well, forever, and over all blockchain runtimes that CosmWasm will ever support has kept the list of CosmosMsg types quite small, only exposing the functionality to send native tokens. However, staking is an essential part of an ever-growing list of PoS blockchains, and a very interesting area for development as I mentioned above. If you are interested in the implementation, please comment on the GitHub issue.

Interested to learn more about CosmWasm? Check out our documentation, or follow us on GitHub, on Medium, on Twitter, or on Telegram.

--

--