Quarter I 2022
原文作者:Ansem(推特@blknoiz06) 原文链接:Quarter I 2022always keep a few gems in your pockethttps://blknoiz06.substack.com译者:Evelyn、AluAyi、Henson、Rex|W3.Hitchhiker2022市场整体展望你好!对于我的堕落同胞(fellow degenerates)和其他不知何故闯入这个页面的读者们,我将尝试在这里梳理今年一季度的一些想法。这是我第二次写这样的长篇大论,所以请忍耐一下(哈哈),希望它比从我推特发出来的数百条零零散散的推文更有条理。 2021年对于加密资产来说很显然是突破性的一年,从机构接受度到散户采纳度,加密货币已经远远超过了其历史上的任何时期。加密资产经历了两年的强劲牛市,部分原因是FED的鸽派态度助长了市场参与者的风险偏好,再加上web3协议的快速创新。令人震惊的是,在这个周期中,我们能从这则典型的新闻吹嘘 "看这个代币上涨了10倍"体会到加密货币在社会中的流行程度。Visa购置了一个朋克,阿迪达斯买了一只无聊猴,许多TradFi公司如Jum...

Arweave—不仅仅是存储这么简单
项目简介Arweave 是个非典型或非主流方向的区块链项目,我们之前对其一无所知,稍有了解的人,可能也就是把它看作是众多类似 Filecoin 的去中心化存储项目之一。所以也造成了之前我们对Arweave的一些忽视,今天就好好的把整个项目重新再认识一下。 Arweave 协议的愿景是提供去中心化、可扩展和永久的链上数据存储(永存);就像以太坊被认为是世界计算机,Arweave 可以被认为是永远不会忘记的世界硬盘。创始人Arweave创始人兼CEO—Sam Williams是去中心化爱好者,在分布式系统设计和实施方面具有丰富的经验。英国人,黑客,博士,目前推特关注者15K。先简单了解Filecoin的方案Filecoin是去中心化存储赛道最知名的项目,我们聊Arweave肯定免不了先来了解下Filecoin。 首先,我们知道,Protocol Labs开创的IPFS 是去中心化存储领域的开创者 ,从 2014 年上线开始,自由生长,已经存储了大量的数据。但是要让 IPFS 成为商业可用的存储系统,而不是随意的数据分享平台,必须提供服务质量保障 ,这就是 Filecoin 要解决的问...

