• Stars
    star
    123
  • Rank 290,145 (Top 6 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 5 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Dockerfile and script to deterministically produce the smallest possible Wasm for your Rust contract

CosmWasm Optimizing Compiler

This is a Docker build with a locked set of dependencies to produce reproducible builds of cosmwasm smart contracts. It also does heavy optimization on the build size, using binary stripping and wasm-opt.

Image Description x86_64 images (default) ARM images (experimental1)
optimizer Combines rust-optimizer and workspace-optimizer in a single image cosmwasm/optimizer
DockerHub
cosmwasm/optimizer-arm64
DockerHub
rust-optimizer Single contract builds cosmwasm/rust-optimizer
DockerHub
cosmwasm/rust-optimizer-arm64
DockerHub
workspace-optimizer Multi-contract workspaces (e.g. cosmwasm-plus) cosmwasm/workspace-optimizer
DockerHub
cosmwasm/workspace-optimizer-arm64
DockerHub

1 ARM images do not produce the same output as the default images and are discouraged for production use. See Notice below.

Usage

This works for most cases, for monorepo builds see advanced

The easiest way is to simply use the published docker image. You must set the local path to the smart contract you wish to compile and it will produce an artifacts directory with <crate_name>.wasm and checksums.txt containing the hashes. This is just one file.

Run it a few times on different computers and use sha256sum to prove to yourself that this is consistent. I challenge you to produce a smaller build that works with the cosmwasm integration tests (and if you do, please make an issue/PR):

docker run --rm -v "$(pwd)":/code \
  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
  cosmwasm/optimizer:0.15.0

Demo this with cosmwasm-examples (going into eg. erc20 subdir before running), with cosmwasm-plus, or with a sample app from cosmwasm-template.

Note that we use one registry cache (to avoid excessive downloads), but the target cache is a different volume per contract that we compile. This means no interference between contracts, but very fast recompile times when making minor adjustments to a contract you had previously created an optimized build for.

Mono Repos

Contracts as Workspace Members

This is designed for cosmwasm-plus samples. We use a separate docker image

Sometime you want many contracts to be related and import common functionality. This is exactly the case of cosmwasm-plus. In such a case, we can often not just compile from root, as the compile order is not deterministic and there are feature flags shared among the repos. This has lead to issues in the past.

For this use-case we made a second docker image, which will compile all the contracts/* folders inside the workspace and do so one-by-one in alphabetical order. It will then add all the generated wasm files to an artifacts directory with a checksum, just like the basic docker image (same output format).

To compile all contracts in the workspace deterministically, you can run:

docker run --rm -v "$(pwd)":/code \
  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
  cosmwasm/optimizer:0.15.0

The downside is that to verify one contract in the workspace, you need to compile them all, but the majority of the build time is in dependencies, which are shared and cached between the various contracts and thus the time is sub-linear with respect to number of contracts.

Contracts excluded from Workspace

This is designed for cosmwasm samples. You cannot provide automatic verification for these

If you have a more complex build environment, you need to pass a few more arguments to define how to run the build process.

cosmwasm has a root workspace and many contracts under ./contracts/*, which are excluded in the top-level Cargo.toml. In this case, we compile each contract separately with it's own cache. However, since they may refer to packages via path (../../packages/std), we need to run the script in the repo root. In this case, we can use the optimize.sh command:

docker run --rm -v "$(pwd)":/code \
  --mount type=volume,source="devcontract_cache_burner",target=/code/contracts/burner/target \
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
  cosmwasm/optimizer:0.15.0 ./contracts/burner

Caches

The build system uses the folder /target in its local file system for all Rust compilation results. This ensures there is no conflict with the target folder of the source repository. It also means that for each compilation, Cargo will have an empty target folder and have to re-compile all contracts and all dependencies. In order to avoid this, you can optionally mount a Docker volume into the file system, as highlighted here:

 docker run --rm -v "$(pwd)":/code \
+  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
   --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
   cosmwasm/rust-optimizer:0.15.0

Using this cache is considered best practice and included in all our example call snippets.

Before version 0.13.0, the target folder was located at /code/target. This caused situations in which rust-optimizer/workspace-optimizer wrote to the target folder of the host in an unintended way. By ensuring the target location is not a subfolder of the mounted source code we can avoid those sort of problems.

Development

Take a look at the Makefile You can edit the Dockerfile (in a fork), and run make build to compile it.

Notice

This has been tested on Linux (Ubuntu / Debian). There are currently versions of both optimizers for two processor architectures: Intel/Amd 64-bits, and Arm 64-bits (these run natively on Mac M1 machines).

However, the native Arm version produces different wasm artifacts than the Intel version. Given that that impacts reproducibility, non-Intel images and build artifacts contain a "-arm64" suffix, to differentiate and flag them.

Arm images are released to ease development and testing on Mac M1 machines. For release / production use, only contracts built with the Intel optimizers must be used.

More Repositories

1

cosmwasm

Framework for building smart contracts in Wasm for the Cosmos SDK
Rust
1,060
star
2

cw-plus

Production Quality contracts under open source licenses
Rust
506
star
3

wasmd

Basic cosmos-sdk app with web assembly smart contracts
Go
367
star
4

cw-template

Quickstart template to get started writing your own cosmwasm contracts
Rust
283
star
5

awesome-cosmwasm

😎 Curated list of tools, contracts, and projects working with CosmWasm
242
star
6

wasmvm

Go bindings to the CosmWasm VM
Go
173
star
7

ts-codegen

Convert your CosmWasm smart contracts into dev-friendly TypeScript classes so you can focus on shipping code.
TypeScript
116
star
8

sylvia

CosmWasm smart contract framework
Rust
93
star
9

mesh-security-hackathon

Implementation of Sunny's Mesh Security talk (Hackathon / Prototype status)
Rust
88
star
10

cw-tokens

Examples of cw20 usage, extracted from cw-plus, maintained by the community
Rust
85
star
11

dApps

A collection of sample dApps for CosmWasm contracts, using CosmJS frontend SDK
TypeScript
55
star
12

docs-deprecated

Updated documentation repo
JavaScript
52
star
13

CosmWasmJS

Source of the cosmwasm npm package
TypeScript
50
star
14

cw-multi-test

CosmWasm multi-contract testing framework
Rust
46
star
15

cw-storage-plus

Storage abstractions for CosmWasm smart contracts
Rust
35
star
16

testnets

Information on all public CosmWasm testnets
TypeScript
34
star
17

book

CosmWasm book
34
star
18

cosmwasm-go

Enabling CosmWasm smart contracts in Go using TinyGo
Go
29
star
19

token-factory

Pulling out Osmosis token factory module and the custom CosmWasm bindings into it's own repo for easier reuse
Go
24
star
20

resources

23
star
21

tinyjson

Fast JSON serializer for golang.
Go
22
star
22

code-explorer

A code explorer for CosmWasm
TypeScript
21
star
23

cw-minus

Contract helpers originally used for cw-plus contracts/specs
Rust
16
star
24

cosmwasm-verify

Verify CosmWasm build results
Shell
15
star
25

advisories

To publicly communicate advisories about serious bugs in CosmWasm, wasmvm, and wasmd
Shell
14
star
26

drand-verify

A drand verification library in Rust. This can be used by other crates or be compiled to a Wasm blob (< 500 kilobytes) with JavaScript bindings.
Rust
12
star
27

cosmwasm-simulate

Simulation tool for cosmwasm smart contract
Rust
10
star
28

cw-academy-course

CosmWasm academy smart contracts course projects
Rust
7
star
29

mesh-security-ui

Basic UI to try out mesh security
TypeScript
6
star
30

docs

MDX
6
star
31

token-bindings

Minimal Rust bindings for token factory
Rust
5
star
32

CWIPs

CosmWasm Improvement Proposals
Shell
5
star
33

storey

Experimental storage abstractions for blockchain key-value stores
Rust
5
star
34

academy-deploy

TypeScript
4
star
35

cw-cron

Basic job scheduler service implementation for CosmWasm
3
star
36

sylvia-book

3
star
37

name-app

Simple react app on top of cosmwasm, showing use of name server contract
TypeScript
3
star
38

terra-contracts

Custom bindings and sample contracts for Terra integration
Rust
2
star
39

cw-mcs-academy-course

Repository for multi contract systems academy course
Rust
2
star
40

docs-old

Documentation for cosmwasm
JavaScript
2
star
41

simple-option

Demo repo for hackatom video
Rust
2
star
42

cw-storage

CosmWasm library with useful helpers for Storage patterns
Rust
1
star
43

chat.cosmwasm.com

Redirect to our community chat
HTML
1
star
44

cw-tools

Rust
1
star
45

idl

The CosmWasm IDL docs
1
star
46

sylvia-template

Rust
1
star