千家信息网

circom/snarkjs实战zk rollup的示例分析

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,今天就跟大家聊聊有关circom/snarkjs实战zk rollup的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。过去的一年出现了
千家信息网最后更新 2026年11月02日circom/snarkjs实战zk rollup的示例分析

今天就跟大家聊聊有关circom/snarkjs实战zk rollup的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

过去的一年出现了很多零知识证明应用,在这个教程中,我们将首先学习零知识证明的基本概念、使用circom搭建算术电路、使用snarkjs实现零知识证明的全过程,并利用这些知识实现二层扩容方案zk rollup。

零知识程序和其他程序的实现不太一样。首先,你要解决的问题需要先转化成多项式,再进一步转化成电路。例如,多项式x³ + x +5 可以表示成如下的电路:

sym_1 = x * x // sym_1 = x² sym_2 = sym_1 * x // sym_2 = x³ y = sym_2 + x // y = x³ + x ~out = y + 5

Circom编译器将逻辑转换为电路。通常我们不需要自己设计基础电路。如果你需要一个哈希函数或签名函数,可以在circomlib 找到。

2、证据的生成与验证:零知识证明的流程

在运行零知识证明程序之前,我们需要创建一个可信的设置,这需要 一个电路以及一些随机数。一旦设置完成就会生成一个证明密钥和一个验证密钥,分别用于生成证据和执行验证。

一旦创建了证明/验证密钥对,就可以生成证据了。

有两种类型的输入:公开输入和私有输入。例如,A向B转账但是不希望公开账户余额,那么A的账户余额就是私有输入,也被称为见证(Witness)。公开输入可以是A和B的地址或者转账金额,这完全取决于你的具体设计。

接下来证明人就可以利用证明密钥、公开输入和见证来生成证据:

最后一步是验证。验证方使用公开输入、证据和验证密钥来验证证据。

公开输入、见证(私有输入)、证明密钥、验证密钥、电路、证据这些基本概念以及相互之间的关系,就是我们继续下面的教程之前需要理解的零知识证明的基本概念。

3、Circom基本概念:算术电路语言

首先我们先了解下Circom的语法。Circom的语法类似javascript和C,提供一些基本的数据类型和操作,例如for、while、>>、array等。

让我们看一个具体的实例。

假设x、y是保密的(即witness),我们不想暴露x和y的具体值,但是希望证明 (x * y) + z == out,其中z,out是公开输入。我们假设out = 30, z = 10, 那么显然 (x*y) = 20,但是这不会暴露x和y的具体值。

circom提供了如下这些关键字用于描述算术电路:

  • signal:信号变量,要转换为电路的变量,可以是private或public

  • template:模板,用于函数定义,就像Solidity中的function或golang中的func

  • component:组件变量,可以把组件变量想象成对象,而信号变量是对象的公共成员

Circom也提供了一些操作符用于操作信号变量:

  • <==, ==>:这两个操作符用于连接信号变量,同时定义约束

  • ←, →:这些操作符为信号变量赋值,但不会生成约束条件

  • ===:这个操作符用来定义约束

好了,这些就是我们继续零知识证明实践需要了解的circom关键字。

4、用circom和snarkjs实现零知识证明应用的全流程

STEP 1:编译电路文件,生成circuit.json:

circom sample1.circom

STEP 2:创建可信设置,使用groth协议生成proving_key.json和verification_key.json

snarkjs setup - protocol groth

STEP 3:生成见证(私有输入)。这一步需要输入,因此应当将你的输入存入input.json,就像下面这样:

// input.json{"x":3, "y":5, "z": 100}

使用下面的命令生成见证文件witness.json:

snarkjs calculatewitness

STEP 4:使用如下的snarkjs命令生成证据:

snarkjs proof

结果是得到proof.json、public.json。在public.json中包含了公开输入,例如:

// public.json{  "115", // → out  "100" // → z:100}

STEP 5:使用如下snarkjs命令进行验证:

snarkjs verify

5、零知识证明实践案例:zk rollup实现

zk rollup是一个二层解决方案,不过它和其他的二层方案不同。zk roolup将所有数据放在链上,使用zk-snark进行验证。因此,不需要复杂的挑战游戏。在zk rollup中,用户的地址记录在智能合约的merkle树上,使用3字节的索引来表征用户的地址(地址的原始大小是20字节),因此zk rollup可以通过减小数据大小来增加交易吞吐量。

为了便于理解,在下面的zk rollup实现中,我们有意忽略一些细节,原始的zk rollup教程可以参考 ZKRollup Tutorial。

首先,有一个记录账号的merkle树,账号记录的内容是(公钥,余额)。每个交易的内容是(发送方索引、接收方索引、金额)。流程如下:

1、检查发送方账号是否在merkle树上 2、验证发送方的签名 3、更新发送方的余额并验证中间merkle根 4、更新接收方的余额并更新merkle根

circom电路程序的变量定义如下:

// account treesignal input account_root;signal private input account_pubkey[2];signal private input account_balance;  // new account root after sender's balance is updatedsignal private input new_sender_account_root;  // txsignal private input tx_sender_pubkey[2]signal private input tx_sender_balancesignal private input tx_amountsignal private input tx_sender_sig_r[2]signal private input tx_sender_sig_ssignal private input tx_sender_path_element[levels]signal private input tx_sender_path_idx[levels]signal private input tx_receiver_pubkey[2]signal private input tx_receiver_balancesignal private input tx_receiver_path_element[levels]signal private input tx_receiver_path_idx[levels]// output new merkle rootsignal output new_root;

