
Tempo Testnet 节点搭建完整教程
Kaito 新人如何撸空投,从注册到写作入门指南(嘴撸)
“生命的货币不是金钱,甚至也不是时间,而是注意力。” ——Kaito 白皮书开篇如此说道。创作者创造内容,用户贡献注意力,品牌付出广告费——价值却流向平台大户。 Kaito 创新性地把注意力变成资产,通过 AI 驱动的 Yap 机制,赋能内容创作生态。如果你还没参与,现在也不晚!一、什么是 Kaito Yaps?Kaito Yaps 是 Kaito 的 AI 驱动算法系统,用来衡量内容贡献价值:不只是点赞转发,而是分析高质量推文、Smart Followers、互动深度等多维评分;越多高质量互动,Yap 分越高,排行榜排名越靠前。多数项目空投目标都面向前 100–200 名 Yapper。二、InfoFi 网络 + Launchpad 背后的生态逻辑Kaito Connect(InfoFi 网络):品牌可直接将空投奖励发放给表现优秀的 Yapper,无需中介参与,公平透明;Launchpad 启动板:基于 Yaps 排行机制,项目可以筛选高质量内容贡献者提前参与测试、营销或领取 Token 空投。三、Kaito 第一季空投结果回顾Yap 与 NFT Holder 共分空投份额,权...
🚀 Nockchain 矿池挖矿完整指南
什么是 Nockchain?Nockchain 是一个面向重计算的轻量级 ZK L1,采用 zkPoW(解 ZKP 谜题来获得 $NOCK)。主网已经上线,支持个人矿工参与,CPU 也能挖。参考:Nockchain GitHub https://mirror.xyz/pangdong.eth/4Sgzv7BIrKWfWRF_uidM3s92XlKy3iyihWJA8CFKx2Y第 1 步:生成钱包地址下载或编译 nockchain-wallet运行以下命令生成密钥对:nockchain-wallet keygen 你会得到:New Private Key → 私钥(只能自己保存,千万不要泄露)New Public Key → 公钥(Base58,大约 132 个字符)👉 在 Nockchain 生态中,这个 Base58 公钥就是钱包地址,用于绑定矿池。第 2 步:创建账户令牌 (Account Token)打开矿池后台页面 https://nockpool.com/signup输入你的 132 字符 Base58 公钥地址点击 创建账户令牌保存 YOUR_ACCOUNT_TO...

Tempo Testnet 节点搭建完整教程
Kaito 新人如何撸空投,从注册到写作入门指南(嘴撸)
“生命的货币不是金钱,甚至也不是时间,而是注意力。” ——Kaito 白皮书开篇如此说道。创作者创造内容,用户贡献注意力,品牌付出广告费——价值却流向平台大户。 Kaito 创新性地把注意力变成资产,通过 AI 驱动的 Yap 机制,赋能内容创作生态。如果你还没参与,现在也不晚!一、什么是 Kaito Yaps?Kaito Yaps 是 Kaito 的 AI 驱动算法系统,用来衡量内容贡献价值:不只是点赞转发,而是分析高质量推文、Smart Followers、互动深度等多维评分;越多高质量互动,Yap 分越高,排行榜排名越靠前。多数项目空投目标都面向前 100–200 名 Yapper。二、InfoFi 网络 + Launchpad 背后的生态逻辑Kaito Connect(InfoFi 网络):品牌可直接将空投奖励发放给表现优秀的 Yapper,无需中介参与,公平透明;Launchpad 启动板:基于 Yaps 排行机制,项目可以筛选高质量内容贡献者提前参与测试、营销或领取 Token 空投。三、Kaito 第一季空投结果回顾Yap 与 NFT Holder 共分空投份额,权...
🚀 Nockchain 矿池挖矿完整指南
什么是 Nockchain?Nockchain 是一个面向重计算的轻量级 ZK L1,采用 zkPoW(解 ZKP 谜题来获得 $NOCK)。主网已经上线,支持个人矿工参与,CPU 也能挖。参考:Nockchain GitHub https://mirror.xyz/pangdong.eth/4Sgzv7BIrKWfWRF_uidM3s92XlKy3iyihWJA8CFKx2Y第 1 步:生成钱包地址下载或编译 nockchain-wallet运行以下命令生成密钥对:nockchain-wallet keygen 你会得到:New Private Key → 私钥(只能自己保存,千万不要泄露)New Public Key → 公钥(Base58,大约 132 个字符)👉 在 Nockchain 生态中,这个 Base58 公钥就是钱包地址,用于绑定矿池。第 2 步:创建账户令牌 (Account Token)打开矿池后台页面 https://nockpool.com/signup输入你的 132 字符 Base58 公钥地址点击 创建账户令牌保存 YOUR_ACCOUNT_TO...
Subscribe to pangdong
Subscribe to pangdong
<100 subscribers
<100 subscribers
目标:30–60 分钟做出一个可提交到 Zama Builder Track 的 dApp:
合约部署到 Sepolia(带 FHE 接口 + 演示接口)
前端(Next.js + ethers)可“连接钱包 / 加一 / 减一 / 读取”
一键发布到 Vercel(免费 HTTPS 域名)
附:提交表单文案要点 & 常见报错速查
sudo apt update && sudo apt upgrade -y && \
sudo apt install -y git curl jq build-essential make gcc \
nodejs npm && \
sudo npm install -g yarn hardhat
node -v && yarn -v
其他系统:可用 WSL/容器;
jq用于处理 ABI。
# 1) 克隆模板
git clone https://github.com/zama-ai/fhevm-hardhat-template
cd fhevm-hardhat-template
npm install
# 2) (可选)使用现成的 hardhat 配置
curl -o hardhat.config.ts https://raw.githubusercontent.com/0xmoei/zama-fhe/refs/heads/main/hardhat.config.ts
# 3) 配置 RPC 与私钥(注意 PRIVATE_KEY 不要带 0x 前缀)
npx hardhat vars set SEPOLIA_RPC_URL https://eth-sepolia.public.blastapi.io
npx hardhat vars set PRIVATE_KEY <你的私钥不带0x>
# 4) 验证账户
npx hardhat accounts --network sepolia
# 能打印你的钱包地址即成功
⚠️ 常见报错:“private key too long, expected 32 bytes” → 去掉
0x前缀后重设:npx hardhat vars delete PRIVATE_KEY && npx hardhat vars set PRIVATE_KEY <不带0x的64位hex>
mkdir -p scripts
cat > scripts/deploy.ts <<'TS'
import { ethers } from "hardhat";
import { writeFileSync, mkdirSync } from "fs";
import path from "path";
async function main() {
const contractName = process.env.CONTRACT || "FHECounter";
const Factory = await ethers.getContractFactory(contractName);
const c = await Factory.deploy();
await c.waitForDeployment();
const address = await c.getAddress();
console.log(`✅ Deployed ${contractName} at: ${address}`);
const outDir = path.join("deployments", "sepolia");
mkdirSync(outDir, { recursive: true });
const artifact = require(path.resolve(
"artifacts",
"contracts",
`${contractName}.sol`,
`${contractName}.json`
));
writeFileSync(
path.join(outDir, `${contractName}.json`),
JSON.stringify({ network: "sepolia", address, contract: contractName, abi: artifact.abi }, null, 2)
);
console.log(`📝 Wrote deployment info to: deployments/sepolia/${contractName}.json`);
}
main().catch((e) => { console.error(e); process.exit(1); });
TS
编译测试:
npx hardhat compile
模板的
FHECounter只有 FHE 函数(需要密文和证明),前端直接调会报 no matching fragment。 我们新增 3 个“演示接口”,便于新手和评审快速体验:incrementPlain / decrementPlain / getCountPlain。
打开并替换 contracts/FHECounter.sol 为下列完整内容(仅在原版基础上新增了 mirror 与 3 个函数;原 FHE 接口保留不变):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
import {SepoliaConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
/// @title A simple FHE counter contract (with plain demo interfaces)
contract FHECounter is SepoliaConfig {
euint32 private _count;
// ✅ 新增:明文镜像,便于演示
uint256 public mirror;
/// @notice Returns the current encrypted count
function getCount() external view returns (euint32) {
return _count;
}
/// @notice FHE increment (ciphertext + proof)
function increment(externalEuint32 inputEuint32, bytes calldata inputProof) external {
euint32 encryptedEuint32 = FHE.fromExternal(inputEuint32, inputProof);
_count = FHE.add(_count, encryptedEuint32);
FHE.allowThis(_count);
FHE.allow(_count, msg.sender);
}
/// @notice FHE decrement (ciphertext + proof)
function decrement(externalEuint32 inputEuint32, bytes calldata inputProof) external {
euint32 encryptedEuint32 = FHE.fromExternal(inputEuint32, inputProof);
_count = FHE.sub(_count, encryptedEuint32);
FHE.allowThis(_count);
FHE.allow(_count, msg.sender);
}
// ✅ 新增:无参演示接口(交易会弹钱包)
function incrementPlain() external { mirror += 1; }
function decrementPlain() external {
require(mirror > 0, "underflow");
mirror -= 1;
}
function getCountPlain() external view returns (uint256) {
return mirror;
}
}
重新编译 + 部署:
npx hardhat compile
npx hardhat run scripts/deploy.ts --network sepolia
# 记录输出的合约地址,例如:
# 0xa0402615e790d92d43e2D6644f95fb196Ae123458
cd ~
npx create-next-app@latest fhevm-dapp --ts --eslint --app --src-dir --use-npm
cd fhevm-dapp
npm i ethers
mkdir -p src/abi
jq '{abi: .abi}' ~/fhevm-hardhat-template/deployments/sepolia/FHECounter.json > src/abi/FHECounter.json
cat > .env.local <<'ENV'
NEXT_PUBLIC_CONTRACT_ADDRESS=改为你刚才的合约地址
NEXT_PUBLIC_RPC_URL=https://eth-sepolia.public.blastapi.io
ENV
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BrowserProvider, Contract } from "ethers";
import abi from "@/abi/FHECounter.json";
export async function getContract() {
if (!(window as any).ethereum) throw new Error("No wallet found. Please install MetaMask.");
const provider = new BrowserProvider((window as any).ethereum);
const signer = await provider.getSigner();
const address = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS!;
const theAbi: any = (abi as any).abi ?? abi;
return new Contract(address, theAbi, signer);
}
如果 Vercel 构建被 ESLint 拦住(
no-explicit-any),可在next.config.ts增加:export default { eslint: { ignoreDuringBuilds: true } }
npm run dev -- -H 0.0.0.0 -p 3000
# 浏览器: http://<服务器IP>:3000
# Connect → Switch → Increment → Read
cd ~/fhevm-dapp
echo -e "node_modules/\n.next/\nout/\n.env.local" >> .gitignore
git init
git add .
git commit -m "init dapp"
git branch -M main
# 先在 GitHub 网页创建仓库 你的用户名/fhevm-dapp
git remote add origin https://github.com/你的用户名/fhevm-dapp.git
git push -u origin main
# 若提示密码:使用 GitHub Personal Access Token(Settings → Developer settings → Tokens)
登录 https://vercel.com → New Project → Import Git Repository
选 你的用户名/fhevm-dapp
Environment Variables 添加:
NEXT_PUBLIC_CONTRACT_ADDRESS = 你的合约地址
NEXT_PUBLIC_RPC_URL = https://eth-sepolia.public.blastapi.io
点击 Deploy
获得 https://<project>.vercel.app(免费 HTTPS)
线上自测:Connect → Switch → Increment → Read,数字应递增。
# Zama FHEVM Demo – Encrypted Counter
- Network: Sepolia
- Contract: 0xa0402615e790d92d43e2D6644f95fb196Ae95199
- Demo: https://<your-project>.vercel.app
## Features
- FHE: increment/decrement (ciphertext + proof), getCount() returns ciphertext.
- Demo: incrementPlain/decrementPlain/getCountPlain (no params, plain number).
## Run Frontend
npm install
# .env.local: NEXT_PUBLIC_CONTRACT_ADDRESS=..., NEXT_PUBLIC_RPC_URL=...
npm run dev
## Deploy Contract
npx hardhat compile
npx hardhat run scripts/deploy.ts --network sepolia
GitHub repo:https://github.com/你的用户名/fhevm-dapp
Deployed demo:https://<your-project>.vercel.app
Project description(可直接贴):
Zama FHEVM Encrypted Counter (Builder Track)
• What it does
A minimal dApp demonstrating homomorphic computation on Zama FHEVM.
It ships both FHE interfaces (encrypted inputs + proof, ciphertext state)
and plain demo interfaces for quick judging (incrementPlain/decrementPlain/getCountPlain).
• Why FHEVM
Secure updates use externalEuint32 + inputProof to modify an euint32 state on-chain,
enabling privacy-preserving computation without revealing raw inputs.
• Implementation
Solidity (Zama FHEVM libs) + Hardhat on Sepolia, Next.js + ethers v6 frontend, Vercel deployment.
The current UI uses the plain interfaces for UX; FHE read-permit/decrypt will be added in v2.
HH8: private key too long → PRIVATE_KEY 不要带 0x。
no matching fragment → 你在前端调用了无参版本,但合约是带参 FHE 函数;使用 incrementPlain/decrementPlain 或按 FHE 流程传 bytes32 + bytes。
Read 显示 0x0000… → 这是密文;使用 getCountPlain() 显示明文演示值。
Vercel 构建被 ESLint 拦住 → 文件头加 /* eslint-disable @typescript-eslint/no-explicit-any */,或 next.config.ts 中 eslint.ignoreDuringBuilds=true。
钱包不弹窗 → 函数名不对 / ABI 未更新 / 钱包不在 Sepolia。
交易 Pending → 换 RPC(Blast/Alchemy/Infura)或提高 Gas。
目标:30–60 分钟做出一个可提交到 Zama Builder Track 的 dApp:
合约部署到 Sepolia(带 FHE 接口 + 演示接口)
前端(Next.js + ethers)可“连接钱包 / 加一 / 减一 / 读取”
一键发布到 Vercel(免费 HTTPS 域名)
附:提交表单文案要点 & 常见报错速查
sudo apt update && sudo apt upgrade -y && \
sudo apt install -y git curl jq build-essential make gcc \
nodejs npm && \
sudo npm install -g yarn hardhat
node -v && yarn -v
其他系统:可用 WSL/容器;
jq用于处理 ABI。
# 1) 克隆模板
git clone https://github.com/zama-ai/fhevm-hardhat-template
cd fhevm-hardhat-template
npm install
# 2) (可选)使用现成的 hardhat 配置
curl -o hardhat.config.ts https://raw.githubusercontent.com/0xmoei/zama-fhe/refs/heads/main/hardhat.config.ts
# 3) 配置 RPC 与私钥(注意 PRIVATE_KEY 不要带 0x 前缀)
npx hardhat vars set SEPOLIA_RPC_URL https://eth-sepolia.public.blastapi.io
npx hardhat vars set PRIVATE_KEY <你的私钥不带0x>
# 4) 验证账户
npx hardhat accounts --network sepolia
# 能打印你的钱包地址即成功
⚠️ 常见报错:“private key too long, expected 32 bytes” → 去掉
0x前缀后重设:npx hardhat vars delete PRIVATE_KEY && npx hardhat vars set PRIVATE_KEY <不带0x的64位hex>
mkdir -p scripts
cat > scripts/deploy.ts <<'TS'
import { ethers } from "hardhat";
import { writeFileSync, mkdirSync } from "fs";
import path from "path";
async function main() {
const contractName = process.env.CONTRACT || "FHECounter";
const Factory = await ethers.getContractFactory(contractName);
const c = await Factory.deploy();
await c.waitForDeployment();
const address = await c.getAddress();
console.log(`✅ Deployed ${contractName} at: ${address}`);
const outDir = path.join("deployments", "sepolia");
mkdirSync(outDir, { recursive: true });
const artifact = require(path.resolve(
"artifacts",
"contracts",
`${contractName}.sol`,
`${contractName}.json`
));
writeFileSync(
path.join(outDir, `${contractName}.json`),
JSON.stringify({ network: "sepolia", address, contract: contractName, abi: artifact.abi }, null, 2)
);
console.log(`📝 Wrote deployment info to: deployments/sepolia/${contractName}.json`);
}
main().catch((e) => { console.error(e); process.exit(1); });
TS
编译测试:
npx hardhat compile
模板的
FHECounter只有 FHE 函数(需要密文和证明),前端直接调会报 no matching fragment。 我们新增 3 个“演示接口”,便于新手和评审快速体验:incrementPlain / decrementPlain / getCountPlain。
打开并替换 contracts/FHECounter.sol 为下列完整内容(仅在原版基础上新增了 mirror 与 3 个函数;原 FHE 接口保留不变):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
import {SepoliaConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
/// @title A simple FHE counter contract (with plain demo interfaces)
contract FHECounter is SepoliaConfig {
euint32 private _count;
// ✅ 新增:明文镜像,便于演示
uint256 public mirror;
/// @notice Returns the current encrypted count
function getCount() external view returns (euint32) {
return _count;
}
/// @notice FHE increment (ciphertext + proof)
function increment(externalEuint32 inputEuint32, bytes calldata inputProof) external {
euint32 encryptedEuint32 = FHE.fromExternal(inputEuint32, inputProof);
_count = FHE.add(_count, encryptedEuint32);
FHE.allowThis(_count);
FHE.allow(_count, msg.sender);
}
/// @notice FHE decrement (ciphertext + proof)
function decrement(externalEuint32 inputEuint32, bytes calldata inputProof) external {
euint32 encryptedEuint32 = FHE.fromExternal(inputEuint32, inputProof);
_count = FHE.sub(_count, encryptedEuint32);
FHE.allowThis(_count);
FHE.allow(_count, msg.sender);
}
// ✅ 新增:无参演示接口(交易会弹钱包)
function incrementPlain() external { mirror += 1; }
function decrementPlain() external {
require(mirror > 0, "underflow");
mirror -= 1;
}
function getCountPlain() external view returns (uint256) {
return mirror;
}
}
重新编译 + 部署:
npx hardhat compile
npx hardhat run scripts/deploy.ts --network sepolia
# 记录输出的合约地址,例如:
# 0xa0402615e790d92d43e2D6644f95fb196Ae123458
cd ~
npx create-next-app@latest fhevm-dapp --ts --eslint --app --src-dir --use-npm
cd fhevm-dapp
npm i ethers
mkdir -p src/abi
jq '{abi: .abi}' ~/fhevm-hardhat-template/deployments/sepolia/FHECounter.json > src/abi/FHECounter.json
cat > .env.local <<'ENV'
NEXT_PUBLIC_CONTRACT_ADDRESS=改为你刚才的合约地址
NEXT_PUBLIC_RPC_URL=https://eth-sepolia.public.blastapi.io
ENV
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BrowserProvider, Contract } from "ethers";
import abi from "@/abi/FHECounter.json";
export async function getContract() {
if (!(window as any).ethereum) throw new Error("No wallet found. Please install MetaMask.");
const provider = new BrowserProvider((window as any).ethereum);
const signer = await provider.getSigner();
const address = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS!;
const theAbi: any = (abi as any).abi ?? abi;
return new Contract(address, theAbi, signer);
}
如果 Vercel 构建被 ESLint 拦住(
no-explicit-any),可在next.config.ts增加:export default { eslint: { ignoreDuringBuilds: true } }
npm run dev -- -H 0.0.0.0 -p 3000
# 浏览器: http://<服务器IP>:3000
# Connect → Switch → Increment → Read
cd ~/fhevm-dapp
echo -e "node_modules/\n.next/\nout/\n.env.local" >> .gitignore
git init
git add .
git commit -m "init dapp"
git branch -M main
# 先在 GitHub 网页创建仓库 你的用户名/fhevm-dapp
git remote add origin https://github.com/你的用户名/fhevm-dapp.git
git push -u origin main
# 若提示密码:使用 GitHub Personal Access Token(Settings → Developer settings → Tokens)
登录 https://vercel.com → New Project → Import Git Repository
选 你的用户名/fhevm-dapp
Environment Variables 添加:
NEXT_PUBLIC_CONTRACT_ADDRESS = 你的合约地址
NEXT_PUBLIC_RPC_URL = https://eth-sepolia.public.blastapi.io
点击 Deploy
获得 https://<project>.vercel.app(免费 HTTPS)
线上自测:Connect → Switch → Increment → Read,数字应递增。
# Zama FHEVM Demo – Encrypted Counter
- Network: Sepolia
- Contract: 0xa0402615e790d92d43e2D6644f95fb196Ae95199
- Demo: https://<your-project>.vercel.app
## Features
- FHE: increment/decrement (ciphertext + proof), getCount() returns ciphertext.
- Demo: incrementPlain/decrementPlain/getCountPlain (no params, plain number).
## Run Frontend
npm install
# .env.local: NEXT_PUBLIC_CONTRACT_ADDRESS=..., NEXT_PUBLIC_RPC_URL=...
npm run dev
## Deploy Contract
npx hardhat compile
npx hardhat run scripts/deploy.ts --network sepolia
GitHub repo:https://github.com/你的用户名/fhevm-dapp
Deployed demo:https://<your-project>.vercel.app
Project description(可直接贴):
Zama FHEVM Encrypted Counter (Builder Track)
• What it does
A minimal dApp demonstrating homomorphic computation on Zama FHEVM.
It ships both FHE interfaces (encrypted inputs + proof, ciphertext state)
and plain demo interfaces for quick judging (incrementPlain/decrementPlain/getCountPlain).
• Why FHEVM
Secure updates use externalEuint32 + inputProof to modify an euint32 state on-chain,
enabling privacy-preserving computation without revealing raw inputs.
• Implementation
Solidity (Zama FHEVM libs) + Hardhat on Sepolia, Next.js + ethers v6 frontend, Vercel deployment.
The current UI uses the plain interfaces for UX; FHE read-permit/decrypt will be added in v2.
HH8: private key too long → PRIVATE_KEY 不要带 0x。
no matching fragment → 你在前端调用了无参版本,但合约是带参 FHE 函数;使用 incrementPlain/decrementPlain 或按 FHE 流程传 bytes32 + bytes。
Read 显示 0x0000… → 这是密文;使用 getCountPlain() 显示明文演示值。
Vercel 构建被 ESLint 拦住 → 文件头加 /* eslint-disable @typescript-eslint/no-explicit-any */,或 next.config.ts 中 eslint.ignoreDuringBuilds=true。
钱包不弹窗 → 函数名不对 / ABI 未更新 / 钱包不在 Sepolia。
交易 Pending → 换 RPC(Blast/Alchemy/Infura)或提高 Gas。
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import { useState } from "react";
import { getContract } from "@/lib/contract";
export default function Home() {
const [status, setStatus] = useState("Idle");
const [count, setCount] = useState<string>("?");
async function connect() {
await (window as any).ethereum.request({ method: "eth_requestAccounts" });
setStatus("Wallet connected");
}
async function switchToSepolia() {
const ethereum = (window as any).ethereum;
try {
await ethereum.request({ method: "wallet_switchEthereumChain", params: [{ chainId: "0xaa36a7" }] });
setStatus("Switched to Sepolia");
} catch (e: any) {
if (e.code === 4902) {
await ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0xaa36a7",
chainName: "Sepolia",
nativeCurrency: { name: "SepoliaETH", symbol: "ETH", decimals: 18 },
rpcUrls: [process.env.NEXT_PUBLIC_RPC_URL],
blockExplorerUrls: ["https://sepolia.etherscan.io/"]
}]
});
setStatus("Sepolia added");
} else {
setStatus("Switch failed: " + e.message);
}
}
}
async function increment() {
try {
const c = await getContract();
const tx = await c.incrementPlain(); // ✅ 演示接口:无参
setStatus("Pending: " + tx.hash);
await tx.wait();
setStatus("Confirmed");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
async function decrement() {
try {
const c = await getContract();
const tx = await c.decrementPlain(); // ✅ 演示接口:无参
setStatus("Pending: " + tx.hash);
await tx.wait();
setStatus("Confirmed");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
async function readCount() {
try {
const c = await getContract();
const v = await c.getCountPlain(); // ✅ 演示接口:返回明文
setCount(v?.toString?.() ?? String(v));
setStatus("Read success");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
return (
<main className="max-w-2xl mx-auto p-6">
<h1 className="text-2xl font-bold">Zama FHEVM Demo</h1>
<p className="text-sm opacity-70 mt-1">Contract: {process.env.NEXT_PUBLIC_CONTRACT_ADDRESS}</p>
<div className="flex gap-2 mt-4">
<button className="px-3 py-2 border rounded" onClick={connect}>Connect Wallet</button>
<button className="px-3 py-2 border rounded" onClick={switchToSepolia}>Switch to Sepolia</button>
</div>
<div className="flex gap-2 mt-4">
<button className="px-3 py-2 border rounded" onClick={increment}>Increment</button>
<button className="px-3 py-2 border rounded" onClick={decrement}>Decrement</button>
<button className="px-3 py-2 border rounded" onClick={readCount}>Read Count</button>
</div>
<p className="mt-4">Count: <b>{count}</b></p>
<p className="mt-2">Status: {status}</p>
<p className="mt-6 text-sm opacity-70">Network: Sepolia</p>
</main>
);
}
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import { useState } from "react";
import { getContract } from "@/lib/contract";
export default function Home() {
const [status, setStatus] = useState("Idle");
const [count, setCount] = useState<string>("?");
async function connect() {
await (window as any).ethereum.request({ method: "eth_requestAccounts" });
setStatus("Wallet connected");
}
async function switchToSepolia() {
const ethereum = (window as any).ethereum;
try {
await ethereum.request({ method: "wallet_switchEthereumChain", params: [{ chainId: "0xaa36a7" }] });
setStatus("Switched to Sepolia");
} catch (e: any) {
if (e.code === 4902) {
await ethereum.request({
method: "wallet_addEthereumChain",
params: [{
chainId: "0xaa36a7",
chainName: "Sepolia",
nativeCurrency: { name: "SepoliaETH", symbol: "ETH", decimals: 18 },
rpcUrls: [process.env.NEXT_PUBLIC_RPC_URL],
blockExplorerUrls: ["https://sepolia.etherscan.io/"]
}]
});
setStatus("Sepolia added");
} else {
setStatus("Switch failed: " + e.message);
}
}
}
async function increment() {
try {
const c = await getContract();
const tx = await c.incrementPlain(); // ✅ 演示接口:无参
setStatus("Pending: " + tx.hash);
await tx.wait();
setStatus("Confirmed");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
async function decrement() {
try {
const c = await getContract();
const tx = await c.decrementPlain(); // ✅ 演示接口:无参
setStatus("Pending: " + tx.hash);
await tx.wait();
setStatus("Confirmed");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
async function readCount() {
try {
const c = await getContract();
const v = await c.getCountPlain(); // ✅ 演示接口:返回明文
setCount(v?.toString?.() ?? String(v));
setStatus("Read success");
} catch (e: any) { setStatus("Error: " + (e?.shortMessage || e?.message)); }
}
return (
<main className="max-w-2xl mx-auto p-6">
<h1 className="text-2xl font-bold">Zama FHEVM Demo</h1>
<p className="text-sm opacity-70 mt-1">Contract: {process.env.NEXT_PUBLIC_CONTRACT_ADDRESS}</p>
<div className="flex gap-2 mt-4">
<button className="px-3 py-2 border rounded" onClick={connect}>Connect Wallet</button>
<button className="px-3 py-2 border rounded" onClick={switchToSepolia}>Switch to Sepolia</button>
</div>
<div className="flex gap-2 mt-4">
<button className="px-3 py-2 border rounded" onClick={increment}>Increment</button>
<button className="px-3 py-2 border rounded" onClick={decrement}>Decrement</button>
<button className="px-3 py-2 border rounded" onClick={readCount}>Read Count</button>
</div>
<p className="mt-4">Count: <b>{count}</b></p>
<p className="mt-2">Status: {status}</p>
<p className="mt-6 text-sm opacity-70">Network: Sepolia</p>
</main>
);
}
Share Dialog
Share Dialog
No activity yet