1703867245
1703867246
当然,你可以展示上述公式里的x值来证明你做到了,但是零知识验证可以让你向别人证明你做到了这一点,同时不需要透露x的值,即便在看过你的证明之后。
1703867247
1703867248
你也可以证明一个如“我知道一个x值,而公式H(x)的结果属于下面这一个集合{…}”这样的声明。该证明既没有展示x值是什么,也没有证明集合里面到底哪一个元素等于H(x)。至关重要的是,零币就是利用零知识验证来实现其功能的。事实上,零币中被这种方式证明的声明,与后面要提到的例子非常相似。本书中,我们把零知识验证当成一个黑匣子,只说明了零知识验证可以实现的属性以及在这个协议中的哪个部分是必需的,我们并没有深究如何实现这一功能的技术细节。零知识验证是现代密码学的一个基石,是很多相关技术协议的基础。再一次强调,我们建议有兴趣的读者可以参考延伸阅读中提到的文献,去了解更多更加详细的内容。
1703867249
1703867250
铸造零币
1703867251
1703867252
零币通过铸币过程而产生,而且任何人都可以铸造一个标准面值的零币。为简便起见,我们认为零币只有一种面值,每一个零币价值一个基础币。虽然任何人都可以铸造一个零币,但是产生的零币并不自动具备任何价值——你不可能获得免费的钱。只有把零币放到区块链网络上,并且通过消耗一个基础币的方式,它才能具备价值。
1703867253
1703867254
为了铸造一个零币,你需要使用加密学承诺。回顾一下我们在第1章讲过的内容,承诺方案类似于将一个值放入一个信封,并将信封置于所有人的视野中(见图6.11)。
1703867255
1703867256
1703867257
1703867258
1703867259
图6.11 一个序列号的承诺
1703867260
1703867261
注:密码学承诺好比把一个序列号封装到一个信封里。
1703867262
1703867263
铸造零币的过程分为三步:
1703867264
1703867265
1.生成一个序列号S和一个随机密钥r。
1703867266
1703867267
2.计算一个函数Commit(S,r),这是序列号S的承诺。
1703867268
1703867269
3.如图6.12所示,在区块链上发布该承诺,这需要消耗一个基础币,此币不可再被花费,进而创建了一个零币。此时并S和r仍然是保密的。
1703867270
1703867271
1703867272
1703867273
1703867274
图6.12 在区块链网络上设置一个零币
1703867275
1703867276
注:为了将一个零币置于区块链中,需要创建一个铸币交易,其输出地址是零币序列号的一个密码承诺,而铸币交易的输入则是一个基础币,这个基础币也会在创建零币的过程被消耗掉,整个交易过程并不需要公示这个序列号。
1703867277
1703867278
为了消耗一个零币并赎回新的基础币,你需要证明你之前已经铸造了一个零币,你可以通过公开之前的承诺也就是说公示S和r的值来证明这一点,但是这样显然就建立了一个你的旧的基础币和新的基础币之间的关联,那么我们怎样才能打破这个关联呢?这个时候就用到零知识验证了,在任何时间节点,区块链网络上都有很多的承诺对象——我们将其命名为c1,c2,…,cn。
1703867279
1703867280
以下是消耗一个具有序列号S的零币以赎回一个新基础币的步骤:
1703867281
1703867282
● 创建一个特殊的“花费”交易,这个交易包含序列号S和一个具备零知识验证的声明:“我知道在承诺对象(S,r)中的r在以下的集合里:{c1,c2,…,cn}”。
1703867283
1703867284
● 矿工将会验证你的零知识验证,这将给予你打开区块链中一个零币承诺的能力,而你并不需要真的打开它。
1703867285
1703867286
● 矿工也会查询序列号S,确认这个零币没有在之前的花费交易中被使用过(为了防止双重消费)。
1703867287
1703867288
● 你的花费交易的输出将形成一个新的零币,你应使用你所拥有的一个地址来作为输出地址。
1703867289
1703867290
1703867291
1703867292
1703867293
图6.13 花费一个零币
1703867294
[
上一页 ]
[ :1.703867245e+09 ]
[
下一页 ]