关于 arcium
arcium 是面向 Solana 开发者的加密计算框架与文档技能,支持通过 MPC 在数据保持加密时执行计算。它涵盖 Arcis 电路、Anchor 程序和 TypeScript 客户端的开发流程,并提供版本迁移与故障排查指引。
主要功能
- 01在 Solana 上执行加密 MPC 计算
- 02使用 Arcis 编写固定形状的 Rust 电路
- 03通过 Anchor 程序编排计算与回调
- 04在 TypeScript 客户端处理加密和提交
- 05提供 CLI 构建、测试与部署流程
- 06指导版本迁移和常见故障排查
适用场景
- 01构建输入数据保持加密的 Solana 应用
- 02让多方基于组合数据计算而不披露输入
- 03实现密封竞价、投票或隐藏游戏状态
- 04排查计算未完成或解密结果错误
MCP 相关
提供 search_arcium_docs 用于查找文档,并通过 query_docs_filesystem_arcium_docs 读取完整页面;CLI 参数等当前信息可通过 MCP 查询。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arcium-hq/ agent-skills --skill arcium安装后在 Claude Code 中输入/arcium确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
mcp.jsonevals/evals.jsonexamples/minimal-circuit.mdpatterns.mdreferences/troubleshooting.md详细介绍
Arcium
通过 MPC 在 Solana 上进行加密计算。计算期间数据始终保持加密状态。你的机密应用由一个 Solana 程序、Arcis 电路(Rust 电路框架)和一个链上元数据账户组成,是一个 MXE(MPC 执行环境)。arcium CLI(封装了 Anchor)负责初始化、构建、测试和部署——使用 MCP 获取最新的标志和选项。
目标版本为 Arcium v0.11.x(Anchor 1.0.2、Solana 3.1.10——与 v0.10.x 保持不变)。要从 v0.10.x 升级?请参阅 v0.10 → v0.11 迁移指南——唯一影响应用的破坏性变更是
queue_computation新增了第 7 个参数callback_cu_limit: u32(传入0可使用默认值)。v0.11 还新增了 Arcis 枚举和Option<T>(属于增量功能;不能用作电路输入或输出)。如果你使用的是 v0.9.x?请先执行 v0.9 → v0.10 迁移(init_comp_def→init_computation_def、@coral-xyz/anchor→@anchor-lang/core、队列端账户使用Box<…>)。
MCP 工具:使用 search_arcium_docs 搜索(返回页面路径),然后使用 query_docs_filesystem_arcium_docs 和 cat <path>.mdx 读取完整页面(例如,cat /developers/arcis/mental-model.mdx)。
没有 MCP? 直接查阅文档:docs.arcium.com/llms.txt 提供页面索引;llms-full.txt 则包含全部文档。
适用场景
适用于:
- 需要无需信任的计算——通过密码学保证,没有任何单方能看到数据
- 多方基于合并后的数据进行计算,同时不泄露各自的输入
- 链上状态必须保持加密,同时仍可用于计算
- 隐私场景:密封投标拍卖、投票、隐藏游戏状态、暗池、机密 DeFi
限制:
- 必须使用固定的循环边界(不支持可变长度迭代)
心智模型
Arcium 应用包含三个相互关联的部分。大多数 Bug 都是它们之间的边界不匹配所致:
| 部分 | 职责 | 常见边界 Bug |
|---|---|---|
| 电路(Arcis/Rust) | 纯粹的固定形状 MPC 逻辑 | 可变循环、动态集合、在条件语句中调用 .reveal() |
| 程序(Anchor/Rust) | 编排:初始化 + 排队 + 回调 | 宏名称不匹配、回调账户不可写、ArgBuilder 顺序错误 |
| 客户端(TypeScript) | 密钥交换、加密、提交、解密 | 重复使用 nonce、Shared 缺少 .x25519_pubkey()、参数顺序与电路顺序不一致 |
MPC 限制(源于秘密共享的工作方式):
- 除非条件是编译时常量,否则
if/else的两个分支都会执行——成本是两个分支之和,而非最大值。同样的规则也适用于非常量match分支和if let——所有可达分支都会执行。 - 循环必须有固定边界——不支持
while、break、continue - 比较操作开销较高;算术操作(加法/乘法)几乎没有开销
- 不能在条件语句中调用
.reveal()和.from_arcis()(编译时常量条件除外;也禁止在非常量match分支和守卫中调用) - 所有数据都必须是固定大小——不支持
Vec、String、HashMap;请使用[T; N] - v0.10+ 支持模式匹配(
match、if let、matches!)。最后一个match分支不能带守卫。Let 链要求在encrypted-ixs/Cargo.toml中设置edition = "2024"。 - v0.11+ 支持枚举和
Option<T>(完整支持Option组合器,包括.unwrap_or、.map、.and_then等)。有两项限制:二者都不能作为电路输入或输出,且不能显式设置枚举判别值。
意图路由器
先确定你要构建什么,再阅读链接的参考资料,然后开始编码。有关 API 详情、CLI 标志、部署和版本,请直接使用 MCP。
| 意图 | 阅读 | MCP 查询 |
|---|---|---|
| 第一个 Arcium 应用 | minimal-circuit.md | "hello world tutorial" |
| 核心概念/术语(MXE、Arx、comp def) | core-concepts | "arcium core concepts" |
| 选择模式(无状态、有状态、多方) | patterns.md | "arcium examples" |
电路语法(#[encrypted]、#[instruction]) | patterns.md | "arcis encrypted instruction" |
| Shared 与 Mxe 加密 | 见下文的 加密上下文 | "Shared vs Mxe encryption" |
| ArgBuilder 排序/密文错误 | troubleshooting.md -- ArgBuilder Ordering Errors | "ArgBuilder encrypted plaintext" |
| 未触发回调/计算卡住 | troubleshooting.md -- Computation Never Finalizes | "arcium_callback queue_computation" |
| Nonce/解密错误 | troubleshooting.md -- Nonce Errors | "RescueCipher encrypt nonce" |
| 客户端加密(RescueCipher、x25519) | minimal-circuit.md -- 测试部分 | "RescueCipher encrypt nonce" |
| 阈值签名/安全随机数 | patterns.md | "MXESigningKey sign" 或 "ArcisRNG" |
| 重新加密/封存 | patterns.md | "arcium sealing re-encryption" |
| 部署(devnet/mainnet) | — | "arcium deploy cluster-offset" |
| CI/GitHub Actions | setup-arcium | "arcium github actions ci" |
| 版本/安装要求 | 安装文档 | "arcium installation anchor solana" |
升级到 v0.11.x(callback_cu_limit、枚举/Option) | 迁移指南 | "v0.11 migration" |
| 关闭 MXE/comp def 以收回租金 | — | "deactivate close computation definition" |
核心模式:三个函数
Solana 程序中的每项计算都需要三个函数:
| 函数 | 用途 | 调用时机 |
|---|---|---|
init_<name>_comp_def | 初始化计算定义——链上账户,用于存放电路编译后的字节码 | 每条指令调用一次 |
<name> | 构建参数并排队计算 | 每次请求 |
<name>_callback | 处理来自 Arx 节点(集群的 MPC 计算节点)的结果 | MPC 完成后 |
const COMP_DEF_OFFSET_FLIP: u32 = comp_def_offset("flip");
// 1. INIT (once per instruction type) — v0.10+ helper is `init_computation_def` (2 args)
pub fn init_flip_comp_def(ctx: Context<InitFlipCompDef>) -> Result<()> {
init_computation_def(ctx.accounts, None)
}
// 2. QUEUE (each computation)
pub fn flip(ctx: Context<Flip>, offset: u64, ...) -> Result<()> {
let args = ArgBuilder::new()...build();
queue_computation(ctx.accounts, offset, args,
vec![FlipCallback::callback_ix(offset, &ctx.accounts.mxe_account, &[])?],
1, 0, 0, // num_callback_txs, cu_price_micro, callback_cu_limit (v0.11: 7th arg, 0 = default)
)?;
Ok(())
}
// 3. CALLBACK (after MPC completes)
#[arcium_callback(encrypted_ix = "flip")]
pub fn flip_callback(ctx: Context<FlipCallback>,
output: SignedComputationOutputs<FlipOutput>) -> Result<()> {
let result = output.verify_output(...)?;
// Use result...
}
加密大小:RescueCipher 会将任意标量加密为 32 字节,与类型无关。
公式:ciphertext_size = 32 * number_of_scalar_values。完整大小表请参见 troubleshooting.md。
加密上下文
Enc<Owner, T> — Owner 是可以解密的一方。编写电路前先选定。
| 场景 | 使用 |
|---|---|
| 用户提交输入/结果封存后返回给同一用户 | Enc<Shared, T> |
| 用户不应访问的内部状态 | Enc<Mxe, T> |
| 在多次计算间持久化的状态(任何一方都可重新读取) | Enc<Mxe, T> |
| 向所有人公开结果 | .reveal() |
**所有者选错会静默失败:**持久化/多方状态必须使用 Mxe——Shared 会将揭示能力授予某个客户端的 x25519 密钥,从而将聚合状态泄露给该接收方。如果之后使用了不同的客户端密钥/nonce,解密结果将是乱码(MPC 无法在不造成信息泄露的情况下报告解密错误)。Shared 也只会封存给一个接收方;要公开结果,请使用 .reveal(),而非 Shared。(在 Shared 输入中省略 .x25519_pubkey() 属于相同的静默失败情况——参见注意事项。)
注意事项
开发期间请参考此部分,避免常见错误。
绝对不要:
- 绝对不要重复使用 nonce——每次调用
cipher.encrypt()都需要一个新的randomBytes(16) - 绝对不要在一次 ArgBuilder 调用中合并多个密文——每个加密标量都应单独调用
[u8; 32] - 对于
Enc<Shared, T>,绝对不要省略.x25519_pubkey()(会静默失败);Enc<Mxe, T>则不需要
严重问题(会静默失败)
- 队列侧 Arcium 账户使用 Box 包装(v0.10+):在
#[queue_computation_accounts]中,遵循生成的模板并使用 Box 包装较大的账户:Box<Account<'info, MXEAccount>>、Box<Account<'info, Cluster>>、Box<Account<'info, ComputationDefinitionAccount>>。未使用 Box 包装的队列账户可能超出 Anchor/Solana 的栈限制。回调侧(#[callback_accounts])可以不使用 Box 包装。 - 宏字符串匹配:所有宏字符串必须与
#[instruction] fn NAME完全匹配,适用于#[arcium_callback]、comp_def_offset()、#[init_computation_definition_accounts]、#[queue_computation_accounts]、#[callback_accounts] - ArgBuilder 调用顺序:调用顺序必须与电路参数从左到右的顺序一致。对于
Enc<Shared, T>:依次调用.x25519_pubkey()、.plaintext_u128(nonce),然后传入密文。对于Enc<Mxe, T>:依次调用.plaintext_u128(nonce),然后传入密文。对于 Shared,缺少.x25519_pubkey()会导致静默失败。 - 除以秘密零值:使用安全除数模式保护除数——MPC 中两个分支都会执行,因此除法始终会运行。请参阅 patterns.md — 安全除法。
- 合并密文数组:每个加密标量都需要单独调用
[u8; 32]ArgBuilder——不要为包含两个标量的类型传入[u8; 64]。请参阅 troubleshooting.md — 密文大小不匹配。
警告(结果错误)
- 重复使用 nonce:多个加密操作使用相同的 nonce 会导致输出乱码。每次加密都使用唯一的
randomBytes(16)。 - 回调账户可写性:通过
callback_ix(..., &[...])中的CallbackAccount { pubkey, is_writable: true }传入额外账户。同时在回调结构体中标记#[account(mut)]。回调期间无法创建或调整账户大小。 - 输出结构体命名:电路
fn add_together会生成AddTogetherOutput。单个返回值使用field_0(一个带有.ciphertexts和.nonce的SharedEncryptedStruct<1>或MXEEncryptedStruct<1>)。元组返回值会嵌套使用field_0、field_1等。
提示
- 优先使用算术而非比较(在 MPC 中成本更低)
- 使用较窄的类型时(
u64而非u128),比较和除法的成本更低;存储成本相同
调试排查顺序
计算失败或返回错误结果时,请从这里开始。
计算失败、返回错误结果或始终无法完成时,请按以下顺序检查:
- 名称完全匹配——
#[instruction] fn NAME必须与#[arcium_callback(encrypted_ix = "NAME")]、comp_def_offset("NAME")和所有账户宏中的名称一致 - 已初始化计算定义——任何计算开始前,必须调用一次
init_*_comp_def - ArgBuilder 参数顺序——调用顺序必须与电路函数参数从左到右的顺序一致
- Shared 参数包含公钥——依次调用
.x25519_pubkey()、.plaintext_u128(nonce),然后传入密文(缺少时会静默失败) - nonce 唯一——每次加密都使用新的
randomBytes(16),并将相同的 nonce 传给程序 - 回调已注册且可写——在
queue_computation调用中传入callback_ix(...);账户同时设置为CallbackAccount { pubkey, is_writable: true },并在回调结构体中标记#[account(mut)] - 环境正确——集群偏移量与网络匹配,MXE 公钥可用(使用退避策略重试),RPC 端点可靠
详细错误解决方案请参阅:troubleshooting.md
验证清单
部署前检查。部署或提交 PR 前请逐项检查。
电路:
-
arcium build编译时没有错误 - 不使用
break/continue/return/变长循环 - 所有宏中的
#[instruction]fn 名称一致
程序:
- 首次计算前调用
init_*_comp_def(每种指令类型调用一次) - 每个电路 fn 都有 init、invoke 和 callback 指令
-
#[arcium_callback(encrypted_ix = "...")]与电路 fn 名称完全一致 - 通过
CallbackAccount { pubkey, is_writable: true }传递额外的 callback 账户,并在 callback 结构体中使用#[account(mut)]
客户端:
- 每次加密使用唯一 nonce(调用之间不重复使用)
- ArgBuilder 调用顺序与电路 fn 参数从左到右的顺序一致
- 为每个
Enc<Shared, T>参数包含.x25519_pubkey() - 集群偏移量与部署环境一致
部署:
- 部署前在本地通过
arcium test - RPC 端点可靠(不是默认的 Solana RPC)
- CI 固定
setup-arcium,并明确指定 Arcium/Anchor/Solana 版本,以便可复现地安装工具链
资源
- MCP 工具(API 详情、CLI 标志、部署和版本的首选来源):
search_arcium_docs+query_docs_filesystem_arcium_docs— docs.arcium.com/mcp - 文档:docs.arcium.com/developers — 无 MCP 时的备用资源:llms.txt(索引)、llms-full.txt(完整文档)
- v0.10 → v0.11 迁移:迁移指南 —
queue_computation的第 7 个参数callback_cu_limit、Arcis 枚举和Option<T> - 账户生命周期 / 关闭:account-lifecycle —
deactivate-computation-definition→ TTL(180 个 slot)→close-computation-definition/close-mxe - 示例:github.com/arcium-hq/examples
- CI / GitHub Actions:github.com/arcium-hq/setup-arcium — 用于 CI 工具链安装的 GitHub Action;对于 v0.11.x,请明确设置 Arcium/Anchor/Solana 版本,而不要依赖默认值
- TypeScript SDK:
@arcium-hq/client+@arcium-hq/reader(订阅计算事件)— ts.arcium.com/api - 模式:patterns.md — 精选电路模式(无状态、有状态、多方、随机数、打包、阈值签名、封装)
- 故障排查:troubleshooting.md — 难以调试的错误
- 最小可运行应用:minimal-circuit.md — 电路 + 程序 + 测试