# Arguments in JSON Tutorial

## Package info <a href="#package-info" id="package-info"></a>

This section references the [`CliArgs` example package](/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts/arguments-in-json-tutorial.md), which contains the following manifest:

```toml
[package]
name = "CliArgs"
version = "0.1.0"
upgrade_policy = "compatible"

[addresses]
test_account = "_"

[dependencies.EndlessFramework]
local = "../../framework/endless-framework"
```

Here, the package is deployed under the named address `test_account`.

{% hint style="info" %}
Set your working directory to [endless-move/move-examples/cli\_args](/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts/arguments-in-json-tutorial.md) to follow along:
{% endhint %}

```shell
cd <endless-core-parent-directory>/endless-core/endless-move/move-examples/cli_args
```

## Deploying the package <a href="#deploying-the-package" id="deploying-the-package"></a>

Start by mining a vanity address for Ace, who will deploy the package:

```shell
endless key generate \
    --vanity-prefix 0xace \
    --output-file ace.key
```

{% hint style="info" %}
The exact account address should vary for each run, though the vanity prefix should not.
{% endhint %}

Store Ace's address in a shell variable, so you can call it inline later on:

```
# Your exact address should vary
ace_addr=0xacef1b9b7d4ab208b99fed60746d18dcd74865edb7eb3c3f1428233988e4ba46
```

Fund Ace's account with the faucet (either devnet or testnet):

```shell
endless account fund-with-move --account $ace_addr --private-key-file ace.key
```

Now publish the package under Ace's account:

```shell
endless move publish \
    --named-addresses test_account=$ace_addr \
    --private-key-file ace.key \
    --assume-yes
```

## Entry functions <a href="#entry-functions" id="entry-functions"></a>

The only module in the package, `cli_args.move`, defines a simple `Holder` resource with fields of various data types:

```rust
struct Holder has key, drop {
    u8_solo: u8,
    bytes: vector<u8>,
    utf8_string: String,
    bool_vec: vector<bool>,
    address_vec_vec: vector<vector<address>>,
    type_info_1: TypeInfo,
    type_info_2: TypeInfo,
}
```

A public entry function with multi-nested vectors can be used to set the fields:

```rust
public entry fun set_vals<T1, T2>(
    account: signer,
    u8_solo: u8,
    bytes: vector<u8>,
    utf8_string: String,
    bool_vec: vector<bool>,
    address_vec_vec: vector<vector<address>>,
) acquires Holder {
    let account_addr = signer::address_of(&account);
    if (exists<Holder>(account_addr)) {
        move_from<Holder>(account_addr);
    };
    move_to(&account, Holder {
        u8_solo,
        bytes,
        utf8_string,
        bool_vec,
        address_vec_vec,
        type_info_1: type_info::type_of<T1>(),
        type_info_2: type_info::type_of<T2>(),
    });
}
```

After the package has been published, endless `move run` can be used to call `set_vals()`:

{% hint style="info" %}
To pass vectors (including nested vectors) as arguments from the command line, use JSON syntax escaped with quotes!
{% endhint %}

```shell
endless move run \
    --function-id $ace_addr::cli_args::set_vals \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args \
        u8:123 \
        "hex:0x1234" \
        "string:hello, world\! ♥" \
        "bool:[false, true, false, false]" \
        'address:[["0xace", "0xbee"], ["0xcad"], []]' \
    --private-key-file ace.key \
    --assume-yes
```

The function ID, type arguments, and arguments can alternatively be specified in a JSON file: move-examples/cli\_args/entry\_function\_arguments.json

```json
{
    "function_id": "<test_account>::cli_args::set_vals",
    "type_args": [
        "0x1::account::Account",
        "0x1::chain_id::ChainId"
    ],
    "args": [
        {
            "type": "u8",
            "value": 123
        },
        {
            "type": "hex",
            "value": "0x1234"
        },
        {
            "type": "string",
            "value": "hello, world! ♥"
        },
        {
            "type": "bool",
            "value": [
                false,
                true,
                false,
                false
            ]
        },
        {
            "type": "address",
            "value": [
                [
                    "0xace",
                    "0xbee"
                ],
                [
                    "0xcad"
                ],
                []
            ]
        }
    ]
}
```

Here, the call to `endless move run` looks like:

```shell
endless move run \
    --json-file entry_function_arguments.json \
    --private-key-file ace.key \
    --assume-yes
```

{% hint style="info" %}
If you are trying to run the example yourself don't forget to substitute Ace's actual address for `<test_account>` in `entry_function_arguments.json`!
{% endhint %}

## View functions <a href="#view-functions" id="view-functions"></a>

Once the values in a `Holder` have been set, the `reveal()` view function can be used to check the first three fields, and to compare type arguments against the last two fields:

