跳到主要内容

使用 zkVerifyJS 验证证明

信息

本教程使用的全部代码可在 这里 查看。

本教程将使用 zkVerify JS 包验证证明。zkVerify JS 是一个 NPM 包,可方便提交证明、监听事件与获取聚合证明,适用于我们支持的所有证明类型。

备注

开始前请将 Node JS 升级到最新版本(v24.1.0),可用 node -v 查看版本。

新建项目并安装 zkverify JS,执行以下命令:

新建目录:

mkdir proof-submission

进入项目目录:

cd proof-submission

初始化 NPM 项目:

npm init -y && npm pkg set type=module

安装 zkverifyjsdotenv

npm i zkverifyjs dotenv

创建 .env 存储 SEED PHRASE,稍后用于发送证明:

SEED_PHRASE = "this is my seed phrase i should not share it with anyone"

新建 index.js 编写验证逻辑,导入 zkVerify JSdotenv

import { zkVerifySession, Library, CurveType, ZkVerifyEvents } from "zkverifyjs";
import dotenv from 'dotenv';
dotenv.config();

还需导入此前生成的文件:proof、verification key、public inputs,示例如下:

import fs from "fs";
const proof = JSON.parse(fs.readFileSync("./data/proof.json"));
const publicInputs = JSON.parse(fs.readFileSync("./data/public.json"));
const key = JSON.parse(fs.readFileSync("./data/main.groth16.vkey.json"));
信息

接下来编写核心逻辑,将证明发送到 zkVerify 验证。以下代码需放在 async main 函数内:

async function main(){
// Required code
}
main();

导入完成后,先用带 $tVFY 的账号在 Volta 测试网上实例化 session:

const session = await zkVerifySession.start().Volta().withAccount(process.env.SEED_PHRASE);

然后向 Volta 提交验证请求,传入证明类型、proof、public signals、key,并指定聚合用的 domainId。关于 Domain 与聚合见此处,按目标链选择 Domain ID(现有域列表)。同时创建事件监听器,在证明被聚合时监听 NewAggregationReceipt

let statement, aggregationId;
session.subscribe([
{
event: ZkVerifyEvents.NewAggregationReceipt,
callback: async (eventData) => {
console.log("New aggregation receipt:", eventData);
if(aggregationId == parseInt(eventData.data.aggregationId.replace(/,/g, ''))){
let statementpath = await session.getAggregateStatementPath(
eventData.blockHash,
parseInt(eventData.data.domainId),
parseInt(eventData.data.aggregationId.replace(/,/g, '')),
statement
);
console.log("Statement path:", statementpath);
const statementproof = {
...statementpath,
domainId: parseInt(eventData.data.domainId),
aggregationId: parseInt(eventData.data.aggregationId.replace(/,/g, '')),
};
fs.writeFileSync("aggregation.json", JSON.stringify(statementproof));
}
},
options: { domainId: 0 },
},
]);
const {events} = await session.verify()
.groth16({library: Library.snarkjs, curve: CurveType.bn128})
.execute({proofData: {
vk: key,
proof: proof,
publicSignals: publicInputs
}, domainId: 0});

可以监听事件获取提交证明的状态,收集用于链上验证的重要数据。我们有区块包含、交易最终化等事件,可用 events.on() 监听:

events.on(ZkVerifyEvents.IncludedInBlock, (eventData) => {
console.log("Included in block", eventData);
statement = eventData.statement;
aggregationId = eventData.aggregationId;
})

node index.js 运行脚本后,会生成 aggregation.json,其中包含在目标链验证聚合所需的全部信息,如:

{
"root": "0xef4752160e8d7ccbc254a87f71256990f2fcd8173e15a592f7ccc7e130aa5ab0",
"proof": [
"0x40fbf21f1990ef8d1425d12ec550176fe848a7c63f0c59f7a48101e51c9aceee",
"0x0be311c3643fb3fcd2b59bf4cfd02bdef943caf78f92d94a080659468c38fef9",
"0x2117831ac2000ccdbb51f5deef96d215961ca42920a9196259e8b6e91b9fef53"
],
"numberOfLeaves": 8,
"leafIndex": 0,
"leaf": "0xc5a8389b231522aad8360d940eb3ce275f0446bba1a9bd188b31d1c7dd37f136",
"domainId": 0,
"aggregationId": 137
}

可在 zkVerify explorer 通过 txHash 查看已验证证明的详情。

alt_text

运行上述代码后,证明凭证会保存在 attestation.json 中。至此已用 zkVerify 完成验证,接下来可在链上业务中使用该凭证。下一步可通过智能合约验证收据,参见此教程