> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genlabs.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy a contract to DevNet

> Push a built contract to DevNet, deploy an instance, install components, call methods, and query state, using `gen client`.

This guide walks through push, deploy, install, and calling methods on DevNet with `gen client`. Steps 1–5 use **simple-token** from [Build your first contract](/tutorials/recipes/build-a-contract); [Composing with another contract](#composing-with-another-contract) deploys a second token instance and an **exchange** that references both.

Contract setup on the Grid is staged:

* **Push** publishes compiled code. Upload the artifact bundle from your `*_modules.json` manifest; the chain stores the code and returns a `contract_code_id`. The same push can back many deploys.
* **Deploy** instantiates that code, creating a root component on an entity. The runtime runs the contract's `#[deploy]` hook once and returns a `contract` address and `root_component_id`.
* **Install** adds non-root [components](/user-guide/concepts/components) from the contract on an entity. Deploy already creates the root component; install is for every other component type the contract defines.

Once setup is done, you call methods with activations. From the CLI:

| Command                                           | What it does                                                                                    |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `push`                                            | Uploads contract code, returns a `contract_code_id`                                             |
| `deploy`                                          | Instantiates the code, runs `#[deploy]`, returns a `contract` address and a `root_component_id` |
| `install`                                         | Installs a non-root component on the deployed instance                                          |
| `build-activation` + `sign-and-submit-activation` | Calls a state-changing method                                                                   |
| `view`                                            | Calls a read-only method                                                                        |

## Prerequisites

* The `gen` CLI configured against DevNet. See [Configuring for DevNet](/reference/cli/configuration#configuring-for-devnet).
* A built contract manifest at `<contract>/artifacts/<contract>_modules.json`. See [Build your first contract](/tutorials/recipes/build-a-contract).
* A funded DevNet wallet — your [entity](/user-guide/concepts/entities-and-accounts) on chain and the key that signs activations. The manifest is what you push; the wallet publishes code, receives the deployed instance, and signs every state-changing step. Follow [Quickstart](/quickstart/index) Steps 3–4.

Stash the active account in an env var; every command below passes it as `--account`:

```bash theme={null}
ACCOUNT=$(gen wallet --json show --account-address-only | jq -r .result.account)
```

## Step 1: Push the contract code

From `demos/from-token-to-amm`:

```bash theme={null}
gen client --json push \
  --file solutions/02-simple-token/artifacts/simple_token_modules.json \
  --account $ACCOUNT
```

Output:

```json theme={null}
{
  "ok": true,
  "result": {
    "activation_id": "0x...",
    "contract_code_id": "grd@..."
  }
}
```

Save the `contract_code_id`; you need it for deploy.

## Step 2: Deploy an instance

```bash theme={null}
gen client --json deploy \
  --contract-code-id <contract_code_id> \
  --account $ACCOUNT
```

If your contract's `#[deploy]` takes parameters, pass them as JSON via `--deploy-params`. Simple-token for example requires `name` and `symbol`:

```bash theme={null}
gen client --json deploy \
  --contract-code-id <contract_code_id> \
  --account $ACCOUNT \
  --deploy-params '{"name":"Token A","symbol":"TKA"}'
# → save the Token A contract address
```

For deploy parameters that take a `GvmContract` argument (composing with another deployed contract), see [Composing with another contract](#composing-with-another-contract) below.

The result includes two fields you need:

* **`contract`**: the bech32m address of the deployed instance. Pass this to `install`.
* **`root_component_id`**: a 4-part, comma-separated string for the root component. Method calls on other components use the 4-part `component_id` returned by `install`.

## Step 3: Install components

Simple-token defines issuer (`component_type_index` 1) and holder (2). Install each on the deployed instance:

```bash theme={null}
gen client --json install \
  --contract <contract> \
  --account $ACCOUNT \
  --component-type-index 1
# → save component_id as ISSUER_ID

gen client --json install \
  --contract <contract> \
  --account $ACCOUNT \
  --component-type-index 2
# → save component_id as HOLDER_ID
```

Steps 1–3 walk through contract setup on chain — **push**, **deploy**, and **install** — to get components ready. Steps 4–5 show how to call those components.

## Step 4: Call a state-changing method

Two CLI commands: build the unsigned activation, then sign and submit it.

Mint on the issuer; `dest` is the holder's 4-part `component_id`, and `amount` is a single-element tuple:

```bash theme={null}
UNSIGNED=$(gen client --json build-activation \
  --component-id "$ISSUER_ID" \
  --method mint \
  --params "{\"dest\":\"$HOLDER_ID\",\"amount\":[1000]}" \
  | jq -r .result.unsigned_activation_hex)

gen client --json sign-and-submit-activation \
  --unsigned-activation "$UNSIGNED"
```

The result's `outcome_result` is the method's return value, Borsh-encoded as hex.

## Step 5: Call a view method

```bash theme={null}
gen client --json view \
  --component-id "$HOLDER_ID" \
  --method balance
```

The result's `decoded` field shows the return value as a string.

## Composing with another contract

Some contracts' `#[deploy]` takes a `GvmContract` argument pointing at a contract you've already deployed. The CLI rejects bech32m strings or hex bytes for this parameter; it accepts only one specific nested-tuple JSON shape.

In [from-token-to-amm](https://github.com/gen-bc/demos/tree/main/from-token-to-amm), the **exchange** contract composes with two **simple-token** instances — one `GvmContract` parameter per token (`token_a_contract`, `token_b_contract`). Token A is already deployed from Steps 1–5 above.

### The JSON shape

```json theme={null}
{
  "token_a_contract": {
    "deployer":        [[[[ <32-byte entity_id as u8 int array> ]]]],
    "component_index": [ <component_index as u32> ]
  },
  "token_b_contract": {
    "deployer":        [[[[ <32-byte entity_id as u8 int array> ]]]],
    "component_index": [ <component_index as u32> ]
  }
}
```

Each field name matches a `GvmContract` parameter on `#[deploy]`. Wrap the 32-byte entity id in **four** JSON arrays (one per newtype layer: `EntityId` → `H256` → `[u8; 32]` → the bytes). Use plain `u8` integers, not a hex string. Wrap the `u32` component index in **one** array.

### Deriving the values from a bech32m address

Decode the `contract` address from `gen client deploy` to get the entity bytes and `component_index`. Until `gen client decode` ships, use this Python snippet:

```python theme={null}
def decode_gen_address(addr: str) -> tuple[list[int], int]:
    CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
    pos = addr.rfind("1")
    data = [CHARSET.index(c) for c in addr[pos + 1:]][:-6]  # strip checksum
    acc = bits = 0
    out: list[int] = []
    for v in data:
        acc = (acc << 5) | v
        bits += 5
        while bits >= 8:
            bits -= 8
            out.append((acc >> bits) & 0xff)
    entity = out[:32]
    component_index = int.from_bytes(bytes(out[32:36]), "little")
    return entity, component_index
```

### Deploy Token B and the exchange

Build the exchange manifest, deploy a second token from the same `contract_code_id`, then push and deploy the exchange. Decode both token `contract` addresses with the Python snippet above before the final deploy:

```bash theme={null}
gen genie build solutions/03-exchange

gen client --json deploy \
  --contract-code-id <contract_code_id> \
  --account $ACCOUNT \
  --deploy-params '{"name":"Token B","symbol":"TKB"}'
# → save the Token B contract address

gen client --json push \
  --file solutions/03-exchange/artifacts/exchange_modules.json \
  --account $ACCOUNT
# → save the exchange contract code id

gen client --json deploy \
  --contract-code-id <exchange_contract_code_id> \
  --account $ACCOUNT \
  --deploy-params '{"token_a_contract":{"deployer":[[[[ENTITY_A_BYTES]]]],"component_index":[COMPONENT_INDEX_A]},"token_b_contract":{"deployer":[[[[ENTITY_B_BYTES]]]],"component_index":[COMPONENT_INDEX_B]}}'
```

## Troubleshooting

* **`error: unexpected argument '--rpc-url'`.** Some `gen client` subcommands take `--rpc-url` after `client`, others take it after the subcommand. If unsure, set the URL once on your active environment (`gen config env set --rpc <url>`, or `gen config env new`/`switch`) and drop the flag.
* **`Invalid GvmComponentId format: expected 2 or 4 bech32m parts`.** `--component-id` needs the full 4-part comma-separated `root_component_id` from `deploy`, not the single `contract` address.
* **`Type mismatch for 'X': expected object, got string`.** `--deploy-params` is rejecting a typed SDK argument. See [Composing with another contract](#composing-with-another-contract) for the JSON shape.

## What's next

* [Genie SDK reference](/reference/contracts/genie-sdk): the full surface area of the SDK these contracts are built on.
* [from-token-to-amm](https://github.com/gen-bc/demos/tree/main/from-token-to-amm): the simple-token and exchange contracts used in this guide.
