# Working With Move Contracts

The Endless CLI is mostly used to compile, test, and formally verify Move contracts. If you have not installed the Endless CLI yet, you can do so by following the steps here Install the Endless CLI.

You can jump to sections here:

1. Compiling Move
2. Unit Testing Move Contracts
3. Generating Test Coverage Reports
4. Publishing Move Contracts
5. Running Published Contracts
6. (Optional) Formally Verifying Move Scripts

To see how to chain together Move contracts on-chain using the CLI, you can follow this "CLI Arguments" tutorial.

{% hint style="info" %}
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>`.
{% endhint %}

## 1. Compiling Move <a href="#id-1.-compiling-move" id="id-1.-compiling-move"></a>

You can compile a Move package by running:

```
endless move compile --package-dir <your-package-directory>
```

{% hint style="info" %}
The package directory is the folder which contains the `Move.toml` file.
{% endhint %}

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](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts), 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.

```shell
endless move compile \
  --package-dir endless-move/move-examples/hello_blockchain/ \
  --named-addresses hello_blockchain=superuser
```

You can learn more about optional parameters when compiling Move contracts by running endless `move compile --help`.

## 2. Unit Testing Move Contracts <a href="#id-2.-unit-testing-move-contracts" id="id-2.-unit-testing-move-contracts"></a>

The Endless CLI can also be used to compile and run unit tests locally by running:

```shell
endless 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 `endless 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 `endless move test`. See an example of how they are used in [DebugDemo.move](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts).

To see the output of testing [DebugDemo.move](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts)’s package:

1. Clone [endless-core](https://github.com/endless-labs/endless.git).
2. Navigate to the [debug-move-example](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts) by running `cd crates/endless/debug-move-example`.
3. Run endless `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](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts).

## 3. Generating Test Coverage Reports <a href="#id-3.-generating-test-coverage-reports" id="id-3.-generating-test-coverage-reports"></a>

The Endless 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:

```
endless 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 `endless 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 `endless move test --help` and `endless move coverage --help`.

## 4. Publishing Move Contracts <a href="#id-4.-publishing-move-contracts" id="id-4.-publishing-move-contracts"></a>

To publish a Move contract, you will need to run:

```shell
endless 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 endless `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.

:::caution By default Move contracts publish their source code. To avoid publishing with source code, publish with the `--included-artifacts none` argument.

Since the Endless 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 <a href="#id-5.-running-published-contracts" id="id-5.-running-published-contracts"></a>

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](https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts) to an account with an address `b9bd2cfa58ca29bce1d7add25fce5c62220604cd0236fe3f90d9de91ed9fb8cb` you could run its `set_message` function via the following command:

```
endless 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::endless_coin::EndlessCoin>"
      },
      {
        "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 <a href="#id-6.-optional-formally-verifying-move-scripts" id="id-6.-optional-formally-verifying-move-scripts"></a>

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.

Once you have installed the Move Prover, you can use it from the Endless CLI by running:

```shell
endless move prove --package-dir <your-package-directory>
```

To learn how to formally verify your code, please follow the in-depth Move tutorial [here](ttps://github.com/endless-labs/endless/tree/main/endless-move/move-examples/move-tutorial) (step 7 and 8 cover how to use the Move Prover and write formal specifications in the example code).
