0x00 前言
距离上次发博客有一两个月了,这段时间里潜(ku)心(bi)的看区块链的论文,经过好多好多论文及材料的学习,我发现现在区块链发展的一个很有意义的方向就是匿名性,早的有匿名交易如ZeroCash和monero,晚点的有以太访为了匿名的zk-SNARK不惜进行硬分叉,现在对于匿名合约的研究更是大热。然鹅,作为我天朝区块链项目的执牛耳者,NEO居然咩有匿名相关的任何研究及研发资料或者文档,这不科学。所以我就试着去研究了一下在NEO上部署匿名交易合约的可行性。
0x01 不可能完成的任务
和我之前研究NEO上的任意数量安全随机数的可能性一样,我对于在NEO上部署匿名交易合约的结论也是不可行。先把结论挂出来,只需要结果的就可以不用往下看分析了。
为了亲民考虑,我们完全抛开什么零知识证明之类高大上的东西(其实是没看懂)。有感兴趣的可以参考零知识证明。但是哇,参考是可以的,但是不建议深入研究。这个东西技术细节需要很强的密码学功底,笔者反正是撤了。
0x02 匿名设计
这里我用到的东西是偷的一部分门罗币里CryptoNight构造交易时隐藏用户信息的方法,但是由于这只是博客而已,所以具体用了多少我也不去深究了。
我们先不考虑这些币怎么来的,就说已经存在了。币采用UTXO的形式设计,每个UTXO的结构如下:
对于这个系统里的每一个UTXO来说,Coin记录着币本身的信息,这个信息由用户的公钥进行加密,也就是说,假如这个币是李总的,那么这个Coin里的信息就是由李总的公钥来加密的。每一个Coin本身有一个私钥,这个私钥可以在每次交易的时候重新生成,在交易构造完成后,与通常的使用用户自己的私钥进行签名不同,这里使用目标用户的公钥进行签名,之后再用Coin本身私钥对应的公钥进行签名。在交易发布之后,系统只需要对Coin本身的合法性进行验证即可,不需要关心究竟转账或者传递的数据的内容是多少。
也就是说,假如A转账给B,那么交易构造的流程应该是这样的:
首先A从自己的Coin里拿出一个Coin,然后用自己的私钥解密获取Coin本身的key1,生成新的key2并用这个key2替换key1构造新的Coin,构造完成后用B的公钥来对Coin进行加密,之后再用key1添加签名。
交易发出后,系统会验证key1是否和这个UTXO之前的版本相关联。
0x03 双花导致的不可能性 在上面的设计中有一个很严重的bug,就是双花问题,A知道UTXO,而且可以解密UTXO,那么A就可能构造许多许多的交易,而系统又要求匿名性,那么就不能引入对已有交易的直接判断,那如何即知道这笔钱已经被消费了,而又不知道是花的哪笔钱呢?这里就需要用到零知识证明,在零知识证明中,最简单的解释就是公式:f(x)+f(y)=f(x+y),就是说,我们只知道f(x),f(y)而不知道x和y,但是我们就可以判断出f(x+y)的结果是正确的。在这个系统中,我们可以认为Coin就是x,用户就是y,我们把Coin和用户都通过算法隐藏起来,但是提供两者交互的结果,那么系统就可以验证这个交互的正确性而不需要知道具体的Coin和用户。这样就达到了匿名而又避免了双花问题。然而,在NEO中,NEO并没有对合约开放验证零知识证明需要的密码学计算接口。没有接口也就意味着无法进行零知识证明。因此,至少以目前的分析来看,在NEO合约中部署匿名交易合约是不可能的,除非官方开放相关密码学接口。但是话说回来,零知识证明本身需要的计算量比较大,如果NEO中开放零知识证明的算法接口,那么节点的计算压力将会暴增。
0x04 结语
本文只是笔者一段时间学习结果的小积累,并不一定完全正确,也不代表严谨的区块链研究。如果有人有相关的思路,欢迎交流。