<contract>/artifacts/<contract>_modules.json and a funded DevNet wallet from the Quickstart.
The full deployment lifecycle uses five gen client commands:
| 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
genCLI configured against DevNet. See Configuring for DevNet. - A funded wallet (use the Quickstart flow to mint one and faucet it).
- A built contract: a manifest at
<contract>/artifacts/<contract>_modules.json. See Build and test a contract for the build step.
Step 1: Push the contract code
contract_code_id; you need it for deploy.
Step 2: Deploy an instance
#[deploy] takes parameters, pass them as JSON via --deploy-params:
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.root_component_id: a 4-part, comma-separated string. This is the value you pass as--component-idto call methods. The singlecontractaddress is not enough for method calls; you need the 4-part form.
Step 3: Install components
If your contract defines non-root components (component_type_index ≥ 1), install each one explicitly:Step 4: Call a state-changing method
Two steps: build the unsigned activation, then sign and submit it.outcome_result is the method’s return value, Borsh-encoded as hex.
Step 5: Call a view method
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 (for example, the example-contracts walkthrough does this in Steps 4, 6, 10, and 11). The CLI rejects bech32m strings or hex bytes for this parameter; it accepts only one specific nested-tuple JSON shape.
The JSON shape
u8 integers, not a hex string), and a single-element tuple wraps the u32 push index.
Deriving the values from a bech32m address
gen client push and deploy return addresses in the form grd@1... that encode (32-byte entity_id, u32 push_index little-endian). Until gen client decode ships, you can extract them with this Python decoder:
Worked example
After deploying a fungible-token instance (Step 10 of the walkthrough composes with this):Troubleshooting
error: unexpected argument '--rpc-url'. Somegen clientsubcommands take--rpc-urlafterclient, others take it after the subcommand. If unsure, set the URL once withgen config set rpc-urland drop the flag.Invalid GvmComponentId format: expected 2 or 4 bech32m parts.--component-idneeds the full 4-part comma-separatedroot_component_idfromdeploy, not the singlecontractaddress.Type mismatch for 'X': expected object, got string.--deploy-paramsis rejecting a typed SDK argument. See Composing with another contract for the JSON shape.
What’s next
- Cross-contract composition walkthrough: 12 example contracts that exercise everything above and a few patterns this guide doesn’t cover.
- Genie SDK reference: the full surface area of the SDK these contracts are built on.
- Grid framework reference: the fungible-token primitive used in the worked example.

