比特币和区块链(2):比特币中区块链的实现
上一篇我们讨论电子货币的时候提出了由一个寡头负责对所有人的电子货币和交易进行记账,记录到只能增加不可修改的账本里,并且把账本公开给所有的人看的这样一个电子货币模式。
这个模式解决了很多的问题。最主要的是电子货币被复制使用的问题。但是这个模式有两个比较大的问题。第一是这个账本怎么实现。第二是一个寡头是不是靠谱。
今天我们重点来讲账本的实现。这个账本的实现其实就是区块链这个名词的由来。可能对懂的人来说节奏有点慢,但是对不懂的人来说,慢工出细活。这篇的内容依然不是很精彩。但是这些仍然是为了讲清楚后面更精彩的内容所必须的准备工作。
下一篇我们将开始讨论怎么样从一个寡头到民主社会的过程。如何达成一致性,如何防止坏人,以及挖矿到底是什么都会逐渐清楚。这篇文章会用到比较多的计算机相关的术语。而我也只能尽力用通俗易懂的方式给大家解释了。 1在一个寡头负责记录,所有人都可以查账的系统里。我们第一个需要解决的问题是,大家怎么确定一笔交易确实是由某个人发起的。比如说,张三发起说给李四付了5块钱。大家怎么能够知道这个交易确实是张三发起,而不是王五冒充的。
这个问题在计算机密码学里被叫做数字签名。我们可以设想一下现实世界里的签名有什么样的特点。一般来说,签名是由特定的人签在特定的文件上的。更通俗一点来说。每个签名应该有如下几条要求:
- 由特定的人签。
- 大家可以辨识。
- 签名附属于特定的文件,坏人无法把一份文件的签名挪到另外一份文件上。
在数字签名的世界里,这些特点也同样需要满足。数字签名通常使用非对称加密算法实现。简单来说,有一个公钥一个私钥。前者用于解密后者用于加密。
如果张三想要发起交易付给李四5块钱,张三可以用自己的私钥对这个交易签字,然后发送给寡头。等寡头把交易写进账本以后,吃瓜群众王二麻子等等都可以用张三公开发布的公钥去验证这个交易是不是张三发起的。
2最早的数字签名算法叫RSA,是以三个发明人的首字母命名的。这三位也同时获得了计算机科学界的最高奖图灵奖。RSA算法主要基于大质数分解问题。这个算法自诞生以来几十年时间里被广泛的检验,简单来说,里面有无数的坑。要实现一个安全可用的RSA,需要很多的技巧。即便如此,它的安全性还是受到各方面的质疑。
而比特币使用的数字签名算法是椭圆曲线算法,而不是目前常用的RSA。这个算法目前为止还没有好的破解方式,哪怕是针对特定情况的。这是非常安全的一个数字签名算法。
在数字签名的使用上,我们还有一个问题没有解决。这些数字签名的公钥是怎么样发布出去的。比特币采用了一个非常聪明的机制。这个机制也同样适用于我们这个一个寡头负责记录所有交易的简化版的系统。简单一点来说,比特币系统认为,一对私钥和公钥代表了一个人。
尽管我们知道在背后无法杜绝一个人使用多对私钥和公钥,而一对私钥和公钥也可能被多个人使用。但是在比特币系统里,每个独立的个体是以不同的私钥和公钥对来区分的。私钥自己藏着不可见,而公钥就成了这个人的身份证号码和地址。所以,如果各位有玩过各种加密货币,钱包的地址是一串杂乱无章的字符串,这个其实就是椭圆曲线算法产生的公钥。总结一下,比特币系统里,每个参与的客户端把自己的公钥作为地址,参与系统交易。其他人要验证一条消息是否是这个人发送的,只需要拿其地址作为公钥去验证即可。
3下面我们讨论账本的不可篡改问题的实现。我们把这个问题的定义改一下。换个说法就是这个账本如果出现了任何的篡改,任意一个查账的吃瓜群众都可以独立的发现这个账本已经被篡改了。所以账本不可被篡改,在区块链里,实际上是一种保障账本一旦被篡改,大家都可以迅速发现的机制。而不是说账本写进去之后就无法被改变了。
这里需要用到计算机领域的另外一项技术:哈希(Hashing)。用通俗一点的话来说,哈希使用一个哈希函数,对一段输入的东西生成一个输出的东西。这里我们需要用一下中学数学的一些知识。
如果y=f(x)是一个函数的话,x的取值范围是定义域,y的取值范围是值域。对于任意一个在定义域里面的x,值域范围内有且仅有一个y对应。但是,对于不同的x,可能会对应到相同的y。这种现象在哈希里面叫做冲突(conflict)。
密码学上的哈希有一些要求。这里我们还是以比特币使用的哈希函数SHA256为例来说明这些要求。SHA256通过一系列复杂的数学变化,对输入的任意长度的文本,生成256比特大小的输出。
这个函数有很多的特殊性,我们先来看第一点:冲突必然存在。因为值域是256比特固定大小的输出,而输入是任意长度的。所以值域其实是定义域的真子集。定义域的大小比值域要大。根据鸽洞原理,10只鸽子,9个鸽洞,必然存在一个鸽洞里面至少有两支鸽子。如果值域是定义域的真子集,冲突必然存在。
4但是所有密码学上的哈希函数,包括SHA256满足如下几个特点。这几个特点构成了区块链技术检测篡改的核心。
第一点,给定x算出y不是一件特别困难的事情。对于SHA256来说,如果我们给定输入,得到256比特的输出,是一件计算上相对很廉价的,只要文本不是太夸张,1秒以内肯定大部分计算机应该能算出来。
第二点,仅仅给定y,找到能够生成y的x候选者,是一件计算上几乎不可能的事情。考虑一下函数y=x+1,对于这种函数来说,每个y算出可能的X候选者是很容易的。SHA256不同,如果仅仅知道y要推算出可能的x,只能靠近似穷举的办法。也许运气不好几百年也不一定能找到一个合适的x。
第三点,对于相邻的x,产生的y的距离是很随机的在y的值域里的。这句话通俗一点讲,也就是说我们无法通过对有限对x和y值的研究去推测出一个新的x可能会产生出什么样的y来。
这几个特点结合起来,我们就有了这样的一个现实的应用。我们可以公布系统使用的哈希函数的细节。然后把y值也公布出去。这样每次不管是谁想要检验是不是某个输入产生了这个对应的y值,只需要把这段输入x用这个函数跑一下,结果出来如果是y,那么大概率就是对的,如果不是y那么大概率就是不对的。用人话翻译一下,就是说真的遇到了另外一个x居然也能产生同样y的概率很低,遇到了只能自己认倒霉了。
所以,如果我们记住了x的哈希值y,又知道哈希函数是什么,当x被篡改之后,只要哈希值y无法被同时篡改,我们就可以很迅速的知道,x是被篡改的。这是区块链防止篡改的基础。
5现在,我们可以给大家介绍区块链是什么了。区块链是一个单项链表。它由若干个连接的区块构成。每个区块包含了若干条交易记录,还有一个表头。表头里面存了很多东西,但是对于我们理解来说,最重要的是两个:1前一个区块的地址,2前一个区块的哈希值。这个区块链就是这个不可篡改的账本了。而区块链的第一个区块的地址和哈希则被发送给系统里面 每一个成员。
系统刚开始的时候只有一个区块:如下面所示区块A
A
A里面包含了若干交易记录。这些交易记录都被数字签名了。而A的地址和哈希值则广播给了整个系统里面的所有吃瓜群众。
这种情况下,A如果被篡改,每个吃瓜群众去查账的时候,只要跑一下SHA256就会发现极大概率的情况下,哈希对不上了。所以这个账本被篡改了。吃瓜群众可以拒绝相信这个账本。
那么随着时间的运行,这个系统里一个区块存不下去了,现在我们有了两个区块A和B
A<---B
这个时候,B的表头记录了A的哈希和地址。而B的地址和哈希被广播给了所有的吃瓜群众。我们知道如果B被篡改了,那么B的哈希值和吃瓜群众手里的哈希值就无法对应了。假设B没有被篡改,那么A被篡改了会怎么样呢?
B里面存了A的哈希值,所以吃瓜群众也可以顺着链条发现A被篡改。那么我们是不是可以同时篡改A和B表头的A对应的哈希值呢?答案当然是不可以。因为篡改了B表头的哈希值,等同于篡改了B。这个被篡改以后的区块算出来的哈希值,和吃瓜群众手里拿着的哈希值是不一样的。
如果系统继续扩张,有了A, B, C呢?
A<---B<---C
道理是一样的,只要吃瓜群众手里拿着原始的C的哈希值,那么寡头的任何篡改都是没有希望不被发现的。当然如果哪天计算机科学发展到了一定程度,或者数学上证明了SHA256不安全,寡头可以伪造出另外一个区块,使得它的哈希值和吃瓜群众手里拿着的原始的C的哈希值是一样的,那么整个系统就再也不安全了。
6下面这段内容,如果没有计算机背景可以略过。
在比特币的区块链系统里。每个区块的交易记录是存成为一颗二叉树。二叉树的叶子节点是每条交易记录,上面的每个父节点的左右指针分别指向左右子树。但是这个二叉树和我们平时常用的二叉树有一点不同,它不但保存左右子树的地址,同时也保存左右子树的哈希值。这种树叫做Merkle Tree。
Merkle Tree的一个重要特点是可以在O(Log n)的时间复杂度里检验一笔具体的交易是否被篡改。O(Log n)的复杂度什么意思呢?简单来说,如果一个区块里面存了2的100次方交易,那么计算机系统大致上只需要做100次的哈希比较,就可以确定一笔具体的交易是否被篡改。这是非常高效的算法。
但是Merkle Tree只是交易记录在区块内的一种存储形式。它是密码学上常用的一个数据结构。也是比特币的发明者中本聪选取的。这并不代表着我们必须,只能用这种结构去存储区块里面的交易。
7我们来总结一下今天的内容。今天主要讲区块链这个不可篡改的账本是什么。
我们首先讲了数字签名技术。数字签名由私钥和公钥对组成,使用者用私钥签名,公钥在比特币系统里面是每个参与者的身份号码和地址。任意的人可以通过公钥去确认一笔交易确实由某个特定的人发起。比特币使用椭圆曲线数字签名算法。
我们接下来讲了密码学上的哈希。密码学上的哈希的特点是从输入x算出输出y很容易,从输出y找到可能的输入x很难,哈希函数对相邻的x的值域y很散,通过已知的若干对x和y的关系,在给定新的y的情况下,去寻找新的x也是没有任何帮助的。穷举法几乎是唯一的寻找特定的y对应的输入x的办法。而以今天的计算机能力,穷举法需要漫长的时间。所以,y可以作为验证x是否被篡改的标记。比特币使用SHA256哈希算法。
我们接下来讲了区块链的结构。每个区块存了若干交易记录。区块们从老到新链接起来,后一个区块记住前一个区块的地址和哈希值,而表头最新的区块的地址和哈希值则广播给所有在网络里的人。我们证明了,因为在网络里的人手头的哈希值无法被篡改,所以任何针对整个区块链的篡改都会被吃瓜群众发现。
最后我们讲了区块链内交易记录的存储。在比特币的区块链里,用的是改良的二叉树Merkle Tree。它提供了O(Log n)的时间复杂度去检验一条具体的交易是否被篡改。
顺便提一下,山寨币和比特币的不同,其中一部分就体现在区块的大小,哈希函数的选择等等。但是这篇文章主要讲述比特币的技术实现,我们就不再比较其他的了。
下面我会开始讲分布式一致性的问题,也就是比特币如何去除这个寡头的问题。
有读者问本人对数字货币的态度到底是什么。简单一点说,我拿身价5%的钱投资数字货币。投资组合里以大币为主,小币则按照我自己对区块链技术的理解选择。理解体现在小币使用的区块链技术的各个方面是否靠谱。本公众号的任何文章都只代表个人观点,不构成投资建议。
转自:飞总聊IT