关于Ethereum隐私数据的现状
一句话概述:以太坊上没有隐私数据
private 声明帮不了你
string private secret;
如上,将变量设置为private只是确保仅通过特定的 function 才能够更改变量的值。但就数据的隐私性“private”而言,这是没用的。基本上,以太坊smart contract上的所有内容都在(所有)节点(即所有矿工和参与者)的硬盘上,私有变量只是为了使阅读不方便,但并不意味着不可能。它不足以保护您的敏感、隐私信息。如下图所示。
而且,smart contract 的代码是透明的,private 的变量声明是很容易被以太坊用户识别的。
1 | 0x5 - length of the string |
private data 上链的方式如下,但是都觉得是隔靴搔痒:
1.hash 上链,作为存证的证明
2.密文上链。
3.时间锁 Time-locked secrets
4.EIP1024
请参考:How to secure Sensitive data on an Ethereum Smart contract?
Zokrates-基于Ethereum的zkp-II-进阶
Project link -> https://github.com/WillZhuang/zkp-workshop-project
让我来 step by step 做介绍:
1.编写关于 bid case 的 code
1 | /// This zksnark is to be used to verify that an operator has choosen |
2.编译
zokrates compile -i verifybid.code
生成 out 和 out.code 文件。其中 out 文件为 102M,out.code 文件为 60M,文件 size 较大。
3.设置
zokrates setup
生成 proving.key 和 verification.key 文件。其中 proving.key 为 121M,文件较大。
4.执行程序
zokrates compute-witness -a 10055980565918579776429468085502320403896861311334950973306171539247124720876 9872212025624827705538064352986283580914984702567748676648365783032194062540 15914440638590293656936968551196129378835493705090190454426890248467449623197 7164401624892807842686423552737135338148312648059491863415011813391162897156 17656893400745400645892949581714190787095935883004706460374622673779099869831 13238137875306891162631161684759202257598937454005976664682588856632564854848 14897476871502190904409029696666322856887678969656209656241038339251270171395 16668832459046858928951622951481252834155254151733002984053501254009901876174 14897476871502190904409029696666322856887678969656209656241038339251270171395 16668832459046858928951622951481252834155254151733002984053501254009901876174 14897476871502190904409029696666322856887678969656209656241038339251270171395 16668832459046858928951622951481252834155254151733002984053501254009901876174 6460329147541296150725376868570071708599740324087744825213520062979428542760 8063340131639693693865282091868641282847827816145781069349300386706996098818 21548706238088528999687556989620717323700520797702367873886065001951944889761 45 500 400 300
-a 后面为执行程序的参数,即对应着verifybid.code中的入参 private field[6] R, field[6] A, field[3] S, private field secret, private field bidone, private field bidtwo, private field bidthree
其中的 500,400,300 即为 3 方的报价,此处可在前序的智能合约中编写为下面的逻辑:
party one,输入 500,执行 smart contract,
party two,输入 400,执行 smart contract,
party three,输入 300,执行smart contract,
smart contract 收集到法定报价数量之后,verifier 端收到 event,执行 step5 和 step6。
其余参数内容来自inputs_of_command_paras
5.生成证明
zokrates generate-proof
生成 witness 文件。其中 witness 文件为 82M,文件较大。
6.导出 solidity verifier
zokrates export-verifier
生成Verifier.sol。
7.编写合约
编写Bid_operator.sol合约,引用 verifyTx 函数。
8.使用 truffle 部署合约
2_deploy_Verifier.js 和 3_deploy_Bid_operator.js 作为配置文件。
9.测试
test/bid_operator.js 中的a, b, c 和 input 均来自于proof.json。
回头来总结一下:
1.本次的 bid case 的目的为验证operator选择了最低的 bid 报价,并且验证了该 bid 为 supplier 所提供;
不能证明 supplier one,two,three 之间互相看不到其他 supplier 的 bid。
2.zokrates默认的证明算法为 G16,根据 zokrates 的说明,在使用了签名和 ethereum address 作为proofs 证明的情况下,G16 是安全的。并且 G16 无需引用libsnark,生成 witness 和 proof 的速度大大加快,使用配置文件的 size 大大降低。
Zokrates-基于Ethereum的zkp-I-介绍
Zokrates
ZoKrates是以太坊上zkSNARKs的工具箱。它可以帮助您在DApp中使用可验证的计算,从高级语言的程序规范到生成计算证明,以及在Solidity中验证这些证明。
闲话少叙,开搞
1.编写 .code 文件
.code 文件是证明的逻辑内容,函数的返回内容为 field、field[n]。
2.1 compile,编译 .code 文件,Zokrates内部生成数字电路,没有指定文件名称的话,默认生成 ./out.code
./zokrates compile -i root.code
2.2 perform the setup phase,进行安装。为 ./out.code 中的已编译程序生成可信设置。在./proving.key和./verifying.key处创建一个证明密钥和一个验证密钥。这些密钥源自随机源,通常称为“有毒废物”。任何有权访问随机源的人都可以生成假证明,该证明将由协议后的验证者接受。
./zokrates setup
2.3 execute the program,执行证明。计算在./out.code中找到的已编译程序的witness和程序的参数。witness是变量的有效分配,包括计算结果。-a 后面跟着程序的参数,用空格分隔。
在./witness创建一个witness文件
./zokrates compute-witness -a 337 113569
2.4 generate a proof of computation,生成 proof(证明)。使用./proving.key中的证明密钥,生成./out.code的证明,从而得到./witness。
./zokrates generate-proof
2.5 export a solidity verifier,使用./verifying.key上的验证密钥,生成一个Solidity合约,其中包含生成的验证密钥和公共函数,以验证./out.code上已编译程序的解决方案。
在./verifier.sol被创建。
./zokrates export-verifier
3.通过验证者合同,可以检查此证明。例如,使用web3,调用将如下所示:
1 | Verifier.at(<verifier contract address>).verifyTx(A, A_p, B, B_p, C, C_p, H, K, [...publicInputs, ...outputs]) |
A, A_p, B, B_p, C, C_p, H, K的值,以及publicInputs和 outputs 均来自于步骤2.4中生成的proof.json文件。
ERC20-721Token的发行-冻结-多方签名功能
发行
ERC 代币的发行已经标准化,最好采用 openzeppelin 的模板,并搭配 solidity5.x 版本和 truffle 工具使用,效果更佳。
1 | // ERC 721 |
1 | // ERC 20 |
Freeze 功能 (openzeppelin-contracts v3.2.0之后)
也叫做 pause 或者 close,具体就是停止 Token 相关的 transfer(转账)功能
1 | // ERC 20 |
openzeppelin-contracts v3.2.0版本中的实现代码如下 ERC721Pausable
1 | contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnable, ERC721Pausable { |
MultiSigWallet 多方签名
gnosis 的 multisignature 功能最为完善。已经有多个生产项目采用此工具。目前此工具合约的 solidity 版本为0.4.15,项目语言版本交旧,但没有发生过安全问题。
首先 ERC20 合约的初始化总金额地址需要给到 MultiSigWallet 的合约地址,由 MultiSigWallet 合约完成多方签名确认后,ERC20 代币从 MultiSigWallet 合约的地址发送到接收人的账户地址。
1 | // ERC 20 |
Live website 地址在这里,以下操作均为https://wallet.gnosis.pm/上的截图。
1.增加钱包。如下图,完成钱包增加配置

2.点击 Wallets Name,即点击’Lcoin’,进入钱包的详细页面,如下图,进入后需要手动添加 Tokens Name,其后点击 Withdraw,最后经过 2 位 Required confirmations 后,Executed 状态变为 Yes
注意,此处,由 MultiSigWallet 合约完成多方签名确认后,ERC20 代币从 MultiSigWallet 合约的地址发送到接收人的账户地址(a825),MultiSigWallet 合约执行 transfer 给到接收人的账户地址(a825),所以 MultiSigWallet 合约的地址上需要有足够的 Eth 作为 gas
即使用 MultiSigWallet 转账时,花费的 gas 是 2 位 Required confirmations 和一次 transfer 的总和

3.如下图,虽然在 MultiSigWallet中可以选择到调用 ERC20 合约中的 close 函数,但是 close 函数并不受 MultiSigWallet 的控制,由onlyOwner,即 msg.sender 单独控制并操作

4.如下图,具体交易的内容在 MultiSigWallet,并配合etherscan 和 MyEtherWallet 中的结果



关联内容 ==> https://willzhuang.github.io/2020/09/07/ERC721%E5%AE%9E%E8%B7%B5/实践