ZoKrates和Truffle实现可验证链下计算Demo

环境:ubuntu20.04 (VMware)。

1. 安装Truffle

安装npm。

# 安装Node.js版本16.x
# 以具有sudo特权的用户身份运行以下命令,以下载并执行NodeSource安装脚本
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
# 启用NodeSource存储库后,安装Node.js和npm
sudo apt-get install -y nodejs
# 确认安装成功
node --version
npm --version

参考:ubuntu下安装npm

安装truffle。

npm install -g truffle
# 确认一下
truffle version

参考:TruffleDocs

2. 安装Zokrates

curl -LSfs get.zokrat.es | sh
export PATH=$PATH:/home/[你的目录]/.zokrates/bin
#确认一下
zokrates --version

参考:ZokratesDocs

3. 简单尝试一下Zokrates

参考:ZokratesDocs

test.zok中编写以下代码。

def main(private field a, field b) {
    assert(a * a == b);
    return;
}

在Terminal中输入如下命令。编译生成outout.r1csabi.json

zokrates compile -i test.zok

输入如下命令。生成proving.keyverification.key

zokrates setup

输入命令来执行zokrates程序。生成out.wtnswitness

zokrates compute-witness -a 2 4

输入命令生成proof。生成proof.json文件。

zokrates generate-proof

或者可以本地验证一下证明是否通过。

zokrates verify

最后我们可以生成一个用来验证的智能合约。生成verifier.sol。这个只能合约我们后面可以进行调用。

zokrates export-verifier

4. ZoKrates和Truffle实现可验证链下计算

4.1 准备一些文件

和上面一样,编写zok文件。

def main(private field a, field b) {
    assert(a * a == b);
    return;
}

将zokrates添加到全局环境变量里。修改profile文件后重启虚拟机。

gedit /etc/profile
# 添加下面一行
export PATH="$PATH:/home/[你的目录]/.zokrates/bin"
# 重启后确认添加成功
echo $PATH

参考:添加环境变量

输入命令,编译生成outout.r1csabi.jsonproving.keyverification.key。其中outabi.jsonproving.key提前放在客户端文件夹中,之后使用。

zokrates compile -i test.zok
zokrates setup

输入命令,生成verifier.sol。这个文件的生成依赖于outout.r1csverification.key。生成之后可以调用其中的函数,之后验证的时候需要用。将名称改为Verifier.sol

zokrates export-verifier

4.2 编写智能合约

新建一个Truffle模板。

mkdir truffle-test
cd truffle-test
truffle unbox webpack

Verfier.sol复制到contracts文件夹中。在truffle-config.js中更改编译器版本为0.8.0

  compilers: {
    solc: {
      version: "0.8.0"
    }
  }

contracts文件夹中编写智能合约Veri.sol

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
import "./Verifier.sol";

contract Veri {
    function checkZKP(
        uint256[2] memory a,
        uint256[2][2] memory b,
        uint256[2] memory c,
        uint256[1] memory input
    ) public returns (bool) {
        Verifier.Proof memory proof = Verifier.Proof(
            Pairing.G1Point(a[0], a[1]),
            Pairing.G2Point(b[0], b[1]),
            Pairing.G1Point(c[0], c[1])
        );
        Verifier v = new Verifier();
        return v.verifyTx(proof, input);
    }
}

更改migrations\2_deploy_contracts.js

const Veri = artifacts.require("Veri");
const verifier = artifacts.require("Verifier");

module.exports = function(deployer) {
  deployer.deploy(Veri);
  deployer.link(verifier, Veri);
  deployer.deploy(verifier);
};

编译,部署智能合约。

truffle develop
compile
migrate

参考:Truffle入门视频

4.3 编写客户端

编写client.py

from web3 import Web3, HTTPProvider
import subprocess
import json

# Truffle后台运行接口
server = Web3(HTTPProvider('http://127.0.0.1:8545'))

# 填写Veri智能合约部署地址
CONTRACT_ADDRESS = server.toChecksumAddress("0xB47cB388D3B55D812e6A7e94FCDC1D57343A239e")

# 在编译好智能合约之后在truffle-test/build/contracts中找到Veri.json。放到客户端文件夹中。
with open('Veri.json', encoding='UTF-8') as f:
    Veri_contract = json.load(f)

CONTRACT_ABI = Veri_contract['abi']

contract = server.eth.contract(address=CONTRACT_ADDRESS, abi=CONTRACT_ABI)

# 生成witness文件。依赖于abi.json
out_path = "./out"
abi_path = "./abi.json"
witness_path = "./witness"
zokrates_compute_witness = ["zokrates", "compute-witness", "-o", witness_path,'-i', out_path, '-s', abi_path, "-a", "2", "4"]
g = subprocess.run(zokrates_compute_witness, capture_output=True)

# 生成proof文件。依赖于witness文件、proving.key文件
proof_path = "proof.json"
proving_key_path = "proving.key"
zokrates_generate_proof = ["zokrates", "generate-proof",'-w',witness_path,'-p',proving_key_path,'-i',out_path,'-j',proof_path]
g = subprocess.run(zokrates_generate_proof, capture_output=True)

# 生成proof文件后读取文件中的数据。
with open(proof_path, 'r+') as f:
    proof = json.load(f)

a=proof['proof']['a']
a=[Web3.toInt(hexstr=x) for x in a]

b=proof['proof']['b']
b=[[Web3.toInt(hexstr=x) for x in y] for y in b ]

c=proof['proof']['c']
c=[Web3.toInt(hexstr=x) for x in c]

inputs = proof['inputs']
inputs = [Web3.toInt(hexstr=x) for x in inputs]

# 将数据发送到智能合约中,应该得到的result为True
result = contract.functions.checkZKP(a,b,c,inputs).call()
print(result)

5. 流程总结

在这里插入图片描述

  1. Verification Smart Contract文件生成需要outout.r1csverification.key
  2. Witness文件生成需要abi.json以及公开输入和私有输入。
  3. Proof文件生成需要witness文件、proving.key文件。

参考:Zokrates讲解

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值