Contract Semantics
This document provides an explanation of the semantics governing the interaction between a CosmWasm contract and its environment.
Definitions
Contract is a WebAssembly code stored in the blockchain’s state. This has no state except that which is contained in the binary code (eg. static constants).
Instance refers to a specific instantiation of a contract. It includes a reference to the contract’s binary as well as a state unique to the instance, which is initialized upon its creation. This state is stored in the key-value store on the blockchain’s state. Consequently, a reference to the contract’s binary, combined with a reference to the prefixed data store, uniquely identifies the smart contract.
Example: we could upload a generic “ERC20 mintable” contract, and many people could create independent instances based on the same bytecode, where the local data defines the token name, the issuer, the max issuance, etc.
- First you store a contract,
- Then you instantiate an instance,
- Finally users invoke the instance.
SDK Context
Before looking at CosmWasm, we should look at the semantics enforced by the blockchain framework we integrate with - the Cosmos SDK. It is based upon the Tendermint BFT Consensus Engine. Let us first look how they process transactions before they arrive in CosmWasm.
First, the Tendermint engine will seek >2/3 consensus on a list of transactions to be included in the next block. This is done without executing them. They are simply subjected to a minimal pre-filter by the Cosmos SDK module, to ensure they are validly formatted transactions, with sufficient gas fees, and signed by an account with sufficient fees to pay it. Notably, this means many transactions that error may be included in a block.
Once a block is committed, the transactions are then fed to the Cosmos SDK sequentially in order to
execute them. Each one returns a result or error along with event logs, which are recorded in the
TxResults
section of the next block. The AppHash
(or merkle proof or blockchain state) after
executing the block is also included in the next block.
The Cosmos SDK BaseApp
handles each transaction in an isolated context. It first verifies all
signatures and deducts the gas fees. It sets the “Gas Meter” to limit the execution to the amount of
gas paid for by the fees. Then it makes an isolated context to run the transaction. This allows the
code to read the current state of the chain (after the last transaction finished), but it only
writes to a cache, which may be committed or rolled back on error.
A transaction may consist of multiple messages and each one is executed in turn under the same
context and same gas limit. If all messages succeed, the context will be committed to the underlying
blockchain state and the results of all messages will be stored in the TxResult
. If one message
fails, all later messages are skipped and all state changes are reverted. This is very important for
atomicity. That means Alice and Bob can both sign a transaction with 2 messages: Alice pays Bob 1000
ATOM, Bob pays Alice 50 ETH, and if Bob doesn’t have the funds in his account, Alice’s payment will
also be reverted. This is similar to how a database transaction typically works.
x/wasm
is a custom Cosmos SDK module,
which processes certain messages and uses them to upload, instantiate, and execute smart contracts.
It accepts a properly signed
CosmWasm message
,
routes it to Keeper
,
which loads the proper smart contract and calls one of the entry-point on it. Note that this method
may either return a success (with data and events) or an error. In the case of an error here, it
will revert the entire transaction in the block.
For more information on contracts design visit entry points chapter.