Cannon
⚠️ CRITICAL: Read This First
Some Cannon commands are IRREVERSIBLE and handle real value. Be careful with:
- -
cannon build (without --dry-run) — deploys contracts on real networks - INLINECODE2 — publishes to on-chain registry (permanent)
- INLINECODE3 — registers package names on-chain
- INLINECODE4 — manages package publisher permissions
Safe commands: cannon build --dry-run, cannon inspect, cannon run, cannon test, cannon decode, cannon trace, INLINECODE11
Rules:
- 1. Always use
--dry-run first — Simulate before executing on real networks - Make every operation clear to the user — Explain what will happen before running
- Confirm before deploying — Never use a real private key without explicit approval
- Test locally first — Use chain 13370 (Cannon Network) before target chains
- Protect private keys — Use
CANNON_PRIVATE_KEY env var or --impersonate (recommended)
Model Recommendation
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.
Schema Reference
For complete cannonfile syntax validation and autocomplete, refer to the official JSON schemas:
- - Full schema: https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema.json
- Fragment schema: https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema-fragment.json
For editor validation, add the schema reference at the top of your cannonfile.toml:
CODEBLOCK0
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.
Prerequisites
Before using this skill, ensure these tools are installed:
- - Node.js 18+ and pnpm - INLINECODE16
- Foundry (forge, anvil, cast) - INLINECODE17
- Cannon CLI - INLINECODE18
Verify installation:
CODEBLOCK1
Quick Reference
For complete CLI options, see references/cli.md.
CLI Commands
CODEBLOCK2
Package Reference Format
<package-name>:<version>@<preset>
Examples:
- - INLINECODE19
- INLINECODE20
- INLINECODE21
Cannonfile Syntax
Package Metadata & Includes
CODEBLOCK4
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]).
Variables
CODEBLOCK5
Deploy Contract
CODEBLOCK6
Invoke Function
CODEBLOCK7
Import/Clone Package
CODEBLOCK8
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 Data from Package
CODEBLOCK9
Access: INLINECODE28
Template Strings
Use ERB-style templates to reference values:
- -
<%= settings.varName %> — settings - INLINECODE30 — deployed contract address
- INLINECODE31 — contract ABI
- INLINECODE32 — imported contract
Actions
| Action | Description |
|---|
| INLINECODE33 | Deploy a contract |
| INLINECODE34 |
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 |
Local Development
⚠️ Always use chain 13370 (Cannon Network) for local testing before deploying to target chains.
Default chain ID: 13370 (Cannon Network)
CODEBLOCK10
On-Chain Deployment
⚠️ Always use --dry-run first to verify deployments before executing on real networks.
CODEBLOCK11
Testing
CODEBLOCK12
Use cannon-std in Forge tests:
CODEBLOCK13
Storage Locations
| Directory | Contents |
|---|
| INLINECODE43 | Package reference files |
| INLINECODE44 |
Cached IPFS artifacts |
|
~/.local/share/cannon/build_results/ | Build outputs |
|
~/.local/share/cannon/blobs/ | Large binary blobs |
Common Patterns
Router Pattern (Bypass Contract Size Limits)
Create a router contract that efficiently passes calls to downstream contracts. Powerful when combined with a UUPS proxy.
CODEBLOCK14
Diamond Pattern (EIP-2535)
CODEBLOCK15
Linked Libraries
CODEBLOCK16
Debugging Tools
Cannon provides commands to decode bytecode, trace transactions, and interact with deployed contracts.
Decode
Decode hex data (function calls, events, errors) using package ABIs:
CODEBLOCK17
Trace
Get human-readable stack traces for transactions:
CODEBLOCK18
Interact
Send transactions to deployed contracts through the CLI:
CODEBLOCK19
Package State Manipulation (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.
Subcommands
| Command | Description |
|---|
| INLINECODE50 | Import existing artifacts into a deployment step (for migrations) |
| INLINECODE51 |
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 |
Example: Import existing deployment
CODEBLOCK20
GitOps Workflows
Cannon supports GitOps-style deployments through the website interface.
Queue with GitOps
Deploy packages directly from GitHub repositories or IPFS hashes via the Cannon website:
- - Preview transactions before execution
- View Git Diff of changes
- Execute through Safe multisig wallets
- Publish to registry after deployment
See: https://usecannon.com/deploy
Deployments Repository
Create a dedicated Git repository for deployment configurations (separate from source code):
- - Keep smart contract source private while maintaining transparent deployments
- Enable team collaboration on deployments
- Maintain clear audit trail
Migration from Other Tools
Migrating from hardhat-deploy, Foundry scripts, or other deployment frameworks:
- 1. Recreate deployment as cannonfile.toml (manual but usually quick)
- Build locally to create template:
cannon build (save the IPFS hash) - For each network, import existing deployments:
# Set the package URL to local template
cannon alter my-package --chain-id 1 set-url <ipfs-hash>
# Import each deployed contract/transaction
cannon alter my-package --chain-id 1 import deploy MyContract 0x...txhash
- 4. Verify by running build (no steps should execute): INLINECODE59
Advanced Topics
For detailed information on:
Troubleshooting
| Issue | Solution |
|---|
| "deployment not found" | Package not published for this chain ID. Check INLINECODE60 |
| 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 |
Development Workflow
- 1. Develop contracts with Foundry
- Write cannonfile.toml to define deployment
- Build locally with
cannon build (chain 13370) - Test with INLINECODE65
- Simulate with
--dry-run for target chain ⚠️ ALWAYS DO THIS FIRST - Deploy with
cannon build --chain-id <id> ⚠️ IRREVERSIBLE on non-local networks (safe on chain 13370) - Verify contracts on Etherscan with INLINECODE68
- Publish with
cannon publish ⚠️ PERMANENT ON-CHAIN
Key Files
| File | Purpose |
|---|
| INLINECODE70 | Package definition |
| INLINECODE71 |
Locked dependencies |
|
.cannon/ | Build cache (gitignored) |
|
deployments/ | Deployment artifacts |
Cannon
⚠️ 关键提示:请先阅读此部分
部分 Cannon 命令不可逆,且涉及真实资产操作。 请谨慎使用以下命令:
- - cannon build(不带 --dry-run 参数)—— 在真实网络上部署合约
- cannon publish —— 发布到链上注册表(永久性操作)
- cannon register —— 在链上注册包名
- cannon publishers —— 管理包发布者权限
安全命令:cannon build --dry-run、cannon inspect、cannon run、cannon test、cannon decode、cannon trace、cannon clean
规则:
- 1. 始终优先使用 --dry-run —— 在真实网络上执行前先进行模拟
- 确保每次操作对用户透明 —— 运行前说明将要执行的操作
- 部署前需确认 —— 未经明确授权绝不使用真实私钥
- 先在本地测试 —— 在目标链上操作前,先使用链 ID 13370(Cannon 网络)
- 保护私钥安全 —— 使用 CANNONPRIVATEKEY 环境变量或 --impersonate(推荐)
模型推荐
为 Cannon 任务使用最先进的模型。 部署脚本涉及真实资产操作——不要为了节省成本而降低模型质量。优先选择 Claude、GPT-4 或同等高性能模型,而非廉价替代方案。
Schema 参考
如需完整的 cannonfile 语法验证和自动补全功能,请参考官方 JSON schemas:
- - 完整 schema: https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema.json
- 片段 schema: https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema-fragment.json
如需编辑器验证,请在 cannonfile.toml 文件顶部添加 schema 引用:
toml
#:schema https://raw.githubusercontent.com/usecannon/cannon/refs/heads/dev/packages/lsp/src/schema.json
name = my-package
version = 1.0.0
...
这可以在支持 TOML LSP 的编辑器(如 taplo)中启用自动补全和验证功能。
Cannon 是以太坊智能合约的包管理和部署系统。它使用声明式 cannonfile 来定义部署工作流,同时支持本地开发和链上部署。
前置条件
使用此技能前,请确保已安装以下工具:
- - Node.js 18+ 和 pnpm —— npm install -g pnpm
- Foundry(forge、anvil、cast)—— curl -L https://foundry.paradigm.xyz | bash && foundryup
- Cannon CLI —— pnpm add -g @usecannon/cli
验证安装:
bash
node --version && pnpm --version
forge --version && anvil --version
cannon --version
快速参考
完整的 CLI 选项请参见 references/cli.md。
CLI 命令
bash
cannon build # 本地构建包(启动 anvil,部署合约)
cannon run
# 运行已部署的包(简写:cannon )
cannon test # 使用部署上下文运行 forge 测试
cannon inspect # 查看包详情
cannon publish # 发布到链上注册表 + IPFS ⚠️ 不可逆操作
cannon clean # 删除缓存目录
cannon verify # 在 Etherscan/Sourcify 上验证合约
包引用格式
:@
示例:
- - greeter-foundry:2.24.0
- safe:1.4.1
- synthetix-omnibus:3.1.4@main
Cannonfile 语法
包元数据与包含文件
toml
name = my-package
version = 1.0.0
description = 我的包描述
tags = [defi, token]
preset = main
包含包含操作的其他文件(适用于大型包)
include = [./deposits.toml, ./withdrawals.toml]
使用 include 将大型 cannonfile 拆分为多个文件。包含的文件使用片段 schema,可以包含任何操作(deploy、invoke、clone 等)。
现代语法使用 [var.label] 进行设置(已弃用:[setting.name])。
变量
toml
[var.chainId]
defaultValue = 1
[var.owner]
defaultValue = 0x...
部署合约
toml
[deploy.MyContract]
artifact = MyContract
args = [<%= settings.owner %>]
调用函数
toml
[invoke.initialize]
target = [<%= contracts.MyContract.address %>]
func = initialize
args = [<%= settings.owner %>]
导入/克隆包
toml
[clone.safe]
source = safe:1.4.1
target = safe
何时使用 clone 与 import:
- - clone —— 将其他包作为蓝图重新部署。务必正确设置 target(如果拥有该包则与 source 相同,否则使用新名称)。
- import —— 从已部署的包中拉取数据,无需重新部署。
从包中拉取数据
toml
[pull.usdc]
source = usdc:1.0.0@main
访问方式:<%= imports.usdc.contracts.USDC.address %>
模板字符串
使用 ERB 风格的模板引用值:
- - <%= settings.varName %> —— 设置
- <%= contracts.ContractName.address %> —— 已部署合约地址
- <%= contracts.ContractName.abi %> —— 合约 ABI
- <%= imports.pkg.contracts.Contract.address %> —— 导入的合约
操作
调用合约函数 |
| clone | 将其他包作为蓝图部署 |
| import | 从已部署的包中拉取数据 |
| pull | (已弃用)import 的别名 |
| var | 定义计算变量 |
| router | 创建路由器合约以绕过大小限制(与 UUPS 代理配合使用效果良好) |
| diamond | 创建包含切面的 EIP-2535 Diamond |
本地开发
⚠️ 在部署到目标链之前,始终使用链 ID 13370(Cannon 网络)进行本地测试。
默认链 ID:13370(Cannon 网络)
bash
使用本地 anvil 构建
cannon build
为特定链构建
cannon build --chain-id 1 --rpc-url $RPC_URL
试运行(仅模拟)
cannon build --dry-run --impersonate-all
本地运行包
cannon run greeter-foundry:2.24.0
链上部署
⚠️ 在真实网络上执行之前,始终先使用 --dry-run 验证部署。
bash
部署到主网
cannon build --chain-id 1 --rpc-url $RPC_URL --private-key $KEY
发布到注册表
cannon publish --chain-id 1 --rpc-url $RPC_URL --private-key $KEY
实际部署前进行模拟
cannon build --chain-id 1 --rpc-url $RPC_URL --dry-run
测试
bash
使用 forge 运行测试
cannon test
测试特定合约
cannon test --match-path test/MyContract.t.sol
在 Forge 测试中使用 cannon-std:
solidity
import {Cannon} from cannon-std/Test.sol;
contract MyTest is Cannon {
function setUp() public {
// 加载已部署的合约
address myContract = getAddress(MyContract);
}
}
存储位置
| 目录 | 内容 |
|---|
| ~/.local/share/cannon/tags/ | 包引用文件 |
| ~/.local/share/cannon/ipfs_cache/ |
缓存的 IPFS 工件 |
| ~/.local/share/cannon/build_results/ | 构建输出 |
| ~/.local/share/cannon/blobs/ | 大型二进制数据块 |
常见模式
路由器模式(绕过合约大小限制)
创建路由器合约,高效