摘要:本文记录 Princeton 大学 MOOC 比特币与数字加密技术(BCT,Bitcoin and Cryptocurrency Technologies)的相关学习笔记。力求从代码层次深入的探讨原理。
参考:
- 比特币与数字加密技术 该笔记系列目前第一周比较完善,供参考。
- 学习笔记 该笔记进行了概要的介绍。
第一周的课程主要是介绍如下几点内容
- 哈希函数
- 哈希指针和数据结构
- 数字签名
- 公钥身份体制
- 简单加密货币设计
本课程目前广受大家欢迎的原因应该是理论和实际紧密相连,理论学完马上就会进行编程实践。
哈希函数
通用Hash 函数的3个基本性质
- 输入是任意长度的字符串
- 输出是一个固定长度的串,比如 256bits
- 计算高效 (efficiently computable )。具体来说,对于一个输入为 n-bit的串计算时间应该是 O(n)
足够安全的哈希函数:
- collision-free : 无冲突
- hiding: 隐藏
- puzzle-friendly
关于特性可以参考该博文:
无冲突
这里的无冲突是相对而言的,或者在概率学角度无冲突。
通过无冲突特性,我们可以根据哈希值相同从而推断原数据是相同的。其实这也是使用哈希进行摘要的原理,比如 MD5 摘要被广泛应用于文件下载校验是否被恶意篡改。
隐藏
原数据无法通过哈希函数和散列值反推回去,所以元数据被哈希函数隐藏起来了。
puzzle-friendly
难题友好性指的是没有便捷的方法产生一个满足特殊要求的哈希值。可以定义为:一个哈希函数H称为难题友好的,如果对于每个n位的输出y,若k是从一个具有较高不可预测性(高小熵high min-entropy)分布中选取的,不可能以小于2^n的时间找到一个x,使得H(k||x)=y。这意味着如果有人想通过锁定哈希函数来产生一些特殊的输出y,而部分输入值以随机方式选定,则很难找到另外一个值,使得其哈希值正好等于y。
哈希函数的难题友好性构成了基于工作量证明的共识算法的基础。例如,给定字符串“blockchain”,并在这个字符串后面连接一个整数值串x,对连接后的字符串进行SHA256哈希运算,要求得到的哈希结果(十六进制)以若干个0开头。按照这个规则,由x=1出发,递增x的值,我们需要经过2688次哈希运算才能找到前3位均为0的哈希值,而要找到前6位均为0的哈希值,则需要进行620969次哈希运算。也就是说没有更快捷的方法来产生一个满足要求的哈希结果。这样通过哈希运算得出的符合特定要求的哈希值,可以作为共识算法中的工作量证明。
哈希指针和数据结构
数字签名
关于数字签名可以参考另外两篇博文
公钥身份体制
简单加密货币设计
Groofy Coin
这是教程提出的一种最简化的数字加密货币。该货币有如下特点:
- 是一个中心化的货币,因为有且仅有
Groofy
能创建货币,其他参与者只能使用货币 - 这里有两种交易
Transaction
类型:CreateCoin
和Pay
。 Groofy
可以产生CreateCoin
交易,需要使用他自己的私钥签名,以保证其合法性,并且每个Coin
都有一个唯一的ID
- 任何参与者都可以产生
Pay
交易,同时需要使用自己的私钥签名,以保证其合法性。 Pay
是关联两个参与者的,Pay
的创建者需要使用自己的私钥签名,而 Pay 的收款方则使用公钥来表示。- 任何人在收到
Coin
之后都可以验证每一个Coin
是否是合法的。验证方法就是根据交易的指向前一个交易的指针追溯,知道找到由Groofy
使用自己私钥签名的CreateCoin
的交易。这里理论上需要有一个CA
,用来验证整条链上的参与者的公钥的合法性。只要公钥合法,就可以验证交易的合法,从而确保Coin
的生成过程是合法的。
综上,由于该货币是中心化的,我们可以用我们现有的实体货币和支付宝进行对比分析一下,他们之间有什么不同。
与实体货币对比
实体货币最为熟悉:
- 由国家发行,也就是国家类似于
Groofy
- 货币需要有防伪标志,理论上阻止伪造,类似于
Groofy
对创建货币进行签名 - 参与者(人民)可以根据防伪标志来验证货币的合法性
- 参与者可以使用货币自由交易,也就是
Pay
的交易
区别:
- 实体货币没有公开的交易记录,每个参与者可以自行任意记录,但是没有任何公开可信的记录。
- 实体货币的防伪性不嫩完全杜绝伪造,其验证也就无法做到百分百正确
- 实体货币一旦交易完成,银货两讫,不可能把货币再进行其他交易。但是
Groofy
没有方式杜绝这种情况出现。这里也就是所谓的双花问题 (double-spending)。假设Alice
有一个Coin
,她分别向两个人提出了Pay
类型的交易,比如Pay
给Bob
和Chuck
各一个Coin
,这时候通过链条Bob
和Chuck
都发现这个Coin
是合法的,但是实际上只有一个Coin
。所以我们必须解决这个问题,该加密货币系统(CryptoCurrenty)才完善。
与支付宝对比
如果我们把支付宝看做一种货币
- 由阿里发行,实际上这个货币只存在阿里系统内部,
- 阿里的中心服务器来验证
- 一旦交易完成,阿里服务器保证银货两讫,支付宝余额不能双花
Scrooge Coin
下面就开始针对双花问题进行对 Groofy Coin
进行改造,得到升级版电子加密货币 Scrooge Coin
。Scrooge Coin
的规则是在现有 Groofy Coin
上进行扩展,所以所有 Groofy Coin
的规则都适用于 Scrooge Coin
。
首先我们简要的说明一下解决双花问题的思路:Scrooge Coin
使用交易历史记录来去检测 double-spending
问题。类似于检测 Coin
的合法性,同样通过交易的链条能够检测每一笔 Pay
是否合法,如果参与者收到一个 Coin
,除了检查Coin
是否合法,还要检查 Pay
是否合法,也就是查看这个 Coin
是否已经出现在发送者已有的 Pay
交易中。
扩展规则如下:
Create Coins 规则变更
Scrooge
可以在一个Transaction
中创建多个Coin
,这里Coin
有价值,价值不再是离散的了,而是连续的,而且每一个创建过程可以创建若干价值的一个Coin
。我们姑且称之为货币创建记录,每一个创建记录有:编号(num),货币价值(value)和一个收款方(或称为初始拥有者 initial owner)的公钥(recipient)。一个交易里面可以有多个这样的创建记录。这个扩展规则,除了可以一次创建多个货币外,还可以直接指定收款方,后面一个操作在Groofy Coin
中实际是另一个Pay
类型的Transaction
完成的。- 通过上面的创建,
Coin
的ID
并不是在Groofy Coin
中指定的,而是通过Transaction
的ID
和 创建记录的编号(num)的组合来唯一确定。比如交易记录为 73,那么编号为0的创建的Coin
的ID
就是73(0)
Pay Coins 规则变更
这种类型的交易和之前的已经完全不同,这里我们根据教程总结如下几点
- 该类型的交易目标是消费
Coins
并销毁这些Coins
,同时创建相同总价值的Coins
。和之前的相比,这里没有直接将原来的Coins
转给其他参与者,而是先销毁,再创建,并在创建的时候指定其他参与者的公钥。 - 教程给了一个案例,这里大家一定不要和前一种类型的交易混淆,虽然两者的数据是一样的,而且ID是一样。这次的创建是因为进行了
Coins
的Consume
。而前面CreateCoins
类型的交易是Scrooge
自发的创建了货币。意义是不同的,不知道其他人是否有一样的误区,自己之前一直和前面的类型混淆。
案例:本次交易号位 73,类型是:PayCoins
。这次交易共消费了三个 Coins
,分别是 68(1),42(0),72(3)。说明有3个其他的交易的Coin
创建的 recipient
指向的是当前用户。这三个 Coins
被消费并被销毁,然后我们增加若干个 Coin
,并使其总价值和这三个 Coins
相同,并且指向消费对象的公钥。最后是签名,这个签名也不仅仅是一个,而是多个,是所有在这次交易中付出了 Coins
的参与者共同的签名。
最后讨论了一下关于 Coins
可变的问题,Coins
一旦创建,其价值就是不可变的,那么如何灵活的 Consume
其价值呢?可以通过 Transaction
来实现目标,我们可以在消费销毁 Coins
后,通过创建不同的新的 Coins
的组合来实现价值的在分割。比如我们可以在上面例子用将 72(3) 这个 Coin
分割成两部分,一部分给其他参与者,一部分可以指向原拥有者,从而达到只消费了某个 Coin
的部分价值。
教程中只显示了一个 Transaction
的数据结构,而且个人感觉,对于 Coin
的 Consumer
并不明确。下面我们对该案例延伸,相信通过该图就能够深入的透彻的连接这个 PayCoins
类型的交易。
参考下图:
缺点
依赖于 Scrooge
的诚实可信,以及其持续的参与。一旦 Scrooge
不在诚实,或者退出整个系统,则该电子加密货币无法继续维持。
所以我们下一步就是要研究如何将加密货币系统进行去中心化!