```rust
struct RevealResult has drop {
        u8_solo: u8,
        bytes: vector<u8>,
        utf8_string: String,
        bool_vec: vector<bool>,
        address_vec_vec: vector<vector<address>>,
        type_info_1_match: bool,
        type_info_2_match: bool
    }

#[view]
/// Pack into a `RevealResult` the first three fields in host's
/// `Holder`, as well as two `bool` flags denoting if `T1` & `T2`
/// respectively match `Holder.type_info_1` & `Holder.type_info_2`,
/// then return the `RevealResult`.
public fun reveal<T1, T2>(host: address): RevealResult acquires Holder {
    let holder_ref = borrow_global<Holder>(host);
    RevealResult {
        u8_solo: holder_ref.u8_solo,
        bytes: holder_ref.bytes,
        utf8_string: holder_ref.utf8_string,
        bool_vec: holder_ref.bool_vec,
        address_vec_vec: holder_ref.address_vec_vec,
        type_info_1_match:
            type_info::type_of<T1>() == holder_ref.type_info_1,
        type_info_2_match:
            type_info::type_of<T2>() == holder_ref.type_info_2
    }
}
```

This view function can be called with arguments specified either from the CLI or from a JSON file:

```shell
endless move view \
    --function-id $ace_addr::cli_args::reveal \
    --type-args \
        0x1::account::Account \
        0x1::account::Account \
    --args address:$ace_addr
```

```shell
endless move view --json-file view_function_arguments.json
```

{% hint style="info" %}
If you are trying to run the example yourself don't forget to substitute Ace's actual address for `<test_account>` in `view_function_arguments.json` (twice)!
{% endhint %}

```json
{
    "function_id": "<test_account>::cli_args::reveal",
    "type_args": [
        "0x1::account::Account",
        "0x1::account::Account"
    ],
    "args": [
        {
            "type": "address",
            "value": "<test_account>"
        }
    ]
}
```

Output:

```json
{
  "Result": [
    {
      "address_vec_vec": [
        [
          "0xace",
          "0xbee"
        ],
        [
          "0xcad"
        ],
        []
      ],
      "bool_vec": [
        false,
        true,
        false,
        false
      ],
      "bytes": "0x1234",
      "type_info_1_match": true,
      "type_info_2_match": false,
      "u8_solo": 123,
      "utf8_string": "hello, world! ♥"
    }
  ]
}
```

## Script functions <a href="#script-functions" id="script-functions"></a>

The package also contains a script, `set_vals.move`, which is a wrapper for the setter function:

```rust
script {
    use test_account::cli_args;
    use std::vector;
    use std::string::String;

    /// Get a `bool` vector where each element indicates `true` if the
    /// corresponding element in `u8_vec` is greater than `u8_solo`.
    /// Then pack `address_solo` in a `vector<vector<<address>>` and
    /// pass resulting argument set to public entry function.
    fun set_vals<T1, T2>(
        account: signer,
        u8_solo: u8,
        bytes: vector<u8>,
        utf8_string: String,
        u8_vec: vector<u8>,
        address_solo: address,
    ) {
        let bool_vec = vector::map_ref(&u8_vec, |e_ref| *e_ref > u8_solo);
        let addr_vec_vec = vector[vector[address_solo]];
        cli_args::set_vals<T1, T2>(account, u8_solo, bytes, utf8_string, bool_vec, addr_vec_vec);
    }
} 
```

First compile the package (this will compile the script):

```shell
endless move compile --named-addresses test_account=$ace_addr
```

Next, run endless `move run-script` Arguments via CLI

```shell
endless move run-script \
    --compiled-script-path build/CliArgs/bytecode_scripts/set_vals.mv \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args \
        u8:123 \
        "hex:0x1234" \
        "string:hello, world\! ♥" \
        "u8:[122, 123, 124, 125]" \
        address:"0xace" \
    --private-key-file ace.key \
    --assume-yes
```

Arguments via JSON file

```shell
endless move run-script \
    --compiled-script-path build/CliArgs/bytecode_scripts/set_vals.mv \
    --json-file script_function_arguments.json \
    --private-key-file ace.key \
    --assume-yes
```

script\_function\_arguments.json

```json
{
    "type_args": [
        "0x1::account::Account",
        "0x1::chain_id::ChainId"
    ],
    "args": [
        {
            "type": "u8",
            "value": 123
        },
        {
            "type": "hex",
            "value": "0x1234"
        },
        {
            "type": "string",
            "value": "hello, world! ♥"
        },
        {
            "type": "u8",
            "value": [
                122,
                123,
                124,
                125
            ]
        },
        {
            "type": "address",
            "value": "0xace"
        }
    ]
}
```

Both such script function invocations result in the following `reveal()` view function output:

```shell
endless move view \
    --function-id $ace_addr::cli_args::reveal \
    --type-args \
        0x1::account::Account \
        0x1::chain_id::ChainId \
    --args address:$ace_addr
```

Output:

```json
{
  "Result": [
    {
      "address_vec_vec": [["0xace"]],
      "bool_vec": [false, false, true, true],
      "bytes": "0x1234",
      "type_info_1_match": true,
      "type_info_2_match": true,
      "u8_solo": 123,
      "utf8_string": "hello, world! ♥"
    }
  ]
}
```

{% hint style="info" %}
As of the time of this writing, the endless CLI only supports script function arguments for vectors of type `u8`, and only up to a vector depth of 1. Hence `vector<address>` and `vector<vector<u8>>` are invalid script function argument types.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.endless.link/endless/devbuild/build/endless-cli/use-endless-cli/working-with-move-contracts/arguments-in-json-tutorial.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