Lyra - Option AMM Pioneer
Created by Jack Ding|W3.HitchhikerAn Overview of On-chain OptionsAt present, there are three main types of on-chain options:OrderbookDeFi Option Vaults(structured products)Auto-market Marker(resource:https://www.panewslab.com/zh/articledetails/1644045861942159.html)Orderbooke.x.:Zeta,Psyoption,Opyn Option order books also require high tps blockchain to guarantee cheap and fast execution. Opyn used the Orderbook model on ETH main chain, but due to the lack of liquidity and high gas costs,trade...
W3.Hitchhiker aims to discover cutting-edge tech and innovative teams by first principles thinking and long-term analysis strategies.
Quarter I 2022
原文作者:Ansem(推特@blknoiz06) 原文链接:Quarter I 2022always keep a few gems in your pockethttps://blknoiz06.substack.com译者:Evelyn、AluAyi、Henson、Rex|W3.Hitchhiker2022市场整体展望你好!对于我的堕落同胞(fellow degenerates)和其他不知何故闯入这个页面的读者们,我将尝试在这里梳理今年一季度的一些想法。这是我第二次写这样的长篇大论,所以请忍耐一下(哈哈),希望它比从我推特发出来的数百条零零散散的推文更有条理。 2021年对于加密资产来说很显然是突破性的一年,从机构接受度到散户采纳度,加密货币已经远远超过了其历史上的任何时期。加密资产经历了两年的强劲牛市,部分原因是FED的鸽派态度助长了市场参与者的风险偏好,再加上web3协议的快速创新。令人震惊的是,在这个周期中,我们能从这则典型的新闻吹嘘 "看这个代币上涨了10倍"体会到加密货币在社会中的流行程度。Visa购置了一个朋克,阿迪达斯买了一只无聊猴,许多TradFi公司如Jum...

Arweave—不仅仅是存储这么简单
项目简介Arweave 是个非典型或非主流方向的区块链项目,我们之前对其一无所知,稍有了解的人,可能也就是把它看作是众多类似 Filecoin 的去中心化存储项目之一。所以也造成了之前我们对Arweave的一些忽视,今天就好好的把整个项目重新再认识一下。 Arweave 协议的愿景是提供去中心化、可扩展和永久的链上数据存储(永存);就像以太坊被认为是世界计算机,Arweave 可以被认为是永远不会忘记的世界硬盘。创始人Arweave创始人兼CEO—Sam Williams是去中心化爱好者,在分布式系统设计和实施方面具有丰富的经验。英国人,黑客,博士,目前推特关注者15K。先简单了解Filecoin的方案Filecoin是去中心化存储赛道最知名的项目,我们聊Arweave肯定免不了先来了解下Filecoin。 首先,我们知道,Protocol Labs开创的IPFS 是去中心化存储领域的开创者 ,从 2014 年上线开始,自由生长,已经存储了大量的数据。但是要让 IPFS 成为商业可用的存储系统,而不是随意的数据分享平台,必须提供服务质量保障 ,这就是 Filecoin 要解决的问...

Lyra - Option AMM Pioneer
Created by Jack Ding|W3.HitchhikerAn Overview of On-chain OptionsAt present, there are three main types of on-chain options:OrderbookDeFi Option Vaults(structured products)Auto-market Marker(resource:https://www.panewslab.com/zh/articledetails/1644045861942159.html)Orderbooke.x.:Zeta,Psyoption,Opyn Option order books also require high tps blockchain to guarantee cheap and fast execution. Opyn used the Orderbook model on ETH main chain, but due to the lack of liquidity and high gas costs,trade...
W3.Hitchhiker aims to discover cutting-edge tech and innovative teams by first principles thinking and long-term analysis strategies.

Subscribe to W3.Hitchhiker

Subscribe to W3.Hitchhiker
Share Dialog
Share Dialog


>100 subscribers
>100 subscribers
作者:Xiang
https://blog.iden3.io/first-zk-proof.html
目前国内参考的经典教程是 circom 老版的(2020 年 4 月的文章),当时教程的一些包文件和指令格式,参数部分已弃用或者改变,circom 也升级到了 circom2,新的 circom2 编译器是通过 rust 生成的。
在本教程中,我们参考 iden3 官方最新教程文档,将指导你使用 circom2 和 snarkjs 库创建和执行你的第一个零知识证明。
在密码学中,零知识证明或零知识协议是一种方法,通过该方法,一方(证明者)可以向另一方(验证者)证明他们知道值x,而无需传达除了他知道值x这个事实之外任何信息。 解释来源于 Wiki
零知识证明使我们能够证明自己的某些特定特征,而无需透露任何额外的信息。
从哲学的角度来看,它们是一组新的加密工具的一部分,这些工具使得透明性不必与隐私性冲突。
术语“ zk-snarks”代表_zero-knowledge succinct non-interactive arguments of knowledge_:
zero-knowledge:零知识
**Succinctness:**简洁(证明信息较短,方便验证)
Non-interactivity:无需交互
arguments of knowledge:知识论据
暂时无需了解这些概念意味着什么。 可以简单地将 zk-snarks 视为产生零知识证明的有效(或简洁)方法:可以使证明信息足够短到可以发布到区块链,并且可以被任何有权验证它们的人( 我们称为验证者)以后都能读取。
如果众筹仅针对 KYC 或授权用户,使用 zk-snarks,你可以证明自己是被授权可参加众筹的人,而无需透露自己是谁或花费了多少。
与上述类似,您可以在不透露性别,年龄甚至姓名的情况下证明自己有资格投票。
例如,可以在全国大选中投票,而仅表明您是该国的公民,并且年满 18 岁。
您可以使用 zk-snarks 来证明您最近对 Covid-19 的测试是阴性,而不用透露测试的确切日期或测试的医院:仅需要在官方认可的时间窗口内有效即可。
Circom 是一个可以轻松构建代数电路的库。
snarkjs 是 zk-snarks 协议的独立实现-完全用 JavaScript 编写。
这些库是设计好能协同工作的:在 circom 中构建的任何电路都可以在 snarkjs 中使用。
zk-snarks 不能直接应用于任何计算问题。在使用之前,首先需要将问题转换为正确的形式。第一步就是将其转换为代数电路。
尽管这一步做起来并不总是很明显,但事实证明,我们关心的大多数计算问题都可以转化为代数电路。

关于零知识问题的转换,可参考前文:
https://w3hitchhiker.mirror.xyz/sjtV-I7l6_XY9uVkykvFRRAriAAusTLFq8s-gCGdviE
你需要系统中的多个依赖项来运行 circom 及其相关工具。
核心工具是用 Rust 编写的circom 编译器。 为使用 Rust , 你可以安装 rustup。如果你使用 Linux 或者 macOS,请打开终端输入以下指令。
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
从我们的源代码安装,请克隆 circom 仓库:
git clone https://github.com/iden3/circom.git
进入 circom 目录,使用 cargo build 编译
cargo build --release
你可以按如下指令安装此二进制可执行文件:
cargo install --path circom
前面指令生成 circom 二进制文件将存在目录 $HOME/.cargo/bin。
现在,你应该能够使用help查看可执行文件的所有选项:
circom --help
Circom Compiler 2.0.0
IDEN3
Compiler for the Circom programming language
USAGE:
circom [FLAGS] [OPTIONS] [input]
FLAGS:
-h, --help Prints help information
--inspect Does an additional check over the constraints produced
--O0 No simplification is applied
-c, --c Compiles the circuit to c
--json outputs the constraints in json format
--r1cs outputs the constraints in r1cs format
--sym outputs witness in sym format
--wasm Compiles the circuit to wasm
--wat Compiles the circuit to wat
--O1 Only applies var to var and var to constant simplification
-V, --version Prints version information
OPTIONS:
--O2 <full_simplification> Full constraint simplification [default: full]
-o, --output <output> Path to the directory where the output will be written [default: .]
ARGS:
<input> Path to a circuit with a main component [default: ./circuit.circom]
需要在电脑中先安装Node.js
snarkjs 是一个 npm 包,其中包含从 circom生成的工件生成和验证 ZK 证明的代码。
你可以用以下命令安装snarkjs : npm install -g snarkjs
circom 允许程序员定义算术电路的约束。所有约束必须采用 A*B + C = 0 的形式,其中 A、B 和 C 是信号的线性组合。
使用circom 构建的算术电路对信号进行操作。让我们定义我们的第一个电路,它简单地将两个输入信号相乘并产生一个输出信号。
pragma circom 2.0.0;
/*This circuit template checks that c is the multiplication of a and b.*/
template Multiplier2 () {
// Declaration of signals.
signal input a;
signal input b;
signal output c;
// Constraints.
c <== a * b;
}
首先, pragma 指令用于指定编译器版本(类似于 solidity)。这是为了确保电路与 pragma 指令后的编译器版本兼容。否则,编译器会抛出警告。
然后,我们使用关键字template 来定义新电路的形状,为 Multiplier2。现在,我们必须定义它的信号。信号可以用标识符命名,例如 a, b, c。
这个电路有2个 private 输入信号,名为 a 和 b ,还有一个输出信号 c。
输入和输出使用<==运算符进行关联。 在 circom 中,<==运算符做两件事。 首先是连接信号。 第二个是施加约束。
在本例中,我们使用<==将c连接到a和b,同时将c约束为a * b的值,即电路做的事情是让强制信号 c 为 a*b 的值。
注意:在每个template 中,我们首先声明它的信号,然后声明相关的约束。
我们创建了叫Multiplier2的template 电路。
但是,要实际创建电路,我们必须创建此模板的一个实例(使用名为main的组件实例化它)。 为此,请创建一个包含以下内容的文件:
pragma circom 2.0.0;
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a*b;
}
component main = Multiplier2();
使用 circom编写算术电路后,我们应该将其保存在扩展名为 .circom 的文件。 你可以创建自己的电路或使用我们电路库 circomlib中的模板。
在我们的案例中,我们创建了multiplier2.circom文件。现在是编译电路以获得表示它的算术方程组的时候了。作为编译的结果,我们还将获得计算见证的程序。我们可以使用以下命令编译电路:
circom multiplier2.circom --r1cs --wasm --sym
使用这些选项,我们生成三种类型的文件:
--r1cs:生成 multiplier2.r1cs ( R1CS 电路的二进制格式的约束系统)
--wasm:生成 multiplier2_js 目录其中包含Wasm 代码(multiplier2.wasm) 和生成见证所需要的其他文件
--sym:生成 multiplier2.sym(以注释方式调试和打印约束系统所需的符号文件)
我们可以使用选项 -o 来指定创建这些文件的目录
要显示电路的信息,可以运行:
snarkjs info -r multiplier2.r1cs
可以看到如下输出:
[INFO] snarkJS: Curve: bn-128
[INFO] snarkJS: # of Wires: 4
[INFO] snarkJS: # of Constraints: 1
[INFO] snarkJS: # of Private Inputs: 2
[INFO] snarkJS: # of Public Inputs: 0
[INFO] snarkJS: # of Labels: 4
[INFO] snarkJS: # of Outputs: 1
此信息与我们设计的电路相吻合。 记住,我们有两个私有输入 a 和 b,以及一个输出 c。 我们指定的一个约束是a * b = c。
可以再检查一遍,通过运行以下命令来打印电路的约束: snarkjs r1cs print multiplier2.r1cs multiplier2.sym
输出如下:
[INFO] snarkJS: [ 21888242871839275222246405745257275088548364400416034343698204186575808495616main.a ] * [ main.b ] - [ 21888242871839275222246405745257275088548364400416034343698204186575808495616main.c ] = 0
忽略前缀,可以读为:
a*b-c=0
在创建证明之前,我们需要计算与电路的所有约束匹配电路的所有信号。为此,我们将使用circom 生成的Wasm 模块来协助完成这项工作。
使用生成的 Wasm二进制文件和三个 JavaScript 文件,我们只需提供一个包含输入的文件,模块将执行电路并计算所有中间信号和输出。输入、中间信号和输出的集合称为见证。
在我们的例子中,我们想证明我们能够因式分解数字 33。因此,我们分配 a = 3 和 b = 11。
请注意,我们也可以将数字 1 分配给一个输入,将数字 33 分配给另一个。所以,我们的证明并没有真正表明我们能够分解数字 33。
我们需要创建一个名为 input.json 的文件,其中包含以标准 json 格式编写的输入:
{"a": 3, "b": 11}
现在,我们计算见证并生成二进制文件 witness.wtns,其中包含 snarkjs接受的格式。
在使用标志 --wasm 和电路 multiplier2.circom 调用 circom 编译器后,我们可以找到 multiplier2_js 文件夹,其中包含 multiplier2.wasm 中的 Wasm 代码和所有需要的 JavaScript 文件。
进入 multiplier2_js 目录,添加 input.json 文件并执行:
node generate_witness.js multiplier2.wasm input.json witness.wtns
将生成 ẁitness.wtns 文件, 该文件以与 snarkjs兼容的二进制格式编码,这是我们用来创建实际证明的工具。
注意. circom 也支持使用 C++ 行进计算见证,我们的例子是采用的小型电路,对于大型电路,C++ 见证计算明显快于 WASM 计算器,使用C++的方法可以参考官方文档。
在编译电路并使用适当的输入运行见证计算器后,我们将拥有一个扩展名为 .wtns 的文件,其中包含所有计算的信号,以及一个扩展名为 .r1cs 的文件,其中包含描述电路的约束。这两个文件都将用于创建我们的证明。
现在,我们将使用 snarkjs 工具为我们的输入,生成证明和验证证明。特别是,使用multiplier2 时,意味着我们可以证明我们能够提供数字 33 的两个因数。也就是说,我们将证明我们知道两个整数 a和 b,因此当我们将它们相乘时,它会得到数字33。
目前,snarkjs 支持 2 个证明系统:Groth16 和 PLONK。
我们样例中采用的方案是 Groth16,使用 PLONK 可以参考 snarkjs教程。
我们将使用 Groth16 zk-SNARK 协议。要使用此协议,你需要生成可信设置(trusted setup)。 **Groth16 需要为每个电路生成可信设置。**更详细地说,可信设置由两部分组成:
tau 的权力,它独立于电路。
阶段2,取决于电路。
接下来,我们为创建可信设置提供了一个非常基本的仪式,我们还提供了创建和验证 Groth16 证明的基本命令。查看相关的背景部分可以查看 snarkjs 教程以获取更多信息。
首先,我们开始新的“tau 的权力”仪式:
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
然后,我们为仪式做出贡献:
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
现在,我们在文件 pot12_0001.ptau 中有对 tau 权力的贡献,下面,我们就可以继续进行阶段 2。
阶段 2 是特定电路的。执行以下命令开始该阶段的生成:
snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
接下来,我们生成一个 .zkey文件,其中包含证明和验证密钥以及所有 阶段2的贡献。执行以下命令启动一个新的 zkey:
snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey
为仪式的 阶段2做出贡献:
snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey --name="1st Contributor Name" -v
导出验证密钥:
snarkjs zkey export verificationkey multiplier2_0001.zkey verification_key.json
一旦计算出见证并且已经执行了可信设置,我们就可以生成与电路和见证人相关联的 zk-proof:
snarkjs groth16 prove multiplier2_0001.zkey witness.wtns proof.json public.json
此命令生成 Groth16 证明并输出两个文件:
proof.json: 它包含了证明
public.json: 它包含公共输入和输出的值。
要验证证明,请执行以下指令:
snarkjs groth16 verify verification_key.json public.json proof.json
该命令使用我们之前导出的文件 verify_key.json、proof.json 和 public.json 来检查证明是否有效。如果证明有效,则命令输出 OK。
一个有效的证明不仅证明我们知道一组满足电路的信号,而且证明我们使用的公共输入和输出与 public.json 文件中描述的相匹配。
👉 snarkjs 还可以生成一个 Solidity 验证器,允许在以太坊区块链上验证证明。
首先,我们需要使用以下命令生成 Solidity 代码:
snarkjs zkey export solidityverifier multiplier2_0001.zkey verifier.sol
此命令采用验证密钥 multiplier2_0001.zkey 并在名为 verifier.sol的文件中输出 Solidity 代码。你可以从此文件中获取代码并将其剪切并粘贴到 Remix 中运行。你将看到代码包含两个合约:Pairing 和Verifier。你只需要部署Verifier 合约。
你可能使用 Rinkeby、Kovan 或 Ropsten 这样的测试网。你也可以使用 JavaScript VM,但在某些浏览器中,验证需要很长时间并且页面可能会冻结。
Verifier 有一个名为 verifyProof 的view 函数,当且仅当证明和输入有效时才返回 TRUE 。为了方便调用,可以使用 snarkJS 生成调用的参数,输入
snarkjs generatecall
将命令的输出的可以复制粘贴到 Remix 中 verifyProof 方法的参数字段中。如果一切正常,此方法应返回结果 TRUE。当你尝试只更改参数,就会看到结果是 FALSE。
以下链接已通过验证,可在浏览器查看生成的verifier.sol 的源码:
https://ropsten.etherscan.io/address/0x9ff6e2a7d7cb20f785aa6c98c4a1772375c9d7f3#code

声明:本文内容仅供参考、交流,不构成任何投资建议。若存在明显的理解或数据的错误,欢迎反馈。
本文内容系 W3.Hitchhiker 参考相关教程后所作内容,如需转载请标明出处。
W3.Hitchhiker 官方推特:
作者:Xiang
https://blog.iden3.io/first-zk-proof.html
目前国内参考的经典教程是 circom 老版的(2020 年 4 月的文章),当时教程的一些包文件和指令格式,参数部分已弃用或者改变,circom 也升级到了 circom2,新的 circom2 编译器是通过 rust 生成的。
在本教程中,我们参考 iden3 官方最新教程文档,将指导你使用 circom2 和 snarkjs 库创建和执行你的第一个零知识证明。
在密码学中,零知识证明或零知识协议是一种方法,通过该方法,一方(证明者)可以向另一方(验证者)证明他们知道值x,而无需传达除了他知道值x这个事实之外任何信息。 解释来源于 Wiki
零知识证明使我们能够证明自己的某些特定特征,而无需透露任何额外的信息。
从哲学的角度来看,它们是一组新的加密工具的一部分,这些工具使得透明性不必与隐私性冲突。
术语“ zk-snarks”代表_zero-knowledge succinct non-interactive arguments of knowledge_:
zero-knowledge:零知识
**Succinctness:**简洁(证明信息较短,方便验证)
Non-interactivity:无需交互
arguments of knowledge:知识论据
暂时无需了解这些概念意味着什么。 可以简单地将 zk-snarks 视为产生零知识证明的有效(或简洁)方法:可以使证明信息足够短到可以发布到区块链,并且可以被任何有权验证它们的人( 我们称为验证者)以后都能读取。
如果众筹仅针对 KYC 或授权用户,使用 zk-snarks,你可以证明自己是被授权可参加众筹的人,而无需透露自己是谁或花费了多少。
与上述类似,您可以在不透露性别,年龄甚至姓名的情况下证明自己有资格投票。
例如,可以在全国大选中投票,而仅表明您是该国的公民,并且年满 18 岁。
您可以使用 zk-snarks 来证明您最近对 Covid-19 的测试是阴性,而不用透露测试的确切日期或测试的医院:仅需要在官方认可的时间窗口内有效即可。
Circom 是一个可以轻松构建代数电路的库。
snarkjs 是 zk-snarks 协议的独立实现-完全用 JavaScript 编写。
这些库是设计好能协同工作的:在 circom 中构建的任何电路都可以在 snarkjs 中使用。
zk-snarks 不能直接应用于任何计算问题。在使用之前,首先需要将问题转换为正确的形式。第一步就是将其转换为代数电路。
尽管这一步做起来并不总是很明显,但事实证明,我们关心的大多数计算问题都可以转化为代数电路。

关于零知识问题的转换,可参考前文:
https://w3hitchhiker.mirror.xyz/sjtV-I7l6_XY9uVkykvFRRAriAAusTLFq8s-gCGdviE
你需要系统中的多个依赖项来运行 circom 及其相关工具。
核心工具是用 Rust 编写的circom 编译器。 为使用 Rust , 你可以安装 rustup。如果你使用 Linux 或者 macOS,请打开终端输入以下指令。
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
从我们的源代码安装,请克隆 circom 仓库:
git clone https://github.com/iden3/circom.git
进入 circom 目录,使用 cargo build 编译
cargo build --release
你可以按如下指令安装此二进制可执行文件:
cargo install --path circom
前面指令生成 circom 二进制文件将存在目录 $HOME/.cargo/bin。
现在,你应该能够使用help查看可执行文件的所有选项:
circom --help
Circom Compiler 2.0.0
IDEN3
Compiler for the Circom programming language
USAGE:
circom [FLAGS] [OPTIONS] [input]
FLAGS:
-h, --help Prints help information
--inspect Does an additional check over the constraints produced
--O0 No simplification is applied
-c, --c Compiles the circuit to c
--json outputs the constraints in json format
--r1cs outputs the constraints in r1cs format
--sym outputs witness in sym format
--wasm Compiles the circuit to wasm
--wat Compiles the circuit to wat
--O1 Only applies var to var and var to constant simplification
-V, --version Prints version information
OPTIONS:
--O2 <full_simplification> Full constraint simplification [default: full]
-o, --output <output> Path to the directory where the output will be written [default: .]
ARGS:
<input> Path to a circuit with a main component [default: ./circuit.circom]
需要在电脑中先安装Node.js
snarkjs 是一个 npm 包,其中包含从 circom生成的工件生成和验证 ZK 证明的代码。
你可以用以下命令安装snarkjs : npm install -g snarkjs
circom 允许程序员定义算术电路的约束。所有约束必须采用 A*B + C = 0 的形式,其中 A、B 和 C 是信号的线性组合。
使用circom 构建的算术电路对信号进行操作。让我们定义我们的第一个电路,它简单地将两个输入信号相乘并产生一个输出信号。
pragma circom 2.0.0;
/*This circuit template checks that c is the multiplication of a and b.*/
template Multiplier2 () {
// Declaration of signals.
signal input a;
signal input b;
signal output c;
// Constraints.
c <== a * b;
}
首先, pragma 指令用于指定编译器版本(类似于 solidity)。这是为了确保电路与 pragma 指令后的编译器版本兼容。否则,编译器会抛出警告。
然后,我们使用关键字template 来定义新电路的形状,为 Multiplier2。现在,我们必须定义它的信号。信号可以用标识符命名,例如 a, b, c。
这个电路有2个 private 输入信号,名为 a 和 b ,还有一个输出信号 c。
输入和输出使用<==运算符进行关联。 在 circom 中,<==运算符做两件事。 首先是连接信号。 第二个是施加约束。
在本例中,我们使用<==将c连接到a和b,同时将c约束为a * b的值,即电路做的事情是让强制信号 c 为 a*b 的值。
注意:在每个template 中,我们首先声明它的信号,然后声明相关的约束。
我们创建了叫Multiplier2的template 电路。
但是,要实际创建电路,我们必须创建此模板的一个实例(使用名为main的组件实例化它)。 为此,请创建一个包含以下内容的文件:
pragma circom 2.0.0;
template Multiplier2() {
signal input a;
signal input b;
signal output c;
c <== a*b;
}
component main = Multiplier2();
使用 circom编写算术电路后,我们应该将其保存在扩展名为 .circom 的文件。 你可以创建自己的电路或使用我们电路库 circomlib中的模板。
在我们的案例中,我们创建了multiplier2.circom文件。现在是编译电路以获得表示它的算术方程组的时候了。作为编译的结果,我们还将获得计算见证的程序。我们可以使用以下命令编译电路:
circom multiplier2.circom --r1cs --wasm --sym
使用这些选项,我们生成三种类型的文件:
--r1cs:生成 multiplier2.r1cs ( R1CS 电路的二进制格式的约束系统)
--wasm:生成 multiplier2_js 目录其中包含Wasm 代码(multiplier2.wasm) 和生成见证所需要的其他文件
--sym:生成 multiplier2.sym(以注释方式调试和打印约束系统所需的符号文件)
我们可以使用选项 -o 来指定创建这些文件的目录
要显示电路的信息,可以运行:
snarkjs info -r multiplier2.r1cs
可以看到如下输出:
[INFO] snarkJS: Curve: bn-128
[INFO] snarkJS: # of Wires: 4
[INFO] snarkJS: # of Constraints: 1
[INFO] snarkJS: # of Private Inputs: 2
[INFO] snarkJS: # of Public Inputs: 0
[INFO] snarkJS: # of Labels: 4
[INFO] snarkJS: # of Outputs: 1
此信息与我们设计的电路相吻合。 记住,我们有两个私有输入 a 和 b,以及一个输出 c。 我们指定的一个约束是a * b = c。
可以再检查一遍,通过运行以下命令来打印电路的约束: snarkjs r1cs print multiplier2.r1cs multiplier2.sym
输出如下:
[INFO] snarkJS: [ 21888242871839275222246405745257275088548364400416034343698204186575808495616main.a ] * [ main.b ] - [ 21888242871839275222246405745257275088548364400416034343698204186575808495616main.c ] = 0
忽略前缀,可以读为:
a*b-c=0
在创建证明之前,我们需要计算与电路的所有约束匹配电路的所有信号。为此,我们将使用circom 生成的Wasm 模块来协助完成这项工作。
使用生成的 Wasm二进制文件和三个 JavaScript 文件,我们只需提供一个包含输入的文件,模块将执行电路并计算所有中间信号和输出。输入、中间信号和输出的集合称为见证。
在我们的例子中,我们想证明我们能够因式分解数字 33。因此,我们分配 a = 3 和 b = 11。
请注意,我们也可以将数字 1 分配给一个输入,将数字 33 分配给另一个。所以,我们的证明并没有真正表明我们能够分解数字 33。
我们需要创建一个名为 input.json 的文件,其中包含以标准 json 格式编写的输入:
{"a": 3, "b": 11}
现在,我们计算见证并生成二进制文件 witness.wtns,其中包含 snarkjs接受的格式。
在使用标志 --wasm 和电路 multiplier2.circom 调用 circom 编译器后,我们可以找到 multiplier2_js 文件夹,其中包含 multiplier2.wasm 中的 Wasm 代码和所有需要的 JavaScript 文件。
进入 multiplier2_js 目录,添加 input.json 文件并执行:
node generate_witness.js multiplier2.wasm input.json witness.wtns
将生成 ẁitness.wtns 文件, 该文件以与 snarkjs兼容的二进制格式编码,这是我们用来创建实际证明的工具。
注意. circom 也支持使用 C++ 行进计算见证,我们的例子是采用的小型电路,对于大型电路,C++ 见证计算明显快于 WASM 计算器,使用C++的方法可以参考官方文档。
在编译电路并使用适当的输入运行见证计算器后,我们将拥有一个扩展名为 .wtns 的文件,其中包含所有计算的信号,以及一个扩展名为 .r1cs 的文件,其中包含描述电路的约束。这两个文件都将用于创建我们的证明。
现在,我们将使用 snarkjs 工具为我们的输入,生成证明和验证证明。特别是,使用multiplier2 时,意味着我们可以证明我们能够提供数字 33 的两个因数。也就是说,我们将证明我们知道两个整数 a和 b,因此当我们将它们相乘时,它会得到数字33。
目前,snarkjs 支持 2 个证明系统:Groth16 和 PLONK。
我们样例中采用的方案是 Groth16,使用 PLONK 可以参考 snarkjs教程。
我们将使用 Groth16 zk-SNARK 协议。要使用此协议,你需要生成可信设置(trusted setup)。 **Groth16 需要为每个电路生成可信设置。**更详细地说,可信设置由两部分组成:
tau 的权力,它独立于电路。
阶段2,取决于电路。
接下来,我们为创建可信设置提供了一个非常基本的仪式,我们还提供了创建和验证 Groth16 证明的基本命令。查看相关的背景部分可以查看 snarkjs 教程以获取更多信息。
首先,我们开始新的“tau 的权力”仪式:
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
然后,我们为仪式做出贡献:
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
现在,我们在文件 pot12_0001.ptau 中有对 tau 权力的贡献,下面,我们就可以继续进行阶段 2。
阶段 2 是特定电路的。执行以下命令开始该阶段的生成:
snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
接下来,我们生成一个 .zkey文件,其中包含证明和验证密钥以及所有 阶段2的贡献。执行以下命令启动一个新的 zkey:
snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey
为仪式的 阶段2做出贡献:
snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey --name="1st Contributor Name" -v
导出验证密钥:
snarkjs zkey export verificationkey multiplier2_0001.zkey verification_key.json
一旦计算出见证并且已经执行了可信设置,我们就可以生成与电路和见证人相关联的 zk-proof:
snarkjs groth16 prove multiplier2_0001.zkey witness.wtns proof.json public.json
此命令生成 Groth16 证明并输出两个文件:
proof.json: 它包含了证明
public.json: 它包含公共输入和输出的值。
要验证证明,请执行以下指令:
snarkjs groth16 verify verification_key.json public.json proof.json
该命令使用我们之前导出的文件 verify_key.json、proof.json 和 public.json 来检查证明是否有效。如果证明有效,则命令输出 OK。
一个有效的证明不仅证明我们知道一组满足电路的信号,而且证明我们使用的公共输入和输出与 public.json 文件中描述的相匹配。
👉 snarkjs 还可以生成一个 Solidity 验证器,允许在以太坊区块链上验证证明。
首先,我们需要使用以下命令生成 Solidity 代码:
snarkjs zkey export solidityverifier multiplier2_0001.zkey verifier.sol
此命令采用验证密钥 multiplier2_0001.zkey 并在名为 verifier.sol的文件中输出 Solidity 代码。你可以从此文件中获取代码并将其剪切并粘贴到 Remix 中运行。你将看到代码包含两个合约:Pairing 和Verifier。你只需要部署Verifier 合约。
你可能使用 Rinkeby、Kovan 或 Ropsten 这样的测试网。你也可以使用 JavaScript VM,但在某些浏览器中,验证需要很长时间并且页面可能会冻结。
Verifier 有一个名为 verifyProof 的view 函数,当且仅当证明和输入有效时才返回 TRUE 。为了方便调用,可以使用 snarkJS 生成调用的参数,输入
snarkjs generatecall
将命令的输出的可以复制粘贴到 Remix 中 verifyProof 方法的参数字段中。如果一切正常,此方法应返回结果 TRUE。当你尝试只更改参数,就会看到结果是 FALSE。
以下链接已通过验证,可在浏览器查看生成的verifier.sol 的源码:
https://ropsten.etherscan.io/address/0x9ff6e2a7d7cb20f785aa6c98c4a1772375c9d7f3#code

声明:本文内容仅供参考、交流,不构成任何投资建议。若存在明显的理解或数据的错误,欢迎反馈。
本文内容系 W3.Hitchhiker 参考相关教程后所作内容,如需转载请标明出处。
W3.Hitchhiker 官方推特:
No activity yet