mcpField
C
cairo-deploy

cairo-deploy

github.com/keep-starknet-strange云与 DevOps8135 次安装3 周前更新
代码仓库

关于 cairo-deploy

Cairo Deploy 是使用 Starknet Foundry 的 sncast 在 Starknet 部署和操作 Cairo 智能合约的参考技能,面向合约开发与部署流程。内容涵盖账户和网络配置、类声明、部署、验证及合约调用。

主要功能

  1. 01使用 Scarb 构建合约
  2. 02设置部署账户和网络配置
  3. 03声明类并部署实例
  4. 04执行写入调用和读取查询
  5. 05运行批量调用及部署脚本
  6. 06验证已部署合约

适用场景

  1. 01将 Cairo 合约部署到 Sepolia 或主网
  2. 02配置账户和 RPC 端点
  3. 03调用已部署合约的读写函数
  4. 04验证合约源代码

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/keep-starknet-strange/starknet-agentic --skill cairo-deploy

安装后在 Claude Code 中输入/cairo-deploy确认已加载。

附带文件agents/openai.yaml

详细介绍

Cairo 部署

使用 sncast(Starknet Foundry)在 Starknet 上部署 Cairo 智能合约的参考指南。

适用场景

  • 将合约部署到 Starknet devnet、Sepolia 或主网
  • 声明合约类
  • 设置部署账户
  • 配置网络端点
  • 验证已部署的合约
  • 调用已部署的合约

不适用场景

  • 编写或重构合约逻辑(cairo-contract-authoring)。
  • 单元、集成或模糊测试(cairo-testing)。
  • Gas 或性能优化(cairo-optimization)。
  • 对现有代码进行安全审查(cairo-auditor)。

快速开始

  1. 使用 scarb build 构建,然后使用 sncast 声明并部署。
  2. 如果任务转为编写、测试或审计,请使用技能目录。

设置

安装 Starknet Foundry
# Install via asdf (recommended for version pinning)
asdf plugin add starknet-foundry
asdf install starknet-foundry 0.56.0
asdf global starknet-foundry 0.56.0

# Or install directly
curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh
snfoundryup
.tool-versions

固定版本以确保构建可复现:

scarb 2.15.1
starknet-foundry 0.56.0

注意: snforge 0.56.0 要求 Scarb >= 2.12.0。请查看 github.com/foundry-rs/starknet-foundry/releases 获取最新版本。

构建

# Build contracts (generates Sierra + CASM)
scarb build

输出位于 target/dev/:

  • myproject_MyContract.contract_class.json(Sierra)
  • myproject_MyContract.compiled_contract_class.json(CASM)

账户设置

创建新账户
# Generate account on Sepolia
sncast account create \
    --url https://starknet-sepolia.g.alchemy.com/v2/YOUR_KEY \
    --name my-deployer

# This outputs the account address — fund it with ETH/STRK before deploying

# Deploy the account contract
sncast account deploy \
    --url https://starknet-sepolia.g.alchemy.com/v2/YOUR_KEY \
    --name my-deployer
导入现有账户
sncast account import \
    --url https://starknet-sepolia.g.alchemy.com/v2/YOUR_KEY \
    --name my-deployer \
    --address 0x123... \
    --private-key 0xabc... \
    --type oz

账户类型:oz(OpenZeppelin)、argent、braavos

sncast.toml

配置默认值,避免重复指定标志:

[default]
url = "https://starknet-sepolia.g.alchemy.com/v2/YOUR_KEY"
account = "my-deployer"
accounts-file = "~/.starknet_accounts/starknet_open_zeppelin_accounts.json"
wait = true

[mainnet]
url = "https://starknet-mainnet.g.alchemy.com/v2/YOUR_KEY"
account = "mainnet-deployer"

使用配置文件:sncast --profile mainnet declare ...

声明(注册类)

部署前,先在链上声明合约类:

# Declare contract
sncast declare \
    --contract-name MyContract

# Output:
# class_hash: 0x1234...
# transaction_hash: 0xabcd...

如果该类已声明,sncast 会提示你——这很正常,请使用现有的类哈希。

部署(创建实例)

# Deploy with constructor args
sncast deploy \
    --class-hash 0x1234... \
    --constructor-calldata 0xOWNER_ADDRESS

# Multiple constructor args (space-separated)
sncast deploy \
    --class-hash 0x1234... \
    --constructor-calldata 0xOWNER 0xTOKEN_ADDRESS 1000
构造函数调用数据编码

参数以 felt252 值的形式传递:

  • ContractAddress — 以十六进制形式传递,例如 0x123...
  • u256 — 作为两个 felt 传递:low high(例如,1000 表示为 1000 0)
  • felt252 — 直接传递
  • bool — true 传递 1,false 传递 0
  • ByteArray(字符串)— 使用 sncast 的字符串编码,或直接传递原始值

