Working With Move Contracts
The Aptos CLI is mostly used to compile, test, and formally verify Move contracts. If you have not installed the Aptos CLI yet, you can do so by following the steps here Install the Aptos CLI.
You can jump to specific sections by using the table of contents on the right.
To see how to chain together Move contracts on-chain using the CLI, you can follow this “CLI Arguments” tutorial.
Throughout this document there are parts of commands you will have to modify to fit your situation. Those variables will be wrapped in triangle brackets <like this>
.
1. Compiling Move
You can compile a Move package by running:
aptos move compile --package-dir <your-package-directory>
The package directory is the folder which contains the Move.toml
file.
Based on the settings in your Move.toml
file, you may need to pass in additional information to that compile command.
For example, if you look at the hello_blockchain example Move contract, in the Move.toml
file it specifies a variable named address called hello_blockchain
.
[addresses]
hello_blockchain = "_"
So, to compile this, you will need to pass in the value for hello_blockchain
with the --named-addresses
parameter.
You can use either a full address e.g. 0x123456...7890
or a name of a profile in the CLI e.g. default
or superuser
.
Below we will use default
in our example:
aptos move compile --package-dir aptos-move/move-examples/hello_blockchain/ --named-addresses hello_blockchain=default
You can learn more about optional parameters when compiling Move contracts by running aptos move compile --help
.
2. Unit Testing Move Contracts
The Aptos CLI can also be used to compile and run unit tests locally by running:
aptos move test --package-dir <your-package-directory>
This command both compiles and runs tests, so it needs all the same optional parameters you use when compiling.
You can learn more about the optional parameters for testing move contracts by running aptos move test --help
.
Printing Debugging Information
When writing tests, it can be helpful to print out debug information or stack traces. You can do that by using debug::print
and debug::print_stack_trace
to print information when you use aptos move test
. See an example of how they are used in DebugDemo.move.
To see the output of testing DebugDemo.move’s package:
- Clone
[aptos-core](https://github.com/aptos-labs/aptos-core)
. - Navigate to the debug-move-example by running
cd crates/aptos/debug-move-example
. - Run
aptos move test
.
You should see:
Running Move unit tests
[debug] 0000000000000000000000000000000000000000000000000000000000000001
Call Stack:
[0] 0000000000000000000000000000000000000000000000000000000000000001::Message::sender_can_set_message
Code:
[4] CallGeneric(0)
[5] MoveLoc(0)
[6] LdConst(0)
> [7] Call(1)
[8] Ret
Locals:
[0] -
[1] 0000000000000000000000000000000000000000000000000000000000000001
Operand Stack:
For more on how to write unit tests with Move, follow this Move tutorial (step 2 focuses on unit tests).
3. Generating Test Coverage Reports
The Aptos CLI can be used to analyze and improve the testing of your Move modules. To use this feature:
To see the code coverage of your tests run the following command from your Move package’s directory:
aptos move test --coverage
If you would like to focus your coverage down to specific packages, you can do so with the --filter
option. To narrow even further to specific Move modules, use the --module
parameter.
For more detailed / advanced coverage information (such as your test coverage in the compiled bytecode) you can run aptos move coverage
. With that command, the CLI will prompt you for more details on what specifically you would like more coverage information about.
You can learn more about optional parameters for test coverage by running aptos move test --help
and aptos move coverage --help
.
4. Publishing Move Contracts
To publish a Move contract, you will need to run:
aptos move publish --package-dir <your-package-directory>
Note that when you are publishing on the main network, the credentials you pass into optional parameters like --named-addresses
will need to reflect accounts on that network instead of test credentials.
The package will be published to your default profile in the CLI. You can override that to specify which account to publish to using --profile
in the command. To generate a new profile for a specific account, use aptos init --profile <name_of_profile>
and follow the prompts.
Please also note that when publishing Move modules, if multiple modules are in one package, then all modules in that package must use the same account. If they use different accounts, then the publishing will fail at the transaction level.
You can estimate the gas fees associated with publishing your Move contract by using the Gas Profiler.
By default Move contracts publish their source code. To avoid publishing with source code, publish with the --included-artifacts none
argument.
Since the Aptos blockchain is inherently open by design, note that even without source access it is possible to regenerate Move source from published Move bytecode.
5. Running Published Contracts
Now that you have published your Move package, you can run it directly from the CLI.
You will first need to construct your function-id
by combining:
<the-address-you-published-to>::<module_name>::<function_name>
You can then pass in args by using the --args
parameter.
As an example, if you were to have published the hello_blockchain example package to an account with an address b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb
you could run its set_message
function via the following command:
aptos move run --function-id 0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb::message::set_message --args string:hello!
Which should result in:
{
"Result": {
"changes": [
{
"address": "b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"data": {
"authentication_key": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"self_address": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"sequence_number": "3"
},
"event": "write_resource",
"resource": "0x1::account::Account"
},
{
"address": "b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"data": {
"coin": {
"value": "9777"
},
"deposit_events": {
"counter": "1",
"guid": {
"id": {
"addr": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"creation_num": "1"
}
}
},
"withdraw_events": {
"counter": "1",
"guid": {
"id": {
"addr": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"creation_num": "2"
}
}
}
},
"event": "write_resource",
"resource": "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"
},
{
"address": "b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"data": {
"counter": "4"
},
"event": "write_resource",
"resource": "0x1::guid::Generator"
},
{
"address": "b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"data": {
"message": "hello!",
"message_change_events": {
"counter": "0",
"guid": {
"id": {
"addr": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb",
"creation_num": "3"
}
}
}
},
"event": "write_resource",
"resource": "0xb9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb::Message::MessageHolder"
}
],
"gas_used": 41,
"success": true,
"version": 3488,
"vm_status": "Executed successfully"
}
}
6. (Optional) Formally Verifying Move Scripts
For cases where you want to guarantee that your code works as expected beyond unit testing, you can use the Move Prover to formally verify your Move contract code.
You can install the Move Prover by following these steps.
Once you have installed the Move Prover, you can use it from the Aptos CLI by running:
aptos move prove --package-dir <your-package-directory>
To learn how to formally verify your code, please follow the in-depth Move tutorial here (step 7 and 8 cover how to use the Move Prover and write formal specifications in the example code).