Create Program Instance
Deploy a program instance from validated code and understand Mirror contracts.
Create Program Instance
Once your code is validated, you can create one or more program instances from it. Each instance gets its own Mirror contract on Ethereum, its own state, and its own Executable Balance.
Creation Methods
CLI
Without ABI:
ethexe tx create "$CODE_ID" \
--ethereum-rpc "$RPC" \
--ethereum-router "$ROUTER" \
--sender "$SENDER"With ABI:
# First deploy ABI interface contract, then:
ethexe tx create-with-abi "$CODE_ID" "$ABI_INTERFACE_ADDRESS" \
--salt 0x0000000000000000000000000000000000000000000000000000000000000000 \
--initializer "$SENDER" \
--ethereum-rpc "$RPC" \
--ethereum-router "$ROUTER" \
--sender "$SENDER"TypeScript SDK
Without ABI:
import { EthereumClient } from '@vara-eth/api';
const client = new EthereumClient(publicClient, ROUTER_ADDRESS, signer);
await client.waitForInitialization();
const tx = await client.router.createProgram(codeId);
await tx.sendAndWaitForReceipt();With ABI:
const tx = await client.router.createProgramWithAbiInterface(
codeId,
abiInterfaceAddress, // Deployed ABI interface contract address
);
await tx.sendAndWaitForReceipt();Why Deploy With ABI?
Deploying with ABI attaches a Solidity interface to your Mirror contract:
Without ABI:
Only base Mirror methods visible — sendMessage, sendReply, executableBalanceTopUp, claimValue
With ABI:
Your custom methods appear on Etherscan under "Write as Proxy" / "Read as Proxy" with decoded parameter names and types
Benefits:
- Etherscan shows your custom methods
- MetaMask can call methods directly
- Hardhat/Foundry can interact as a standard contract
- Other Solidity contracts can call your program with typed interfaces
Generating ABI from IDL
If your program is built with Sails, generate a Solidity interface from the IDL:
cargo sails sol --idl-path ./target/wasm32-gear/release/my_program.idlThis produces MyProgram.sol with:
- Solidity interface matching your Sails services
- ABI contract definition
- Callback definitions for handling replies
Deploy the ABI contract to Ethereum (via Foundry, Hardhat, or any tool), then use its address when creating your program.
Salt & Deterministic Addressing
The program's address is computed deterministically:
Mirror Address = CREATE2(Router, keccak256(codeId, salt))
ActorId = keccak256(codeId, salt)This means:
- Same code + same salt = same address (across deployments)
- Different salt = different address (multiple instances of same code)
- You can predict the address before deploying
What Gets Deployed
When you call createProgram, the Router:
- Verifies the
codeIdis inValidatedstate - Computes the deterministic address from
(codeId, salt) - Deploys a
MirrorProxycontract at that address (EIP-1167 minimal proxy) - Calls
Mirror.initialize(...)on the new proxy - Emits
ProgramCreated(actorId, codeId)event
After Creation
The program exists on Ethereum but is not yet initialized. You need to:
- Fund it — Top up the Executable Balance with wVARA
- Initialize it — Send the first message (constructor call)
createProgram → Fund (wVARA) → Initialize (first message) → ActiveExample initialization command:
ethexe tx send-message "$PROGRAM_ID" "0x..." 0 \
--ethereum-rpc "$RPC" \
--ethereum-router "$ROUTER" \
--sender "$SENDER"→ Funding Executable Balance | Initialization
Multiple Instances
You can deploy many instances from the same CODE_ID using different salts. Each instance has independent state, balance, and lifecycle.
Use cases:
- Multi-tenant applications (one instance per user/organization)
- Testing different configurations of the same program
- Deploying sharded versions for horizontal scaling