调用(写入)

# Call a write function
sncast invoke \
    --contract-address 0xCONTRACT \
    --function "transfer" \
    --calldata 0xRECIPIENT 1000 0

调用(读取)

# Call a view function (free, no tx)
sncast call \
    --contract-address 0xCONTRACT \
    --function "get_balance" \
    --calldata 0xACCOUNT

以编程方式部署(starknet.js)

import { Account, CallData, Contract, RpcProvider } from "starknet";

const provider = new RpcProvider({ nodeUrl: process.env.STARKNET_RPC! });
const account = new Account(provider, process.env.ACCOUNT_ADDRESS!, process.env.PRIVATE_KEY!);

const declareTx = await account.declare({ contract: compiledSierra, casm: compiledCasm });
await provider.waitForTransaction(declareTx.transaction_hash);

const deployTx = await account.deploy({
  classHash: declareTx.class_hash,
  constructorCalldata: CallData.compile({ owner: process.env.OWNER! }),
});
await provider.waitForTransaction(deployTx.transaction_hash);

const contract = new Contract(abi, deployTx.contract_address[0], provider).connect(account);
await contract.invoke("set_fee", [10]);
const fee = await contract.call("get_fee", []);
console.log({ fee });

多重调用

在单笔交易中执行多个调用:

# Create a multicall file
cat > multicall.toml << 'EOF'
[[call]]
call_type = "deploy"
class_hash = "0x1234..."
inputs = ["0xOWNER"]

[[call]]
call_type = "invoke"
contract_address = "0xTOKEN"
function = "approve"
inputs = ["0xSPENDER", "1000", "0"]
EOF

sncast multicall run --path multicall.toml

部署脚本模式

对于复杂部署,请使用脚本:

#!/bin/bash
set -euo pipefail

RPC_URL="https://starknet-sepolia.g.alchemy.com/v2/YOUR_KEY"
ACCOUNT="my-deployer"

echo "Building..."
scarb build

echo "Declaring MyToken..."
TOKEN_CLASS=$(sncast --json declare --contract-name MyToken --url $RPC_URL --account $ACCOUNT | jq -r '.class_hash')
echo "Token class: $TOKEN_CLASS"

echo "Deploying MyToken..."
TOKEN_ADDR=$(sncast --json deploy --class-hash $TOKEN_CLASS --constructor-calldata 0xOWNER --url $RPC_URL --account $ACCOUNT | jq -r '.contract_address')
echo "Token deployed at: $TOKEN_ADDR"

echo "Declaring AMM..."
AMM_CLASS=$(sncast --json declare --contract-name AMM --url $RPC_URL --account $ACCOUNT | jq -r '.class_hash')

echo "Deploying AMM..."
AMM_ADDR=$(sncast --json deploy --class-hash $AMM_CLASS --constructor-calldata $TOKEN_ADDR --url $RPC_URL --account $ACCOUNT | jq -r '.contract_address')
echo "AMM deployed at: $AMM_ADDR"

echo "Done. Addresses:"
echo "  Token: $TOKEN_ADDR"
echo "  AMM:   $AMM_ADDR"

网络端点

网络RPC URL
Devnet(本地)http://localhost:5050
Sepolia(测试网)https://starknet-sepolia.g.alchemy.com/v2/KEY
Mainnethttps://starknet-mainnet.g.alchemy.com/v2/KEY

其他服务提供商:Infura、Blast、Nethermind(提供免费套餐)。

本地 Devnet
# Install and run starknet-devnet-rs
cargo install starknet-devnet
starknet-devnet --seed 42

# Devnet provides pre-funded accounts — use them for testing

合约验证

在 Voyager 或 Starkscan 上验证源代码:

# Verify on Voyager (manual: upload Sierra JSON via web UI)
# https://sepolia.voyager.online/contract/0xADDRESS#code

# Or use Walnut for programmatic verification
# https://app.walnut.dev

注意: sncast verify 支持 Walnut 和 Voyager 两种后端。请明确使用 --verifier walnut 或 --verifier voyager。

可升级合约

对于使用 OZ UpgradeableComponent 的合约:

# 1. Declare new class
sncast declare --contract-name MyContractV2

# 2. Call upgrade on existing contract
sncast invoke \
    --contract-address 0xEXISTING_CONTRACT \
    --function "upgrade" \
    --calldata 0xNEW_CLASS_HASH

常见错误

错误原因解决方法
Contract not found账户尚未部署运行 sncast account deploy
Insufficient max feeETH/STRK 不足以支付 Gas为部署账户充值
Class already declared相同的类哈希已存在部署时使用现有的类哈希
Entry point not found函数名称错误检查合约 ABI
Invalid calldata参数数量或类型错误检查构造函数签名,记住 u256 = 2 个 felts

评论

支持 Markdown