mcpField
L
lightning

lightning

github.com/inco-fhevm开发138 次安装8 周前更新
代码仓库

关于 lightning

lightning 是面向 EVM 链上机密 Solidity 合约开发的 Agent skill,供使用 Inco Lightning 的开发者参考。它涵盖加密数据类型、访问控制、费用、前端加解密与验证,并强调该方案基于 TEE 而非 FHE。

主要功能

  1. 01指导加密 Solidity 类型与操作
  2. 02说明访问控制和费用处理
  3. 03提供前端加密与解密流程
  4. 04涵盖证明验证和部署测试
  5. 05包含合约模板与示例

适用场景

  1. 01构建 EVM 机密智能合约
  2. 02将前端接入已部署的机密合约
  3. 03开发隐藏信息游戏
  4. 04部署前检查权限与费用处理

安装

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

$npx skills add https://github.com/inco-fhevm/skills --skill lightning

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

docs/
troubleshooting.md
examples/
attestation-flow.ts
basic-encrypt-decrypt.ts
confidential-token-interaction.ts
session-key-decrypt.ts
references/
deployment-testing.md
elist-reference.md
js-sdk-reference.md
solidity-reference.md
references/games/
archetypes.md
choosing-your-approach.md
frontend.md
overview.md
patterns.md
settlement-and-math.md
scripts/
ConfidentialToken.sol
ConfidentialWithAttestation.sol
incoHelper.ts
scripts/games/hangman/
IncoHangMan.sol
scripts/games/mines/
Mines.sol
MinesFactory.sol
MinesMath.sol

详细介绍

Inco EVM 开发

在 EVM 链上构建保密智能合约。Inco 使用基于 TEE 的保密计算,为 Solidity 添加加密数据类型、操作和可编程访问控制,无需修改底层区块链。本技能介绍 Inco 在 EVM(Inco Lightning) 上的应用;此处不涉及 Inco 的 Solana/SVM 路线。

重要:Inco 不是 FHE(全同态加密)。它基于 TEE(可信执行环境)。绝不要向用户描述 Inco 使用 FHE。 面向开发者的 API 使用「加密」相关术语(euint256、ebool),但其底层加密机制是在 TEE 中进行加密/解密,而非同态加密。

关键:导致每个新项目出错的三条规则

  1. 存储加密句柄后,务必调用 allowThis(),否则合约将永久失去访问权限
  2. 每次调用 newEuint256/newEbool/newEaddress,或在任何消费 bytes calldata 密文的地方,都务必通过 msg.value >= inco.getFee() 支付费用
  3. 绝不要对加密条件使用 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 对应使用此技能的三种方式——只加载你需要的部分:

正在构建保密游戏?

正在设计隐藏信息游戏(赌场/可证明公平、纸牌、棋盘、密封拍卖、社交推理、战争迷雾、单词/代码猜谜)?本页的基础 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 匹配、按玩家单独解密、客户端结算。概念验证——请参阅文件头部的注意事项

可运行示例

故障排除

常见问题和解决方法: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 { ... }
完整的加密-计算-解密流程
  1. 前端:zap.encrypt(value) -> 密文数据
  2. 合约:newEuint256(bytes, sender) -> 句柄,然后执行加密操作
  3. 合约:e.allow(result, user) -> 授予解密权限
  4. 前端:zap.attestedDecrypt(walletClient, [handle]) -> 明文 + 签名
  5. (可选)前端:在链上提交证明以供验证

关键依赖项

PackageVersionPurpose
@inco/lightninglatest (v1+)Solidity 库 — 安装 @latest
@inco/lightning-jslatest (v1+)JavaScript SDK(从 @inco/js 重命名而来)— 安装 @latest
Solidity0.8.30编译器版本(支持 0.8.29+)
EVMcancun目标 EVM 版本

评论

支持 Markdown