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.)
(Source)
Read more about Cargo in the official Cargo Book
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 your 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 propertiesname
andversion
[lib]
- Library target settings[profile.release]
- This section is for setting your build profile. Cargo has 4 built-in profiles:dev
,release
,test
, andbench
.[features]
- Conditional compilation features[package.metadata.scripts]
- This section is part of thecargo-run-script
module, it's where scripts are defined. If you are familiar with node,cargo-run-script
brings thenpm 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
For a full list of possible sections and valid properties, see the Cargo Book
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 tricky part of this procedure is that your dependencies have dependencies. If you get a compilation error after updating a dependency, that's usually why (e.g. a sub-dependency has changed or been added).
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 = 3
debug = false
rpath = false
lto = true
debug-assertions = false
codegen-units = 1
panic = 'abort'
incremental = false
overflow-checks = true
[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
[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" }
To update the Increment Cargo.toml to use cosmwasm-std
version 1.0.0-beta5
, the above toml 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 = 3
debug = false
rpath = false
lto = true
debug-assertions = false
codegen-units = 1
panic = 'abort'
incremental = false
overflow-checks = true
[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
[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"
As you probably noticed, the above 2 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
.
To migrate a contract with the archwayd
daemon, use the migrate
command from the tx wasm
module.
Usage:
archwayd tx wasm migrate [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args] [flags]
Example:
archwayd tx wasm migrate ${CONTRACT_ADDRESS} ${NEW_CODE_ID} '{"entrypoint":"value"}' --gas auto --gas-prices 0.05uconst --gas-adjustment 1.4 --from ${WALLET_LABEL} --chain-id "constantine-1" --node "https://rpc.constantine-1.archway.tech:443" --broadcast-mode sync --output json -y
Replace ${CONTRACT_ADDRESS}
, ${CODE_ID}
, and '{"entrypoint":"value"}'
(which is your Instantiation constructor arguments for the new instance), with your own values.