在这个案例中几乎所有的变量都是私有的,不管是公钥、账户余额还是签名等等,只有merkle根和更新后的merkle根是公开的。path_element是构建merkle根的中间值,path_idx是一个索引数组,用于保存merkle树每一层的索引 -- 这时一个二叉树,因此只有左右两个分支,0表示左,1表示右。最终的路径像一个二进制字符串:001011。

下面的circom代码检查发送方是否存在:

//__1. verify sender account existencecomponent senderLeaf = HashedLeaf();senderLeaf.pubkey[0] <== tx_sender_pubkey[0];senderLeaf.pubkey[1] <== tx_sender_pubkey[1];senderLeaf.balance <== account_balance; component senderExistence = GetMerkleRoot(levels);senderExistence.leaf <== senderLeaf.out; for (var i=0; i

上面的代码也比较简单,哈希发送方的公钥和账户余额,用merkle树的中间值计算,然后得到merkle根(senderExistence.out)。检查计算得到的merkle根和输入是否一致(account_root)。

出于简化考虑,我们省略了merkle树和哈希函数的实现,你可以查看HashedLeaf和GetMerkleRoot。

下面的circom代码检查发送方的签名:

//__2. verify signaturecomponent msgHasher = MessageHash(5);msgHasher.ins[0] <== tx_sender_pubkey[0];msgHasher.ins[1] <== tx_sender_pubkey[1];msgHasher.ins[2] <== tx_receiver_pubkey[0];msgHasher.ins[3] <== tx_receiver_pubkey[1];msgHasher.ins[4] <== tx_amount    component sigVerifier = EdDSAMiMCSpongeVerifier(); sigVerifier.enabled <== 1;sigVerifier.Ax <== tx_sender_pubkey[0];sigVerifier.Ay <== tx_sender_pubkey[1];sigVerifier.R8x <== tx_sender_sig_r[0];sigVerifier.R8y <== tx_sender_sig_r[1];sigVerifier.S <== tx_sender_sig_s;sigVerifier.M <== msgHasher.out;

就像区块链交易需要验证发送方的签名一样,在上面的代码中,我们首先哈希消息然后进行签名,然后调用不同的封装函数。

更新发送方余额并检查新的merkle根。

//__3. Check the root of new tree is equivalentcomponent newAccLeaf = HashedLeaf();newAccLeaf.pubkey[0] <== tx_sender_pubkey[0];newAccLeaf.pubkey[1] <== tx_sender_pubkey[1];newAccLeaf.balance <== account_balance - tx_amount;component newTreeExistence = GetMerkleRoot(levels);newTreeExistence.leaf <== newAccLeaf.out;for (var i=0; i

前面的两个步骤从发送方的角度检查信息,然后更新发送方的余额并计算新的merkle根。最下面一行:newTreeExistence.out === new_sender_account_root;作用是检查计算得到的merkle根和输入(new_sender_account_root)是否一致。通过这个检查,可以避免伪造或不正确的输入。

下面的代码更新接收方余额以及merkle树:

//__5. update the root of account treecomponent newReceiverLeaf = HashedLeaf();newReceiverLeaf.pubkey[0] <== tx_receiver_pubkey[0];newReceiverLeaf.pubkey[1] <== tx_receiver_pubkey[1];newReceiverLeaf.balance <== tx_receiver_balance + tx_amount;component newReceiverTreeExistence = GetMerkleRoot(levels);newReceiverTreeExistence.leaf <== newReceiverLeaf.out;for (var i=0; i

最后一步更新接收方余额,计算并输出新的merkle根。一旦电路构建好,就像一个黑盒子。如果你输入正确的值,那么输出一定是正确的,因此用户容易检查以避免恶意中间人。这就是为什么我们需要在电路最后输出一些东西的原因 -- 在这个案例里我们输出的是merkle根。

看完上述内容,你们对circom/snarkjs实战zk rollup的示例分析有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

输入 电路 验证 知识 余额 生成 变量 检查 证据 面的 更新 密钥 代码 信号 内容 函数 见证 私有 地址 就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技企业 互联网黑科技 广东万易互联网科技有限公司惠州分公司 博彦科技互联网金融 科技互联网龙头 睿民互联网科技 互联网金融 科技创新 甘肃拓世互联网科技有限公司 互联网科技创新企业排名 科技大学互联网专业好不好 银川新华互联网科技学校地址 互联网科技革命什么开始 中国科技创新与世界互联网大会 烟台灵鸽互联网科技有限公司 区块链结合互联网科技 上海创道互联网络科技有限公司 卡尔迅互联网科技有限公司 张家口科技产业互联网平台 玉溪新华互联网科技怎么选 互联网科技创业有什么好项目 万易互联网科技 互联网女皇 腾讯科技 互联网金融 科技创新 顺网科技2021年互联网排名 互联网科技中介 佳云科技和互联网广告 成都互联网科技公司工作好不好 华夏恒生科技与互联网科技 互联网科技股为什么大涨 工业互联网科技创业
0