Greetings! New to Zcash?
The Zcash network is young, but evolving quickly! Sign up and we'll be in touch with more information about how you can get started with Zcash!

语种

Zcash 在以太坊上的集成的最新进展 (ZoE)

Ariel Gabizon and Christian Reitwiessner | Jan 19, 2017

以太坊研发团队成员和 Zcash 公司合作,致力于开发出将可编程技术和隐私性同时结合仅区块链中。这篇联合博文同时倍发布在 以太坊博客, 本文的联合作者是 Ariel Gabizon (Zcash) 和 Christian Reitwiessner (Ethereum)。

以太坊灵活的智能合约接口使得大范围的区块链应用成为可能,其中有很多应用可能还未被发觉。这种可能性使得隐私性的添加是十分有必要的。

想象一下,比如,在一个选举或拍卖活动中使用区块链的智能合约,此项活动的结果可以被任何区块链的观察者所查看到,但是个人的投票历史或者竞拍出价则是保密的。另外一个设置是选择性的公开;比如,证明投票者在特定的城市却不公开具体位置。

以太坊想要添加这种功能的核心任务是添加简明非交互式的零知识,这个零知识是 Zcash 底层技术零知识证明 (zk-SNARKs) 中的参数。

Zcash 公司的一个目标,代码名称为 炼金术项目,是使用去中心化的交易所方式来进行 Ethereum 和 Zcash 的互换。 连接这两条区块链和两个团队,一个专注于开发可编程性,另一个专注于隐私性,这似乎是生活中必不可少的应用把它们聚在一起。

在上一周以太坊团队在柏林阻止的聚会中,Ariel Gabizon 作为 Zcash 和 Ethereum 联合团队中 Zcash 的一员拜访了 Christian Reitwiessner。值得一提的是本次拜访完成了将 zk-SNARK 写入 Solidity 的概念验证阶段,Solidity 是基于预编译的以太坊智能合约的以太坊 C++ 客户端。本次的补充名为 Baby ZoE,在其中 zk-SNARK 的预编译合约被写入 Parity - 它是以太坊 Rust 客户端。添加后的区别在于,我们仅添加了微小的密码学源码(椭圆曲线乘法,加法和配对),剩余工作留给了 Solidity。这使得 zk-SNARK 的建造具备更高的灵活度和多样性,同时不需要进行硬分叉 (更多细节在下文中提到)。我们通过在以太坊测试网络中成功的验证一个隐私的 Zcash 交易来验证这些代码的有效性。 这个验证仅花费了 42 毫秒,这表明预编译合约的功能可以被添加至以太坊智能合约,同时这样做所消耗的 gas 可以被控制在可接受的范围内。

这样的系统可以用来做什么?

Zcash 的系统可以被以太坊使用发行隐私的自定义代币。这样的代币已经有了很多应用场合,比如投票(更多细节请见下文)或是简单的拍卖中买家之间互相看不到竞价。

如果你想要尝试编译这些概念证明,你可以使用以下的命令行。如果你需要帮助,请访问 https://gitter.im/ethereum/privacy-tech

git clone https://github.com/scipr-lab/libsnark.git

cd libsnark
sudo PREFIX=/usr/local make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 CURVE=ALT_BN128 \
   FEATUREFLAGS="-DBINARY_OUTPUT=1 -DMONTGOMERY_OUTPUT=1 -DNO_PT_COMPRESSION=1" \
   lib install
cd ..
git clone --recursive -b snark https://github.com/ethereum/cpp-ethereum.git
cd cpp-ethereum
./scripts/install_deps.sh && cmake . -DEVMJIT=0 -DETHASHCL=0 && make eth
cd ..
git clone --recursive -b snarks https://github.com/ethereum/solidity.git
cd solidity
./scripts/install_deps.sh && cmake . && make soltest
cd ..
./cpp-ethereum/eth/eth --test -d /tmp/test
# And on a second terminal:
./solidity/test/soltest -t "*/snark" -- --ipcpath   /tmp/test/geth.ipc  --show-messages

我们同样讨论了 zk-SNARKs 在以太坊区块链上的其他使用场合,现在我们展开讨论。

定义预编译合约

回顾得知 ZNARK 是对某些财产的一个简短的证明,而为以太坊区块链添加的隐私功能正是用户有能力验证这种证明。

在近期的建造中,验证过程仅仅由单纯执行椭圆曲线完成。特别的,验证需要在椭圆曲线组中进行标量乘法和加法;但同时也需要一个更加繁琐的求解操作称为双线性配对。

正如 这里 提到的,在 EVM 中应用这些操作太过耗费资源。 因此,我们想要使用预编译合约来进行这些操作。 现在,我们面临的问题是 - 这些预编译合约的普遍性应该有多大呢?

