Deploying Contracts
The xyz program deploy command uploads your contract to the chain and creates an instance in a single step.
Usage
xyz program deploy < wasm-fil e > --from < ke y > [options]
Basic Deployment
xyz program deploy artifacts/my_contract.wasm --from alice --label "My Contract"
⠋ Uploading contract...
⠙ Instantiating contract...
Contract Deployed Successfully!
Code ID: 1
Contract: xyz1abc123def456...
Label: My Contract
TxHash: ABC123DEF456...
Gas Used: 234567
Block: 12345
Options
Flag Description Default --fromSigning key Required --labelContract label Filename --msgInstantiate message (JSON or @file) {}--adminAdmin address Sender --no-adminNo admin (immutable) false --fundsInitial funds None --dry-runSimulate only false --gas-bufferGas multiplier 1.3
Examples
With Instantiate Message
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--label "Counter" \
--msg '{"count": 42}'
From Message File
# Create init.json
echo '{"count": 42, "owner": "xyz1..."}' > init.json
# Deploy with file
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--msg @init.json
With Initial Funds
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--label "Escrow" \
--funds 1000000uxyz
Immutable Contract (No Admin)
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--no-admin
Immutable contracts cannot be upgraded or migrated. Use this for production contracts that should never change.
Custom Admin
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--admin xyz1multisigaddress...
Dry Run
Simulate deployment without broadcasting:
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--dry-run
Output:
Dry run mode - transaction not broadcast
Store:
Estimated gas: 1,500,000
Estimated fee: 15,000 uxyz
Instantiate:
Estimated gas: 250,000
Estimated fee: 2,500 uxyz
Total:
Gas: 1,750,000
Fee: 17,500 uxyz
Contract Details:
Label: my_contract
Admin: xyz1youraddress...
Init msg: {}
Deployment Flow
xyz program deploy combines two operations:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Upload Wasm │────▶│ Get Code ID │────▶│ Instantiate │
│ (MsgStoreCode) │ │ (from events) │ │ (MsgInst...) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
Upload TX Code ID: 1 Contract Address
Step 1: Store Code
Uploads the Wasm bytecode to the chain:
Creates a unique Code ID
Bytecode stored in chain state
Same code can be instantiated multiple times
Step 2: Instantiate
Creates a contract instance:
New contract address generated
Initial state set via InstantiateMsg
Admin assigned (for migrations)
Separate Upload and Instantiate
For advanced use cases, separate the steps:
# 1. Store code only
xyzd tx wasm store artifacts/my_contract.wasm \
--from alice \
--gas auto \
--gas-adjustment 1.5 \
--chain-id xyz-testnet-1 \
-y
# 2. Get code ID
xyzd query wasm list-code --node tcp://localhost:26657
# 3. Instantiate
xyzd tx wasm instantiate 1 '{"count":42}' \
--from alice \
--label "Counter" \
--admin xyz1... \
--gas auto \
--gas-adjustment 1.5 \
--chain-id xyz-testnet-1 \
-y
Multiple Instances
Create multiple instances of the same code:
# First instance
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--label "Counter A" \
--msg '{"count": 0}'
# Second instance (reuses code if already uploaded)
xyz program deploy artifacts/my_contract.wasm \
--from alice \
--label "Counter B" \
--msg '{"count": 100}'
Error Handling
Common errors and solutions:
Error Cause Solution ”wasm validation failed” Invalid Wasm file Rebuild contract ”insufficient funds” Not enough uxyz Fund account ”duplicate label” Label already exists Use unique label ”instantiate error” Invalid init message Check message format
User-Friendly Errors
The CLI translates chain errors:
# Instead of raw error:
# "rpc error: code = InvalidArgument desc = ..."
# You see:
Error: contract validation failed - ensure the wasm file is a valid CosmWasm contract
Verify Deployment
After deployment:
# Check contract info
xyz program info xyz1contractaddress...
# Query contract state
xyz program query xyz1contractaddress... '{"get_count":{}}'
Troubleshooting
Contract validation failed
The Wasm file may be invalid: # Rebuild
xyz program build
# Check file
file artifacts/my_contract.wasm
Check balance: For localnet, use test accounts with pre-funded balances.
Invalid instantiate message
Check your JSON: # Validate JSON
echo '{"count": 42}' | jq .
Ensure it matches InstantiateMsg in your contract.
Node may be slow: # Check node status
curl http://localhost:26657/status | jq '.result.sync_info'