CosmWasm 1.2

Simon Warta
CosmWasm
Published in
4 min readJan 31, 2023

The 1.2 release of the CosmWasm delivers important new features and API improvements while keeping a strong focus on compatibility.

Foto von Lindsay Henwood auf Unsplash

Full instantiate 2 support

MsgInstantiateContract2, or Instantiate2 for short, allows instantiating addresses at a predictable contract address. This is useful for off-chain services that can, e.g., create deposit addresses before instantiating a contract at that address. Now contracts get the ability to use Instantiate2. If you have a factory contract, you can now store the address of the newly created instance without the need for a reply call. Also, you can instantiate a contract and execute it right away.

The virus

The virus contract is a new development contract that shows how to use Instantiate2. It cannot do anything useful, but it can replicate many times and predict on which addresses it will live.

An instance of the virus replicating itself recursively over 3 levels in one transaction using Instantiate2

As you can see in the virus source code, Instantiate2 consists of two components:

  1. The function cosmwasm_std::instantiate2_address allows the calculation of the address in advance. It requires a canonicalized creator address, an application-specific salt, and the checksum, which you can now query from a code ID. It returns a canonical contract address that needs to be humanized.
  2. WasmMsg::Instantiate2 creates an instance using the predictable address derivation, very similar to how WasmMsg::Instantiate is used.

Big steps toward Windows support

Being able to run CosmWasm on Windows was initially planned for 1.2. We made major progress on making the codebase OS agnostic and successfully ran cosmwasm-vm tests on Windows in the CI. Unfortunately, we discovered issues around signal handling when using Wasmer inside of a shared library linked to a Go project on Windows. As a result, it became infeasible to close this epic. However, we are better prepared than ever before, and the progress and missing steps are well documented now.

In the meantime, wasmvm can now be built without CGO enabled, making it possible to have wasmvm as a dependency in projects that do not execute contracts. This allows for an alternative path toward wasmd client support on Windows.

Weighted voting

The new GovMsg::VoteWeighted allows the contract to cast a split vote. This can be useful if the contract holds funds on behalf of multiple owners who want to vote differently. Or maybe you just want to express mixed feelings.

The cosmwasm_1_2 capability and feature

A new cosmwasm_1_2 capability is used to allow the contract to communicate that it requires CosmWasm 1.2+ on the chain (wasmd 0.31+). By enabling the cosmwasm_1_2 feature in cosmwasm-std, new messages and queries become available, and the contract requires the cosmwasm_1_2 capability.

As long as the cosmwasm_1_2 feature is not enabled, all 1.2 contracts run on all 1.x chains. And, of course, contracts compiled with earlier 1.x versions run unchanged on 1.2 chains.

Contract APIs

The following list of changes only makes it more convenient to use CosmWasm without affecting compatibility.

Uint128/Decimal multiplication

The Uint128*Decimal implementation is one of the major sources of confusion in CosmWasm math. Why does it return an integer? Why does it perform rounding? Those are just the most common questions around it. It was concluded that mixed-type arithmetic is not a good idea in general, and the implementation will be removed eventually. In 1.2, we are shipping a set of alternatives to prepare your codebase today.

  1. Uint128/Uint256::{checked_,}mul_floor is the direct replacement of the mixed type operator. It multiples an integer with a Fraction (such as Decimal) and returns an integer. The flooring becomes explicit, and you also have a checked version.
  2. Uint128/Uint256::{checked_,}mul_ceil is like 1. but rounds up instead of down.
  3. The 8 new functions Uint{128,256}::{checked_,}div_{ceil,floor} do what the name suggests, like 1./2. but with division instead of multiplication.
  4. A pair like (Uint128, Uint128) now implements Fracttion<Uint128>, making it possible to represent rational numbers like this: let two_third = (Uint128::new(2), Uint128::new(3)). This can now be used for all functions of 1./2./3. as an alternative to Decimal/Decimal256.
  5. If you want to operate on Decimals instead of integers, we have 4 new exporters for you. Decimal/Decimal256::to_uint_floor is your friend for Decimal -> uint conversion (like the Uint128::one() * my_decimal workaround but fast and readable). Decimal/Decimal256::to_uint_ceil complement it by a ceiling conversion. To convert Uint128/256 to Decimal/Decimal256, we recommend the existing ::from_atomics APIs over ::from_ratio(x, 1u128) since from_atomics is more efficient and only has one error case.

Huge shoutout to Gabe Rodriguez for contributing to the mixed arithmetic implementations. He brought in the skill and patience to meet the high cosmwasm-std quality standards.

The Never type

The new type cosmwasm_std::Never is a type that can never be instantiated. This is useful in cases where you are bound to an API such as Result<GoodCase, ErrorCase> but want to get type safety so that your implementation does not create an error. Using Result<GoodCase, Never> allows that. In ibc_packet_receive and ibc_packet_ack, it allows you to ensure all error cases make it into an error acknowledgment. But it is useful beyond that. Best practices around IBC error handling have yet to be developed.

Misc

Various other fixes and improvements between 1.1 and 1.2 can be found in the full changelog.

--

--

Simon Warta
CosmWasm

Building CosmWasm and CosmJS at Confio | Ex IOV | Co-Founder of Kullo | Board member prolina Foundation