众所周知,以太坊的区块链是公开可见的.也就是说,每当你转移ERC-20通证或任何其他的数字资产时都会在区块链上留下记录,任何第三方都可以轻而易举地监控到这些记录.
同时,如果借助Etherscan,Blockscout这样的区块链浏览器,第三方还可以查到你全部区块链上活动的历史记录.
可以说,你在区块链上的活动就好像是在"裸奔",不过不要害怕,我们可以通过一些手段来保护自己的隐私.比如,你可以开通多个加密货币的帐户,但你必须时刻牢记不要让这些帐户产生关联.
就拿我们日常生活中时常见到的情况来说,如果突然出现一个账户钱不够的情况该怎么办?这些条条框框将成为你在使用加密货币时的噩梦.有没有一种更优雅的,更有技术含量的解决方案呢?
最好的办法,就是利用AZTEC(一个建立在以太坊之上的隐私协议).在本篇文章中,我不会像你的高中老师一样一条条地为你讲述协议使用到的底层密码学技术.我们来聊点轻松的,聊聊这个协议的实际应用,也就是我们今天的主题 -  - 如何用AZTEC来开发隐私通证.
可以不夸张的说,AZTEC这个协议就是我的心血.
在开始前,这里我假定你已经是一名"链圈"的老司机了,并对以下的一些常识有了最基本的了解:
同时,请确保你的计算机上装有node.js和npm ,接下来我们使用npm来安装Truffle框架,只需一行指令:
说完了最基本的区块链常识,现在我们上点干货,来聊聊核心的技术概念.
如果把以太坊比作一个国家,那么AZTEC协议就是一片森林.
在以太坊这个国家中,人们通过去中心化应用进行交互和财务往来,还可以自由地搬到想去的城市(自由选择钱包软件).我认为AZTEC协议就是这个国家里的一片宁静森林,人们可以来到森林里躲避追踪,在进入森林前你的区块链上活动都是公开可见的,而一旦踏入了森林,你所有的交易都是保密的.
就像下面这张美丽的风景图,就可以代表我所说的进入AZTEC协议的理念.在正常情况下,你的区块链上活动就如同这张图中的风景一样清晰可见,而一旦穿越了图中的拱门,整个世界(以太坊)就会逐渐模糊,并最终被森林( AZTEC 协议)隐藏.
AZTEC中有一个基本概念,叫记录(notes).记录是该协议中的"一等公民"和核心原语(操作系统或计算机网络用语范畴,是由若干条指令组成的,用于完成一定功能的一个过程).
当你使用零知识证明技术进行交易时,智能合约中不会存储任何的余额信息,仅仅存储椭圆曲线点(密码学上的概念,可以简单地理解为零知识证明机制的组件),而椭圆曲线点对于没有私钥进行解密的第三方来说都只是计算噪声.
很重要的一点是,我们要正确地区分最常见的ERC-20标准和AZTEC协议的隐私通证标准ERC-1724.
从原理上来说,前者存储了以太坊地址和未加密余额之间的映射,而后者对余额进行了加密.我喜欢将AZTEC记录比作比特币的UTXO(Unspent Transaction Output,即未使用的交易输出)模型,因为在AZTEC上花费记录的过程与它非常相似.
以下是一个记录中的内容,我们可以按照可见性将它们分类:
为了节省时间,在这里我们不过多地去讲那些花里胡哨的密码学技术.不过在进行编程之前,你需要注意的是AZTEC协议需要一个可信任的设置.本篇文章先暂时使用我们团队内部生成的可信任设置,这里仅作为介绍,由于生产环境情况十分复杂,不同情况还需要不同对待.
首先,按照如下命令复制代码库并安装node模块:
在这个过程中,控制台中可能会弹出很多关于scrypt和keccak这两种哈希函数的信息,不要在意,因为我们用到了aztec.js,而它调用了以太坊的web3.js库,从而生成了一些关于密码学的依赖项.
在实际运行展示程序之前,你还需要执行以下几个重要步骤:
在存放源代码的src文件夹中创建一个accounts.js文件,在其中只需要设置两个帐户,具体的设置方法你可以参考一个名为accounts.js.example的示例文件;
在项目的根目录下创建一个.env文件,并使用下面的属性填充它.同样的,文件夹中也包含一个名为.env.example的示例文件;
将包含隐私通证的智能合约部署到以太坊测试网络Rinkeby上,你可以使用Truffle框架来执行这一操作:
接下来是部署环境变量,可以按照如下步骤:
INFURA_API_KEY:INFURA托管节点的API访问密钥.
完成上述步骤之后,现在,你的项目应该是这样的:
接下来运行这个展示程序:
中间需要等待一段时间,因为交易被发送到了以太坊测试网络Rinkeby上.几分钟后,你会在控制台中收到一份收据清单.恭喜你,你刚刚在以太坊上进行了第一次隐私通证的转移!
现在,让我们来看看src / demo.js中的源代码.
生成一些随机帐户,这里我们必须使用椭圆曲线"secp256k1"来生成公钥私钥对,因为AZTEC协议需要帐户的公钥,而不仅仅是它们的地址;
创建4个记录,前两个记录属于第一个帐户,后两个从初始总共10个通证中转移8个到第二个帐户.
为了更好地理解第2步,请回想一下我们刚才说到的,AZTEC的记录与比特币UTXO模型相似的性质.当一个人转移资金时,他必须把余额转换成一组新的记录,这与使用平衡模型的以太坊的交易规范相反.
此外,我将以太坊中使用的帐户(src / accounts.js中的帐户)与随机生成的AZTEC帐户区分开来(演示脚本生成了一个名为aztecAccounts.json的文件).
声明所有者publicOwner很乐意将10个公共可见的ERC-20通证转换为AZTEC隐私通证;
第一个随机生成的AZTEC帐户成为通证新的所有者,回想一下,前两个记录每个值为5个通证,并且都由该AZTEC帐户拥有.
以完全成熟的零知识证明形式将8个通证转移到第二个AZTEC账户;
销毁前两个输入的记录,从而第一个AZTEC帐户将来不能再重复使用它们.
我们需要这些代码来与名为"NoteRegistry"(记录注册)的智能合约进行交互,这个智能合约是每个隐私通证智能合约所特有的.你可以将代码中的proofHashes视为先前生成证明的唯一标识符列表.
在代码中,我们制作了一些通证并授予NoteRegistry智能合约从ERC-20智能合约中支出它们的权限.
就像ERC-20一样,NoteRegistry需要被授予使用AZTEC证明的权限.我们承认这是一个需要积极研究的领域,我们也正在研究大幅度提升用户体验的方法.
最后,也是最有趣的部分:调用隐私通证智能合约进行通证转移.
请注意,第一笔交易仅转移ERC-20通证,因此第三方可以分析得到转移的通证数.但第二笔交易就是完全保密的了.
以下是我们本篇文章所有操作逻辑的思维导图:
在触发隐私通证转移之前,需要进行大量的预先批准.正如前面说到的,这是我们接下来改进的方向.
AZTEC协议使用的Solidity版本是0.4.24,因此你在使用OpenZeppelin库时需要指定与之兼容的版本,即2.0.0.
当AZTEC智能合约只有一个用户时,隐私性就会大大降低.由于通过ERC-20通证存入的钱是在区块链上公开可见的,因此第三方可以将其与智能合约持有的总金额进行比较从而大致推测出用户的交易.也就是说,越多的用户加入 AZTEC ,它的隐私性就越好.
以下是在本文中AZTEC协议所使用程序包的详尽清单:
我们的主干程序库monorepo 中提供了所有这些程序的源代码.
如果你喜欢这个教程,或者对隐私交易十分感兴趣,或者想了解更多内容.
可以请查看以下两笔以完全成熟的零知识证明形式,使用一些AZTEC证明转移10个ERC-20通证的交易: