Some Cannon commands are IRREVERSIBLE and handle real value. Be careful with:
cannon build (without --dry-run) — deploys contracts on real networkscannon publish — publishes to on-chain registry (permanent)cannon register — registers package names on-chaincannon publishers — manages package publisher permissionsSafe commands: cannon build --dry-run, cannon inspect, cannon run, cannon test, cannon decode, cannon trace, cannon clean
Rules:
--dry-run first — Simulate before executing on real networksCANNON_PRIVATE_KEY env var or --impersonate (recommended)Use state-of-the-art models for Cannon tasks. Deployment scripts handle real value — don't skimp on model quality. Prefer Claude, GPT-4, or equivalent high-capability models over cheaper alternatives.
For complete cannonfile syntax validation and autocomplete, refer to the official JSON schemas:
For editor validation, add the schema reference at the top of your cannonfile.toml:
#:schema https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema.json
name = "my-package"
version = "1.0.0"
...
This enables autocomplete and validation in editors with TOML LSP support (like taplo).
Cannon is a package manager and deployment system for Ethereum smart contracts. It uses declarative cannonfiles to define deployment workflows and supports both local development and on-chain deployments.
Before using this skill, ensure these tools are installed:
npm install -g pnpmcurl -L https://foundry.paradigm.xyz | bash && foundryuppnpm add -g @usecannon/cliVerify installation:
node --version && pnpm --version
forge --version && anvil --version
cannon --version
For complete CLI options, see references/cli.md.
cannon build # Build package locally (starts anvil, deploys contracts)
cannon run <pkg:ver> # Run a deployed package (shorthand: cannon <pkg:ver>)
cannon test # Run forge tests with deployment context
cannon inspect <pkg:ver> # View package details
cannon publish # Publish to on-chain registry + IPFS ⚠️ IRREVERSIBLE
cannon clean # Delete cache directories
cannon verify # Verify contracts on Etherscan/Sourcify
<package-name>:<version>@<preset>
Examples:
greeter-foundry:2.24.0safe:1.4.1synthetix-omnibus:3.1.4@mainname = "my-package"
version = "1.0.0"
description = "My package description"
tags = ["defi", "token"]
preset = "main"
# Include additional files containing actions (for larger packages)
include = ["./deposits.toml", "./withdrawals.toml"]
Use include to split large cannonfiles into multiple files. Included files use the fragment schema and can contain any actions (deploy, invoke, clone, etc.).
Modern syntax uses [var.label] for settings (deprecated: [setting.name]).
[var.chainId]
defaultValue = 1
[var.owner]
defaultValue = "0x..."
[deploy.MyContract]
artifact = "MyContract"
args = ["<%= settings.owner %>"]
[invoke.initialize]
target = ["<%= contracts.MyContract.address %>"]
func = "initialize"
args = ["<%= settings.owner %>"]
[clone.safe]
source = "safe:1.4.1"
target = "safe"
When to use clone vs import:
clone — Use another package as a "blueprint" to deploy it anew. Always set target appropriately (same as source if you own it, or a new name if not).import — Pull in data from an already-deployed package without re-deploying.[pull.usdc]
source = "usdc:1.0.0@main"
Access: <%= imports.usdc.contracts.USDC.address %>
Use ERB-style templates to reference values:
<%= settings.varName %> — settings<%= contracts.ContractName.address %> — deployed contract address<%= contracts.ContractName.abi %> — contract ABI<%= imports.pkg.contracts.Contract.address %> — imported contract| Action | Description |
|---|---|
| -------- | ------------- |
deploy | Deploy a contract |
invoke | Call a contract function |
clone | Deploy another package as a blueprint |
import | Pull data from an already-deployed package |
pull | (deprecated) Alias for import |
var | Define computed variables |
router | Create a router contract to bypass size limits (pairs well with UUPS proxy) |
diamond | Create an EIP-2535 Diamond with facets |
⚠️ Always use chain 13370 (Cannon Network) for local testing before deploying to target chains.
Default chain ID: 13370 (Cannon Network)
# Build with local anvil
cannon build
# Build for specific chain
cannon build --chain-id 1 --rpc-url $RPC_URL
# Dry run (simulation only)
cannon build --dry-run --impersonate-all
# Run a package locally
cannon run greeter-foundry:2.24.0
⚠️ Always use --dry-run first to verify deployments before executing on real networks.
# Deploy to mainnet
cannon build --chain-id 1 --rpc-url $RPC_URL --private-key $KEY
# Publish to registry
cannon publish --chain-id 1 --rpc-url $RPC_URL --private-key $KEY
# For simulation before actual deploy
cannon build --chain-id 1 --rpc-url $RPC_URL --dry-run
# Run tests with forge
cannon test
# Test specific contract
cannon test --match-path "test/MyContract.t.sol"
Use cannon-std in Forge tests:
import {Cannon} from "cannon-std/Test.sol";
contract MyTest is Cannon {
function setUp() public {
// Load deployed contracts
address myContract = getAddress("MyContract");
}
}
| Directory | Contents |
|---|---|
| ----------- | ---------- |
~/.local/share/cannon/tags/ | Package reference files |
~/.local/share/cannon/ipfs_cache/ | Cached IPFS artifacts |
~/.local/share/cannon/build_results/ | Build outputs |
~/.local/share/cannon/blobs/ | Large binary blobs |
Create a router contract that efficiently passes calls to downstream contracts. Powerful when combined with a UUPS proxy.
[deploy.CoreImplementation]
artifact = "Core"
[deploy.AnotherImplementation]
artifact = "Another"
[router.CoreRouter]
dependencies = ["CoreImplementation", "AnotherImplementation"]
[deploy.Diamond]
artifact = "Diamond"
[deploy.FacetA]
artifact = "FacetA"
[deploy.FacetB]
artifact = "FacetB"
[diamond.Diamond]
facets = ["FacetA", "FacetB"]
[deploy.Library]
artifact = "Library"
[deploy.Contract]
artifact = "Contract"
libraries = { Library = "<%= contracts.Library.address %>" }
Cannon provides commands to decode bytecode, trace transactions, and interact with deployed contracts.
Decode hex data (function calls, events, errors) using package ABIs:
cannon decode synthetix-omnibus --chain-id 8453 --preset main 0x...
Get human-readable stack traces for transactions:
cannon trace <tx-hash> --chain-id 1 --rpc-url $RPC_URL
Send transactions to deployed contracts through the CLI:
cannon interact synthetix-omnibus --chain-id 8453 --contract CoreProxy
alter)The alter command modifies existing Cannon packages outside the regular build process. Use for troubleshooting, migrations, or fixing broken package state.
⚠️ Only use alter when no other option exists.
| Command | Description |
|---|---|
| --------- | ------------- |
import | Import existing artifacts into a deployment step (for migrations) |
set-contract-address | Change a contract's address in the deployment |
mark-complete | Mark a deployment step as complete |
mark-incomplete | Mark a deployment step as incomplete |
set-url | Update the deployment URL reference |
set-misc | Update miscellaneous data URL |
clean-unused | Remove unused deployment states |
migrate-212 | Migrate packages from version 2.12 format |
# Import a deployed contract by its creation transaction
cannon alter my-package:1.0.0 --chain-id 1 import deploy MyContract 0x...txhash
# Import an executed transaction
cannon alter my-package:1.0.0 --chain-id 1 import invoke initialize 0x...txhash
Cannon supports GitOps-style deployments through the website interface.
Deploy packages directly from GitHub repositories or IPFS hashes via the Cannon website:
See: https://usecannon.com/deploy
Create a dedicated Git repository for deployment configurations (separate from source code):
Migrating from hardhat-deploy, Foundry scripts, or other deployment frameworks:
cannon build (save the IPFS hash)```bash
# Set the package URL to local template
cannon alter my-package --chain-id 1 set-url
# Import each deployed contract/transaction
cannon alter my-package --chain-id 1 import deploy MyContract 0x...txhash
```
cannon build --chain-id 1For detailed information on:
| Issue | Solution |
|---|---|
| ------- | ---------- |
| "deployment not found" | Package not published for this chain ID. Check --chain-id |
| Build fails with "artifact not found" | Run forge build first, or check artifact path |
| IPFS timeout | Check network connection, may need IPFS gateway |
| Registry publish fails | Verify you have write permissions for the package name |
| Wrong chain deployed | Always double-check --chain-id — deployments cannot be undone |
| Published incorrect package | Registry publishes are permanent — verify version and artifacts first |
cannon build (chain 13370)cannon test--dry-run for target chain ⚠️ ALWAYS DO THIS FIRSTcannon build --chain-id ⚠️ IRREVERSIBLE on non-local networks (safe on chain 13370)cannon verifycannon publish ⚠️ PERMANENT ON-CHAIN| File | Purpose |
|---|---|
| ------ | --------- |
cannonfile.toml | Package definition |
cannonfile.lock | Locked dependencies |
.cannon/ | Build cache (gitignored) |
deployments/ | Deployment artifacts |
共 1 个版本