mcpField
L
lightning

lightning

github.com/inco-fhevm開発138 回インストール8 週間前に更新
リポジトリ

lightning について

lightningは、Inco Lightningを使ってEVMチェーン上の機密Solidityコントラクトを開発するためのエージェントスキルです。暗号化型、アクセス制御、手数料、フロントエンドでの暗号化・復号、検証を扱い、TEE方式とFHEを区別します。

主な機能

  1. 01暗号化Solidity型と操作のガイド
  2. 02アクセス制御と手数料処理
  3. 03フロントエンドの暗号化・復号フロー
  4. 04アテステーション検証とデプロイテスト
  5. 05コントラクトテンプレートと実行例

活用シーン

  1. 01EVM上で機密スマートコントラクトを構築
  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 に追加します。このスキルでは、EVM(Inco Lightning) 上の Inco を扱います。Inco の Solana/SVM 系統は対象外です。

重要:Inco は FHE(完全準同型暗号)ではありません。TEE(信頼実行環境)ベースです。ユーザーに Inco を FHE と説明しないでください。 開発者向け API では「暗号化」という用語(euint256、ebool)を使いますが、基盤となる暗号化方式は TEE での暗号化/復号であり、準同型暗号ではありません。

重大:新しいプロジェクトで必ず問題になる3つのルール

  1. 暗号化ハンドルを保存した後は、必ず allowThis() を呼び出してください。そうしないと、コントラクトはそのハンドルへのアクセスを永久に失います
  2. newEuint256/newEbool/newEaddress の呼び出しごと、または bytes calldata の暗号文を消費する箇所では、必ず msg.value >= inco.getFee() で手数料を支払ってください
  3. 暗号化された条件に if/else を使わないでください。代わりに condition.select(ifTrue, ifFalse) を使用してください
危険信号 — こう考えてしまったら作業を止めてください:
考え実際には
「仕上げの段階で allowThis() を追加しよう」トランザクションが確定すると、アクセスは永久に失われます。暗号化データを保存するたび、その次の行に追加してください。
「この暗号化された条件は単純だから、if/else で問題ない」ebool はハンドルであり、bool ではありません。それに基づく分岐は壊れたコードです。例外なく .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 は、このスキルの3つの利用方法に対応しています。必要な部分だけを読み込んでください。

機密性の高いゲームを構築しますか?

隠された情報を扱うゲーム(カジノ/プロバブリー・フェア、カード、ボード、封印入札、ソーシャル・ディダクション、フォグ・オブ・ウォー、単語/コード当て)を設計していますか?このページの基本 API は引き続き適用されますが、まず references/games/overview.md をご覧ください。意思決定ツリー(何が秘密で、いつ公開されるか)、アーキタイプのカタログ、複数のゲームに共通する手法、2 つの精算モデル、フロントエンドのループを掲載しています。タスクに必要なゲームのリファレンスだけを読み込んでください。

デッキ型のゲーム(カードの手札、隠された役割、ランダムなドロー)を構築しますか? ConfidentialDeck template が最も手早く始められます。1 つのベースコントラクト上に、実装例として完成した 4 つのゲーム(War、Blackjack、Raffle、Mafia)、AI に概要を伝える AGENTS.md、ライブデモが含まれています。対応するのはこのデッキ型のゲームだけです。対応範囲と、それ以外の場合の進め方については、ゲームジャム:デッキ型のゲームをすばやく構築するをご覧ください。

コーディング前に設計してください(必須): 意思決定ツリーに答えるまで、Solidity を絶対に書かないでください。何が秘密で、誰から隠され、いつ公開されるのかを決める必要があります。これらに答える前に書いたコードは、誤ったプライバシー境界を埋め込んでしまい、書き直すことになります。「ゲームは単純だから、作りながら設計すればいい」という考えは危険信号です。単純なゲームでも、イベントログ、公開状態、公開タイミングから情報が漏れることがあります。

コアコンセプト

暗号化型

euint256、ebool、eaddress は、すべてオフチェーンの暗号化データを指す bytes32 ハンドルです。

演算

using e for *; を使う場合、同じ処理を 2 通りの書き方で呼び出せます。

// 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)(第 1 引数は条件が 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()))、またはコントラクトに事前入金してスポンサーする場合は(呼び出し元はガスレスになります)。詳しくは手数料の支払いをご覧ください。

アテステーションの検証
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 フックについては、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 - ミント、転送、承認、transferFrom を備えた完全なコンフィデンシャル ERC20
  • scripts/ConfidentialWithAttestation.sol - 3 種類すべてのアテステーションパターン(復号、公開、計算)
  • scripts/incoHelper.ts - フロントエンドユーティリティ:暗号化、リトライ付き復号、手数料の取得、アテステーションのフォーマット
  • scripts/games/mines/ - コンフィデンシャル・マインズ(モデル A の賭け)— 暗号化された盤面のシャッフル、sticky accumulator、オンチェーンのアテステーションによる決済、ファクトリーの資金プール/負債。監査済みのリファレンス(Mines.sol + MinesMath.sol + MinesFactory.sol)
  • scripts/games/hangman/IncoHangMan.sol - コンフィデンシャル・ハングマン(モデル B の単語当て)— パックされた単語、e.eq による一致判定、プレイヤーごとのプライベートな復号、クライアント側の決済。POC — ヘッダーの注意事項を参照してください

実行可能なサンプル

トラブルシューティング

よくある問題と解決策:docs/troubleshooting.md 対象:手数料エラー、allowThis の不足、covalidator のタイムアウト、ハンドルのフォーマット、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. (任意)フロントエンド:検証のため、オンチェーンでアテステーションを送信

主な依存関係

パッケージバージョン用途
@inco/lightninglatest (v1+)Solidity ライブラリ — @latest をインストール
@inco/lightning-jslatest (v1+)JavaScript SDK(@inco/js から名称変更)— @latest をインストール
Solidity0.8.30コンパイラのバージョン(0.8.29+ をサポート)
EVMcancun対象 EVM バージョン

コメント