关于 lightning
lightning 是面向 EVM 链上机密 Solidity 合约开发的 Agent skill,供使用 Inco Lightning 的开发者参考。它涵盖加密数据类型、访问控制、费用、前端加解密与验证,并强调该方案基于 TEE 而非 FHE。
主要功能
- 01指导加密 Solidity 类型与操作
- 02说明访问控制和费用处理
- 03提供前端加密与解密流程
- 04涵盖证明验证和部署测试
- 05包含合约模板与示例
适用场景
- 01构建 EVM 机密智能合约
- 02将前端接入已部署的机密合约
- 03开发隐藏信息游戏
- 04部署前检查权限与费用处理
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ inco-fhevm/ skills --skill lightning安装后在 Claude Code 中输入/lightning确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
docs/troubleshooting.mdexamples/attestation-flow.tsbasic-encrypt-decrypt.tsconfidential-token-interaction.tssession-key-decrypt.tsreferences/deployment-testing.mdelist-reference.mdjs-sdk-reference.mdsolidity-reference.mdreferences/games/archetypes.mdchoosing-your-approach.mdfrontend.mdoverview.mdpatterns.mdsettlement-and-math.mdscripts/ConfidentialToken.solConfidentialWithAttestation.solincoHelper.tsscripts/games/hangman/IncoHangMan.solscripts/games/mines/Mines.solMinesFactory.solMinesMath.sol详细介绍
Inco EVM 开发
在 EVM 链上构建保密智能合约。Inco 使用基于 TEE 的保密计算,为 Solidity 添加加密数据类型、操作和可编程访问控制,无需修改底层区块链。本技能介绍 Inco 在 EVM(Inco Lightning) 上的应用;此处不涉及 Inco 的 Solana/SVM 路线。
重要:Inco 不是 FHE(全同态加密)。它基于 TEE(可信执行环境)。绝不要向用户描述 Inco 使用 FHE。 面向开发者的 API 使用「加密」相关术语(euint256、ebool),但其底层加密机制是在 TEE 中进行加密/解密,而非同态加密。
关键:导致每个新项目出错的三条规则
- 存储加密句柄后,务必调用
allowThis(),否则合约将永久失去访问权限 - 每次调用
newEuint256/newEbool/newEaddress,或在任何消费bytes calldata密文的地方,都务必通过msg.value >= inco.getFee()支付费用 - 绝不要对加密条件使用
if/else——改用condition.select(ifTrue, ifFalse)
危险信号——如果发现自己这样想,请立即停下:
| 想法 | 实际情况 |
|---|---|
“我会在清理阶段补上 allowThis()” | 交易上链后,访问权限就会永久丢失。每次存储加密数据后,都要在下一行添加它。 |
“这个加密条件很简单——用 if/else 没问题” | ebool 是句柄,不是布尔值。基于它进行分支判断会导致代码出错。请使用 .select(),没有例外。 |
| “费用处理以后再说” | 每次导入密文以及调用 rand/shuffle,如果没有足额支付费用都会回滚。编写函数前,先决定由用户付费还是由合约代付。 |
| “这个合约很小,不用跑验证清单” | 小合约也会丢失句柄。每次部署前都要运行验证清单。 |
架构(30 秒概览)
Frontend (@inco/lightning-js) Smart Contract (@inco/lightning) Covalidator (TEE)
───────────────────────────── ─────────────────────────────── ──────────────────
zap.encrypt(value) ──────────> newEuint256(bytes, sender)
e.add / e.sub / e.select / ...
e.allow(handle, user)
zap.attestedDecrypt(handle) <──────────────────────────────────── decrypt + sign
submit attestation on-chain -> incoVerifier().isValidAttestation()
快速开始
1. 搭建项目
npx create-inco-app my-app --chain evm --framework hardhat --wallet rainbowkit --yes
2. 最精简的 Solidity 合约
import {euint256, ebool, e, inco} from "@inco/lightning/src/Lib.sol";
contract MyConfidentialContract {
using e for *;
mapping(address => euint256) public balanceOf;
function deposit(bytes memory encryptedAmount) external payable {
require(msg.value >= inco.getFee(), "Fee not paid");
euint256 amount = encryptedAmount.newEuint256(msg.sender);
euint256 newBal = balanceOf[msg.sender].add(amount);
balanceOf[msg.sender] = newBal;
newBal.allow(msg.sender); // User can decrypt
newBal.allowThis(); // CRITICAL: contract retains access
}
}
3. 前端加密与解密
import { Lightning } from "@inco/lightning-js/lite";
import { handleTypes } from "@inco/lightning-js";
const zap = await Lightning.baseSepoliaTestnet(); // Base Sepolia (chain 84532)
// Encrypt
const ct = await zap.encrypt(100n, {
accountAddress: userAddress,
dappAddress: contractAddress,
handleType: handleTypes.euint256,
});
// Send to contract (with fee as msg.value)
writeContract({ address: contractAddr, abi, functionName: "deposit", args: [ct], value: fee });
// Decrypt (retry if covalidator hasn't processed yet)
const results = await zap.attestedDecrypt(walletClient, [handle]);
const plaintext = results[0].plaintext.value;
选择适合你的路径
create-inco-app 的 --template 对应使用此技能的三种方式——只加载你需要的部分:
- 完整 dApp(
--template monorepo,默认)——先参考上面的快速开始,再按需查阅参考资料。 - 仅合约(
--template contracts)——加密类型、allow/allowThis、费用处理和.select(绝不对加密条件使用if/else);使用 IncoTest 在 Foundry/Hardhat 中编写合约并进行单元测试。→ solidity-reference.md、deployment-testing.md、scripts/ConfidentialToken.sol。 - 仅前端(
--template frontend,用于集成已部署的保密合约)——针对你可能并不拥有的合约进行加密/解密。→ js-sdk-reference.md(集成现有合约)、examples/basic-encrypt-decrypt.ts、scripts/incoHelper.ts。
正在构建保密游戏?
正在设计隐藏信息游戏(赌场/可证明公平、纸牌、棋盘、密封拍卖、社交推理、战争迷雾、单词/代码猜谜)?本页的基础 API 仍然适用,但请从 references/games/overview.md 开始:其中包含决策树(哪些内容是秘密、何时揭晓)、游戏类型目录、跨类型通用操作、两种结算模型和前端循环。仅加载任务需要的游戏参考资料。
正在构建牌组型游戏(手牌、隐藏身份或随机抽牌)? ConfidentialDeck 模板是最快的起步方式:它基于一个基础合约实现了四款完整示例游戏(War、Blackjack、Raffle、Mafia),包含一份为 AI 提供项目简介的 AGENTS.md,以及一个在线演示。它仅适用于这种牌组类型;请参阅游戏冲刺:快速构建牌组型游戏,了解其涵盖范围以及其他情况下的后续方向。
**先设计,再编码(严格要求):**在回答决策树问题之前,切勿编写任何 Solidity 代码——哪些内容是秘密、对谁保密,以及何时揭晓。在回答这些问题之前编写代码,会导致隐私边界设计错误,之后不得不重写。“游戏很简单,我边做边设计”就是危险信号——即使是简单游戏,也可能通过事件日志、公开状态和揭晓时机泄露信息。
核心概念
加密类型
euint256、ebool、eaddress —— 都是指向链下加密数据的 bytes32 句柄。
操作
使用 using e for *; 时,有两种等效的调用方式:
// Style 1: variable.operation(other) - method syntax on the encrypted variable
euint256 sum = a.add(b);
ebool isGreater = a.ge(b);
euint256 result = condition.select(ifTrue, ifFalse);
// Style 2: e.operation(a, b) - static call via the `e` library
euint256 sum = e.add(a, b);
ebool isGreater = e.ge(a, b);
euint256 result = e.select(condition, ifTrue, ifFalse);
两者完全相同。根据上下文,选用更易读的方式即可。
仅限静态调用的操作(没有可调用该操作的变量):
e.rand() // Random euint256
e.randBounded(n) // Random euint256 in [0, n)
e.asEuint256(42) // Plaintext -> encrypted handle
e.asEbool(true) // Plaintext -> encrypted handle
e.asEaddress(addr) // Plaintext -> encrypted handle
可用操作:
数学:add、sub、mul、div、rem、and、or、xor、shr、shl
比较:eq、ne、ge、gt、le、lt、min、max、not
控制:select(ifTrue, ifFalse)(第一个参数是条件为 true 时的值)——切勿对加密条件使用 if/else
关键:访问控制
newValue.allow(userAddress); // User can decrypt
newValue.allowThis(); // Contract can use in future txs
忘记调用 allowThis() = 合约将永久失去对该句柄的访问权限。
费用支付
每次调用 newEuint256/newEbool/newEaddress(以及 rand/randBounded/shuffle)都会收取 inco.getFee(),费用从合约余额中扣除。可以由用户支付(payable + require(msg.value >= inco.getFee())),也可以预先为合约充值以代付费用(调用者无需支付 Gas)。请参阅费用支付。
证明验证
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), "Invalid");
require(euint256.unwrap(myHandle) == decryption.handle, "Handle mismatch"); // ALWAYS check
关键:验证清单
部署任何 Inco 合约之前,请确认:
- 每次加密状态更新都调用
.allowThis() - 每个面向用户的值都调用
.allow(userAddress) - 所有接收加密字节的函数都带有费用检查的
payable - 不对加密条件使用
if/else或require(请使用.select()) - 合约中已声明
using e for *; - 前端使用正确的
accountAddress和dappAddress进行加密 - 提交证明时会验证句柄是否与链上记录一致
详细参考资料
- Solidity API:所有类型、操作、访问控制和证明模式——请参阅 solidity-reference.md
- JS SDK:加密、解密、证明计算、会话密钥、wagmi hooks——请参阅 js-sdk-reference.md
- 部署与测试:Foundry/Hardhat 配置、Docker 本地节点、测试网部署、IncoTest 测试替身——请参阅 deployment-testing.md
- EList:加密动态列表(已在 v1 纳入核心
@inco/lightning)——请参阅 elist-reference.md - 保密游戏:游戏设计层——请从 references/games/overview.md 开始
即用型模板
- scripts/ConfidentialToken.sol - 完整的机密 ERC20,包含 mint、transfer、approve、transferFrom
- scripts/ConfidentialWithAttestation.sol - 全部 3 种证明模式(decrypt、reveal、compute)
- scripts/incoHelper.ts - 前端工具:加密、带重试的解密、获取费用、格式化证明
- scripts/games/mines/ - 机密扫雷(模型 A 下注)——加密棋盘洗牌、累积器锁定机制、链上证明结算、工厂合约资金池/负债。经过审计的参考实现(
Mines.sol+MinesMath.sol+MinesFactory.sol) - scripts/games/hangman/IncoHangMan.sol - 机密猜词游戏(模型 B 猜词)——打包单词、
e.eq匹配、按玩家单独解密、客户端结算。概念验证——请参阅文件头部的注意事项
可运行示例
- examples/basic-encrypt-decrypt.ts - 核心流程:初始化 SDK、加密、发送到合约、重试解密
- examples/confidential-token-interaction.ts - 使用加密代币执行 Mint、transfer、approve、transferFrom
- examples/attestation-flow.ts - 端到端演示全部 3 种证明模式(decrypt、reveal、compute)
- examples/session-key-decrypt.ts - 使用会话密钥实现无需弹窗的解密和委托
故障排除
常见问题和解决方法:docs/troubleshooting.md 涵盖:费用错误、缺少 allowThis、协处理器超时、句柄格式问题、Docker 问题、Foundry 测试陷阱。
常见模式
多路复用器(静默失败)
ebool canTransfer = balanceOf[sender].ge(amount);
euint256 transferred = canTransfer.select(amount, e.asEuint256(0));
// Transfers 0 instead of reverting - hides the failure reason
双函数(EOA + 合约)
// EOA: encrypted bytes input (requires fee)
function transfer(address to, bytes memory input) external payable { ... }
// Contract: existing handle (requires isAllowed check)
function transfer(address to, euint256 value) public { ... }
完整的加密-计算-解密流程
- 前端:
zap.encrypt(value)-> 密文数据 - 合约:
newEuint256(bytes, sender)-> 句柄,然后执行加密操作 - 合约:
e.allow(result, user)-> 授予解密权限 - 前端:
zap.attestedDecrypt(walletClient, [handle])-> 明文 + 签名 - (可选)前端:在链上提交证明以供验证
关键依赖项
| Package | Version | Purpose |
|---|---|---|
@inco/lightning | latest (v1+) | Solidity 库 — 安装 @latest |
@inco/lightning-js | latest (v1+) | JavaScript SDK(从 @inco/js 重命名而来)— 安装 @latest |
| Solidity | 0.8.30 | 编译器版本(支持 0.8.29+) |
| EVM | cancun | 目标 EVM 版本 |