This site requires Javascript to be enabled.

Cargo

Cargo is Rust's build system and package manager. Most Rustaceans use this tool to manage their Rust projects because Cargo handles a lot of tasks for you, such as building your code, downloading the libraries your code depends on, and building those libraries. (We call the libraries that your code needs dependencies.)

Read more about Cargo in the official Cargo Book

Overview

Here's an overview of some common Cargo commands used in Archway projects:

  • cargo build: Compiles your project and its dependencies. Use cargo build --release to compile with optimizations for a production build.
  • cargo test: Runs tests for your project and its dependencies.
  • cargo run: Compiles and runs your project.
  • cargo update: Updates your project's dependencies according to the specified version ranges in the Cargo.toml file.

Workspaces

Cargo workspaces help manage multiple related projects within a single repository. To create and configure a workspace, add a workspace section to the Cargo.toml file, and list the project paths under the members key.

Example:

[workspace]members = [  "project-1",  "project-2",  "project-3",]

Cargo.toml

The Cargo.toml file at the root of an Archway project is called its manifest, and contains all of the metadata Cargo needs to compile the smart contract project and its dependencies. Every manifest file consists of one or more sections.

The following sections are some examples commonly found in Archway projects:

  • package - The first section in a Cargo.toml is always package and must include the metadata properties name and version
  • lib - Library target settings
  • profile.release - This section is for setting your build profile. Cargo has 4 built-in profiles: dev, release, test, and bench.
  • features - Conditional compilation features
  • package.metadata.scripts - This section is part of the cargo-run-script module, it's where scripts are defined. If you are familiar with node, cargo-run-script brings the npm run functionality to the Rust and Cargo ecosystem
  • dependencies - Use this section for defining your project's dependencies for compilation and releases
  • dev-dependencies - Use this section for defining your project's dependencies for examples, tests, and benchmarks

Check the Cargo book for the full list of possible sections and valid properties.

Semantic Versioning

Cargo bakes in the concept of Semantic Versioning. It is configured to look for dependencies on crates.io by default. Only the name and a version string are required in this case.

Example:

[dependencies]cosmwasm-std = "1.0.0-beta"

Updating dependencies

It's recommended to follow CosmWasm development and release schedule. As fixes or new features become available, it could be advantageous or critical to update your project dependencies.

The only challenging aspect of this process is that your dependencies may have their own dependencies. If you encounter a compilation error after updating a dependency, it is likely due to a change or addition in a sub-dependency.

Here's an older version of the Cargo.toml for the Increment code template:

Cargo.toml for cosmwasm-std version 0.16.2
[package]name = "{{project-name}}"version = "0.1.0"authors = ["{{authors}}"]edition = "2018"exclude = [  # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.  "contract.wasm",  "hash.txt",]# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[lib]crate-type = ["cdylib", "rlib"][profile.release]opt-level = 3debug = falserpath = falselto = truedebug-assertions = falsecodegen-units = 1panic = 'abort'incremental = falseoverflow-checks = true[features]# for more explicit tests, cargo test --features=backtracesbacktraces = ["cosmwasm-std/backtraces"]# use library feature to disable all instantiate/execute/query exportslibrary = [][package.metadata.scripts]optimize = """docker run --rm -v "$(pwd)":/code \  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \  cosmwasm/rust-optimizer:0.12.3"""[dependencies]cosmwasm-std = { version = "0.16.2" }cosmwasm-storage = { version = "0.16.0" }cw-storage-plus = "0.8.0"cw2 = "0.8.1"schemars = "0.8.3"serde = { version = "1.0.127", default-features = false, features = ["derive"] }thiserror = { version = "1.0.26" }[dev-dependencies]cosmwasm-schema = { version = "0.16.0" }

Source

To update the Increment Cargo.toml to use cosmwasm-std version 1.0.0-beta5, the above file becomes:

Cargo.toml for cosmwasm-std version 1.0.0-beta5
[package]name = "{{project-name}}"version = "0.1.0"authors = ["{{authors}}"]edition = "2018"exclude = [  # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.  "contract.wasm",  "hash.txt",]# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[lib]crate-type = ["cdylib", "rlib"][profile.release]opt-level = 3debug = falserpath = falselto = truedebug-assertions = falsecodegen-units = 1panic = 'abort'incremental = falseoverflow-checks = true[features]# for more explicit tests, cargo test --features=backtracesbacktraces = ["cosmwasm-std/backtraces"]# use library feature to disable all instantiate/execute/query exportslibrary = [][package.metadata.scripts]optimize = """docker run --rm -v "$(pwd)":/code \  -e CARGO_TERM_COLOR=always \  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \  cosmwasm/rust-optimizer:0.12.5"""[dependencies]cosmwasm-std = "1.0.0-beta5"cosmwasm-storage = "1.0.0-beta5"cw-storage-plus = "0.12"cw2 = "0.12"schemars = "0.8"serde = { version = "1.0", default-features = false, features = ["derive"] }thiserror = "1.0"[dev-dependencies]cosmwasm-schema = "1.0.0-beta5"

SourceView the GitHub diff

As you probably noticed, the above two examples are nearly identical, but all packages listed in the dependencies section have been changed.

Upgrading a deployed contract

Changing dependencies produces different wasm output (even when there's no substantive change to the contract source code). However, it's possible to update even a deployed contract.

Migrating a contract will retain its address but associate it with a new Code ID.

archwayd tx wasm migrate [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args] [flags]

For example you can launch:

mainnet

testnet

archwayd tx wasm migrate <contract-address> <new-code-id> '{"entrypoint":"value"}' --gas auto --gas-prices $(archwayd q rewards estimate-fees 1 --node 'https://rpc.mainnet.archway.io:443' --output json | jq -r '.gas_unit_price | (.amount + .denom)') --gas-adjustment 1.4 --from <wallet-label> --chain-id archway-1 --node https://rpc.mainnet.archway.io:443 --broadcast-mode sync --output json -y

and replace the values <contract-address>, <new-code-is>, and {"entrypoint":"value"} (which is the instantiation constructor).