CLI
Introduction
As mentioned before, the meta tool comes in two flavors, one for the individual contract (based on the contract's ABI), and the other as a standalone tool.
We will go through the CLI of both of these flavors.
Standalone tool CLI
The all command
But first, there is a special feature that needs additional explanation: the sc-meta all ... command.
The standalone and the contract tools are not completely separate: the standalone tool can control multiple smart contract projects in a single command.
This is where the all command comes in: all it does is find all contracts in a given folder and call the contract tool for each of them with the given arguments.
For example:
sc-meta all abiwill generate the ABIs for all contracts;sc-meta all build --lockedwill build all contracts, with the crate versions given by Cargo.lock;sc-meta all cleanwill clean all projects;- etc.
You can call sc-meta all help and see that the CLI docs are almost the same as those of the individual contract tool.
A related command is the info command, which just prints a tree with all the contract and contract libraries in a folder, without doing anything to them.
Since the CLI of the individual contract tool is available in the standalone tool, the following two commands are equivalent:
cd my-contract
sc-meta all build
cd my-contract/meta
cargo run build
Parameters:
--path- Target directory where to call all contract meta crates.
- default: current directory.
--ignore- Ignore all directories with these names.
- default:
target.
--no-abi-git-version- Skips loading the Git version into the ABI
--target-dir-meta- For the meta crates, allows specifying the target directory where the Rust compiler will build the intermediary files. Sharing the same target directory can speed up building multiple contract crates at once.
- default: uses the workspace, or builds in
meta/target.
--target-dir-all- Overrides both the
--target-dir-metaand the--target-dir-wasmargs.
- Overrides both the
Calling info
The info command prints an overview of the contracts and libraries and residing under a folder. It also prints their framework versions.
As an example, below is the output of calling it in the example contract folder in the framework:

Parameters:
--path- Target directory where to call all contract meta crates.
- default: current directory.
--ignore- Ignore all directories with these names.
- default:
target.
Calling upgrade
Calling sc-meta upgrade will try to automatically alter the code of a contract or group of contracts to make it/them compatible with the latest rust framework version.
The oldest version currently supported is 0.28.0. Any older than that, and the developer will need to manually upgrade it to 0.28.0.
It is especially important when upgrading from 0.38 to 0.39.0, since a lot of changes happened at that point.
For projects with multiple contract crates, we recommend upgrading all of them at once. The upgrade algorithm goes step by step, version after version. For some of the major versions, it also checks that the project compiles before moving on. This is to give developers the chance to fix issues manually, if necessary, and not have those issues pile up. If there are local dependencies between contracts, the upgrader will not be able to do the check unless all of them are upgraded together.
Generally, we strongly recommend to ensure code versioning or at least a backup of the contract code to avoid the impossibility of reverting permanent changes. This automatic code altering process involved in using sc-meta upgrade highly raises this recommendation.
Parameters:
--path- Target directory where to call all contract meta crates.
- default: current directory.
--ignore- Ignore all directories with these names.
- default:
target.
--to- Overrides the version to upgrade to.
- default: the last released version.
--no-check- By default
upgradecompile checks the project after each major version upgrade. This is to allow developers that upgrade multiple versions to address issues with the upgrade before too many such issues get to accumulate. This feature can be turned off by the--no-checkflag. - default: project is compiled.
- By default
Calling local-deps
Calling sc-meta local-deps will create in each contract a report of the local dependencies between contracts and libraries. This helps with the reproducible builds, but might be extended in the future for other uses.
Example output (abridged):
{
"root": "/home/user/multiversx/mx-exchange-sc/",
"contractPath": "/home/user/multiversx/mx-exchange-sc/dex/pair",
"commonDependencyPath": "/home/user/multiversx/mx-exchange-sc",
"dependencies": [
{
"path": "common/common_errors",
"depth": 1
},
{
"path": "common/common_structs",
"depth": 1
},
{
"path": "common/modules/legacy_token_decode_module",
"depth": 3
},
{
"path": "common/modules/locking_module",
"depth": 2
},
{
"path": "common/modules/math",
"depth": 2
}
]
}
Parameters:
--path- Target directory where to call all contract meta crates.
- default: current directory.
--ignore- Ignore all directories with these names.
- default:
target.
Calling new
Creates a new smart contract project from a standard template.
The tool will replace all necessary names in the project, based on the the project name given by the user. These include:
- the crate name,
- the contract trait name,
- the file name of the main source file.
Parameters:
--template- The contract template to clone. Available options can be retrieve by using this
- Required.
--name- The new name the contract is to receive.
- default: If missing, the template name will be kept.
--tag- The framework version on which the contracts should be created.
- default: The latest released version.
--path- Target directory where to create the new contract directory.
- default: current directory.
Calling templates
This command lists all available templates. As of framework version 0.43.2, they are:
crypto-zombies
empty
adder
Parameter:
--tag- The framework version on which the contracts should be created.
- default: The latest released version.
Calling test
This command is a useful shorthand for running various types of tests.
Parameters:
--path- Target directory where to generate contract integration tests.
- default: current directory.
--go- Use this argument to only run the mx-scenario-go tool, directly. It is equivalent to running
mx-scenario-go run. - You can find out how to install
mx-scenario-gohere. - default:
false
- Use this argument to only run the mx-scenario-go tool, directly. It is equivalent to running
--scen- This argument causes cargo test to be run with the
multiversx-sc-scenario/run-go-testsfeature, causing tests relying on the mx-scenairo-go tool to also be run. - default:
false - If
scenandgoare both specified, scen overrides the go argument.
- This argument causes cargo test to be run with the
--nocapture- This argument prints the entire output of the vm.
- default:
false
--help- Print help
--version- Print version
Calling test-gen
The test-gen tool is used to generate boilerplate code when integrating JSON scenario files in a contract's Rust test suite.
In short:
Contracts often have JSON scenario tests associated with them, which normally reside in the scenarios folder, under the contract crate root.
In order to execute them as part of the CI, it is helpful to generate a Rust test for each of them. The test-gen tool does just that.
These integration tests come in two flavors:
- Rust tests, that exclusively use the Rust debugger infrastructure;
- VM tests that use the Go infrastructure.
Read more about JSON scenarios in smart contract projects here.
Parameters:
--path- Target directory where to call all contract meta crates.
- default: current directory.
--ignore- Ignore all directories with these names.
- default:
target.
--create- Creates test files if they don't exist.
Calling install
This command can be used to quickly install other tools needed for smart contract development, interaction and testing.
Parameters:
all- Installs all the known tools.
mx-scenario-go- Installs the
mx-scenario-gotool. - Can further specify the framework version on which the contracts should be created by using
--tag
- Installs the
Individual contract CLI
Calling abi
ABI generation can be triggered by calling sc-meta all abi or cargo run abi in the contract root folder. This command generates the main ABI file of the contract (<contract>.abi.json) along with all the other json files created if #[esdt_attribute("name", type)] was used (<name>.esdt-abi.json). You can read more about ESDT Attribute ABI here.
ABI generation will also be triggered for all the other contract commands, such as build, build-dbg, update, etc. The abi command is for when we just want to generate the ABI and do nothing else.
For a simple contract such as:
#[multiversx_sc::contract]
#[esdt_attribute("myTicker", u64)]
pub trait SomeContract {
#[init]
fn init(&self) {}
}
The produced files are:
output
├── myTicker.esdt-abi.json
└── some_contract.abi.json
Arguments:
--pathUsed to specify a target directory where to call all contract meta crates. Will be current directory if not specified.--ignoreFollowed by a name is used to ignore all directories with these names [default:target].--no-abi-git-versionSkips loading the Git version into the ABI--target-dir-metaFor the meta crates, allows specifying the target directory where the Rust compiler will build the intermediary files. Sharing the same target directory can speed up building multiple contract crates at once.--target-dir-allOverrides both the--target-dir-metaand the--target-dir-wasmargs.
Calling build
A build can be triggered by calling either sc-meta all build or cargo run build in the meta crate of the contract. In fact, the standalone sc-meta tool simply forwards the command to the contract meta crate itself.
By default, this command will produce three files for each output contract: the ABI (<contract>.abi.json), the contract (<contract>.wasm) and a json file with all the used VM EI imported functions (<contract>.imports.json). For the multisig example above, the produced files are as follows:
output
├── multisig-full.abi.json
├── multisig-full.imports.json
├── multisig-full.wasm
├── multisig-view.abi.json
├── multisig-view.imports.json
├── multisig-view.wasm
├── multisig.abi.json
├── multisig.imports.json
└── multisig.wasm
Arguments:
--lockedUses the version fromCargo.lock, without updating. Required for reproducible builds.--wasm-namefollowed by name: Replaces the main contract's name with this one. Does nothing for secondary contracts.--wasm-suffixfollowed by a suffix: Adds a dash and this suffix to all produced contracts. E.g.cargo run build --wasm-suffix dbgon multisig will produce contractsmultisig-dbg.wasm,multisig-view-dbg.wasmandmultisig-full-dbg.wasm.--wasm-symbolsDoes not optimize away symbols at compile time, retains function names, good for investigating the WAT.--no-wasm-optDoes not applywasm-optafter the build, this retains function names, good for investigating the WAT.--watAlso generates a WAT file for each of the contract outputs. It does so by callingwasm2wat.--mirAlso emit MIR files when building.--llvm-irAlso emit LL (LLVM) files when building.--no-abi-git-versionSkips loading the Git version into the ABI.--no-importsDoes not generate an EI imports JSON file for each contract, as is the default.--target-dir-wasmAllows specifying the target directory where the Rust compiler will build the intermediary files. Sharing the same target directory can speed up building multiple contract crates at once.--target-dirSynonym of--wasm-target-dir, used for backwards compatibility.--twiggy-topGenerate a twiggy top report after building.--twiggy-pathsGenerate a twiggy paths report after building.--twiggy-monosGenerate a twiggy monos report after building.--twiggy-dominatorsGenerate a twiggy dominators report after building.
Additional parameters are inherited from all, when running out of the standalone tool:
--target-dir-metaFor the meta crates, allows specifying the target directory where the Rust compiler will build the intermediary files.--target-dir-allOverrides both the--target-dir-metaand the--target-dir-wasmargs.
Calling build-dbg
There is another command, provided for convenience: cargo run build-dbg. Calling this is equivalent to cargo run build --wasm-symbols --no-wasm-opt --wasm-suffix "dbg" --wat --no-imports. It is ideal for developers who want to investigate the WebAssembly output produced by the compiler.
The output for build-dbg in the multisig example would be:
output
├── multisig.abi.json
├── multisig-dbg.wasm
├── multisig-dbg.wat
├── multisig-full.abi.json
├── multisig-full-dbg.wasm
├── multisig-full-dbg.wat
├── multisig-view.abi.json
├── multisig-view-dbg.wasm
└── multisig-view-dbg.wat
It accepts all the arguments from build, so --target-dir works here too.
Calling twiggy
This command is similar to build-dbg, in that it provides a shorthand for building contracts and analyzing their size. It is equivalent to running cargo run build-dbg --twiggy-top --twiggy-paths --twiggy-monos --twiggy-dominators.
Calling clean
Calling sc-meta all clean in the contract folder will remove all build artifacts, including the output folder.
Calling snippets
Calling cargo run snippets in the meta crate or sc-meta all snippets in the root crate will create a project called interactor in the contract main directory, containing auto-generated boilerplate code for building an interactor for the current contract.
An interactor is a small tool, meant for developers to interact with the contract on-chain and write system tests. Being written in Rust, it is ideal for quick interactions and tinkering, directly from the contract project.
Inside the interactor project there is the interactor source file called interact_main.rs, a config.toml state file containing the chain simulator config, a config.rs file containing the source code for parsing the config and a newly generated contract proxy (proxy.rs). The sc-config.toml file of the contract (if existent) will be updated with the newly created proxy path (to the interactor project) or created from scratch if not existent.
After calling sc-meta all snippets in the factorial smart contract crate, we get:

Parameters:
--overwriteOverride snippets project if it already exists. Rewritessc-config.tomlas well, placing only interactor as proxy path.--pathTarget directory where to call all contract meta crates. Will be current directory if not specified.--ignoreIgnore all directories with these names. [default: target]--no-abi-git-versionSkips loading the Git version into the ABI.--target-dir-metaFor the meta crates, allows specifying the target directory where the Rust compiler will build the intermediary files. Sharing the same target directory can speed up building multiple contract crates at once.--target-dir-allOverrides both the --target-dir-meta and the --target-dir-wasm args.
Calling cs
Calling cargo run cs in the meta crate or sc-meta cs in the root crate will start the interaction with the chain simulator. In order to start an action, one must choose between the following subcommands.
Subcommands:
installPulls the latest chain simulator docker image available. This command needs Docker to be installed and running on the current machine.startStarts the chain simulator in verbose mode atlocalhost:8085.stopStops the chain simulator.