Skip to main content
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; 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 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:

Prerequisites

  • The gen CLI configured against DevNet. See Configuring for DevNet.
  • A built contract manifest at <contract>/artifacts/<contract>_modules.json. See Build your first contract.
  • A funded DevNet wallet — your entity 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 Steps 3–4.
Stash the active account in an env var; every command below passes it as --account:

Step 1: Push the contract code

From demos/from-token-to-amm:
Output:
Save the contract_code_id; you need it for deploy.

Step 2: Deploy an instance

If your contract’s #[deploy] takes parameters, pass them as JSON via --deploy-params. Simple-token for example requires name and symbol:
For deploy parameters that take a GvmContract argument (composing with another deployed contract), see 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:
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:
The result’s outcome_result is the method’s return value, Borsh-encoded as hex.

Step 5: Call a view method

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, 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

Each field name matches a GvmContract parameter on #[deploy]. Wrap the 32-byte entity id in four JSON arrays (one per newtype layer: EntityIdH256[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:

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:

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 for the JSON shape.

What’s next