CosmWasm 1.2
The 1.2 release of the CosmWasm delivers important new features and API improvements while keeping a strong focus on compatibility.
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.
As you can see in the virus source code, Instantiate2 consists of two components:
- 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.
- 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.
- 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.
- Uint128/Uint256::{checked_,}mul_ceil is like 1. but rounds up instead of down.
- 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.
- 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. - 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.