SNARK 的安全等级与参数曲线相对应。 粗略估计,曲线的阶数越高,所谓的嵌入阶数也越高,这基于这条曲线的 SNARK 安全程度也就越高。另一方面,自然地,这一过程中产生的参数越多,计算曲线过程所消耗的资源就越多。 因此,作为合约的设计者们可能会期望出于他们自己的效率和安全的这种考虑来选择这些参数。 这是关于实施预编译合约过程中能达到更好的普遍性的一个重要参数,合约的设计者可以从一簇曲线中选择适合自己需求的曲线。 我们确实从开始时就面向更高的普遍适用性 - 对于曲线的描述被设计为合约输入的一部分。在这种情况下,一个智能合约能够为任何椭圆曲线簇增加辅助功能。

这种方法的一个复杂之处在于操作过程中填写 gas 消耗 - 你必须仅仅从椭圆曲线的描述来估计 gas 消耗,并没有直接的明确方式来计算运行一个曲线需要花费多少(在最坏的情况下)。 一个更加一般化的方法时从一个给定的曲线簇中给出所有的曲线。我们发现当使用 Barreto-Naehrig (BN) 曲线簇时,用户可以使用曲线参数粗略估算曲线计算所消耗的费用,同时这类曲线支持一项特殊的优化 Ate 配对方法。以下时预编译的工作过程和 gas 消耗计算的概述, 概述

我们从这个问题中学到了很多,但最终选择让观念证明“保持简单化”;同时也是为了实施当前 Zcash 所使用的特定曲线。 我们通过使用在 libsnark 程序库中对应函数的包装来实现以上功能,这个函数库同样用于 Zcash。 我们注意到可以仅仅为整个 SNARK 使用一个包装来完成当前 Zcash 所有的验证 - 这样的操作同样适用于上文提到的 Baby ZoE 项目。然而,清晰的定义椭圆曲线的操作可以有助于一个更加广泛的 SNARK 参数的建立,这种做法需要一个验证器包含上文提到的三种椭圆曲线进行操作。

重新使用 Zcash 设置来发行新的匿名代币和其他应用

你也许已经听说了,使用 SNARKs 需要一个 复杂的相位设置 ,在这个过程中系统的公开参数建立了。这些公开参数生成需要以一种安全的方式,当每次我们需要使用一个 SNARK 作为环路参数来明显的阻碍使用 SNARKs。(简化这个相位设置过程同样是我们工作的重要目标之一,但目前并未在这方面取得进展)。

在另一方面,好消息是如果有人想要发行一个代币来支持隐私交易,他可以简单的采用已经通过安全方式生成的 Zcash 参数。 以上方式能够实现的原因在于,Zcash 用于验证隐私交易的环路并未依附于一种货币或区块链。然而,它的一个明确的输入是 Merkle 树的一个根,它包含所有记账的货币;也因此,如果用户想使用一种货币,那么他的输入也会随改变。 同时,如果发行一个新的匿名代币是如此的简单,你已经可以再这方面做很多工作,即便这些工作看起来于代币关系不大。 比如,假设我们要发起一个匿名的投票来完成一项二选一的选择工作。我们可以为这次投票发行一个订制的代币,并为每一个投票人发送一个代币。由于这个过程中没有“挖矿”,因此不会产生新的代币。现在参选人可以按照他们的选择把代币发送至两个备选地址之一。最终优胜的一方是持有更多代币的地址。

其他应用

一个不基于代币的系统会更简单的拥有“选择性揭露”功能:你可以,比如,持续的再区块链上发布你的加密消息,假设消息中包含你的当前地址(也许还包含其他人的签名来避免诈骗)。如果你对每条消息都使用不同的密钥,你仅可以在某个特定时段使用密钥揭露你的位置。通过使用 zk-SNARKs,你可以证明你的位置所在地同时并不揭露你去过哪: 在 zk-SNARK 中,你可以解密你的位置并且确定你所在的区域。通过使用零知识证明的特性,每个人可以验证位置的真实性,但没有人会查询导你的真实所在地。

未来的工作

真正的实现上面提到的功能 - 创建匿名代币并在以太坊区块链上验证 Zcash 交易,将 Zcash 所使用的更多元素集成如 Solidity 客户端。 首先,我们必须为目前在 Zcash 网络中的节点部署任务,不入升级承诺树。 其次,我们需要在 Solidity 中部署 equihash 工作量证明算法。否则,交易可以为自身进行验证,但是我们不知道是否使用过的单据存在在 Zcash 区块链中,也不知道交易是否发送给了 Zcash 区块链。 幸运的是,以上功能的实施已经 被写入; 然而,为了更够进入实用阶段,它的效率还需要进一步提升。

感谢:我们感谢 Sean Bowe 的技术支持。我们同样感谢 Sean 和 Vitalik Buterin 有帮助的批注和 Ming Chan 的编辑。