程序员

原汁原味科普比特币(中)

2018-03-23  本文已影响0人  shengofbig

维持人群账本的一致

接下来我们看如何使分散在世界各地的计算机节点维持账户余额保持一致。

回到最开始的理想模型,大家的记账过程是这样的:

也就是说,从一个空的账本开始,在每一笔交易产生的时候,大家都同时把交易追加到自己的账本的同一行上。如果这种行为可以一直维持下来,那么每个人余额是多少,以及谁给谁转了多少钱,自然会一直保持一致。

这种做法有点像我们小时候被老师听写生字:

在最开始我们也分析过,这种“听写”的模式是无法适用于计算机世界的,这里再次重温下原因:

如果非要用“教室课堂”的模式类比,比特币系统有点像一场奇怪的听力考试:

如果我们深入去思考这场“诡异的考试”,一定就会为它难到“急火攻心”。乍一想,我们也许可以指定某个人是单词唯一的来源,但我们很难保证他的耳机里会一直放单词。为保险起见,还是每个人都可记录并传播单词,并且找一些规则来维持笔记本内容的一致为妙。

那么我们就需要静下心来想想,阻止我们就“笔记本内容达成一致”的最大阻碍是什么?主要原因在于:同时产生并传来传去的单词太多了,大家不管记自己的,还是抄别人的纸条,都会有一种手忙脚乱的感觉。如果每个时间段内只有一个单词产生,那么大家记起来就容易多了。

换句话说:只有降低单词产生的速度,才更有可能让大家达成一致。为了达到这一目标,我们可以在考试系统中先引入规则一

道理也很简单:虽然大家都可以快速记下单词,但运气总不会一样好。在掷骰子的约束之下,单词的产生速度会瞬间慢下来。最理想的情况:

可这么做有个很明显的问题:记单词的速度太慢了,最后会影响总分的。为了解决这个问题,我们引入规则二

那么收到别人的整页单词后,纸条的接受者该怎么做呢?我们引入规则三:

有了三这个规则,我们可以在脑子里过一下整个考试的过程:

好,假设这样的方法是奏效的。但不可避免的,到某一页的时候,突然A和B两个人先后都掷出了六,也都开始传播自己的该页内容。很快的,这两份答案蔓延到了班级的每一个同学手中。此时,大家要么有A的那一份,要么有B的那一份,要么两份都有,分歧产生了

在这种情况下,我们需要引入接收者对答案验证的规则四

在这一规则下,每个人手上的答案不会有两份答案。无论是A的那份还是B的那份,谁的先到他们手上他们就选谁的。

有了这一规则,尽管每个人不会拥有多份答案,但就整个集体而言,两个帮派还是不可避免的形成了。他们就“最近一页内容是什么”这一问题而相持不下。


分成了不同帮派

为了避免这一局面,我们需要再次引入一个新的规则。

在介绍下一个规则之前,我们先搁置争议,用发展的眼光来继续审视下这场考试。尽管帮派已经产生,但班级里的每个成员仍在继续热火朝天的进行着“写单词-掷骰子”过程。在某个时间点,又有新的一页产生了,这页内容也会和任何其他页一样,迅速在班里扩散开来。当这页扩散到另一个帮派时,我们的规则五就会起作用了:

规则五其实给传纸条悄悄引入了一个新的约束:大家在传播纸条时,传播的根本不是某一页内容,而是一整个笔记本。因为不传播整个笔记本,没法对前面的内容进行对比。

当然,这样的传答案方式在你看来可能极其搞笑:把别人的一整本笔记抄下来传纸条似乎会慢的可怜,对整本笔记逐行对比时也算苦逼到家了。这两个问题并非不可以解决,我们后面会再次回过头来看这个问题。这里,就让我们暂时无脑的假设“传整本笔记”是可行的。而且,我们也可以“鸵鸟心态”的更彻底一些:

有了规则五之后,即便班级里暂时分成了两个帮派,也不再是一件非常头疼的事了。所有的分歧都是暂时的、不稳定的。随着笔记页数的持续推进,一定会有一方产生比别人都新的答案,这份更多的答案会在传播中慢慢把别的帮派吞并掉,最后整个班级归于一致。再朝深一步想就是:在最近一页或几页的内容上大家可能会有不一致,但一些比较靠前的页面,大家基本上是会保持一致的。

如果把上面“考试答题”的过程映射回比特币系统,我们大体就可以知道比特币维持系统一致的雏形方法了。

区块链

在前面介绍“页数多的胜出”这一规则时,为了保证其有效实施,我们要求班级学生在传播答案的时候,要传播“整个笔记本”。之所以要这么做,是为了大家在接受最大的页面内容时,可以检验并维持前面内容的一致。

还拿100页的例子说事。假如仅仅只传递新生成的第101页,收到该的人无法验证“自己的第100页”“收到的101页的前一页”内容是不是一样;同理,也无从验证“自己的第99页”“收到的101页的前两页”的内容是不是一样;依次类推,前面的每一页也无从验证。而传播“整个笔记本”,从物理上保证了全部内容的连贯完整性,从而也给了内容验证以强有力的保证。

那么,我们能不能找到一种更快速有效的方式来进行笔记本内容的验证呢?

答案是可以的:只要我们能对班级中产生的每一页单词笔记进行唯一的编号就可以了。我们在描述一页的时候,不能仅仅说“第x页”,而是应该说“xxx产生的第xxx页”。更精确一点,如果用“学号+页号”的方式来编码,我们就可以避免传播整个笔记内容了。

例如,当X产生出第101页时,或者他收到别人新发来的第101页时,他只需把这一页的完整内容抄成纸条传播即可;而对于所有的前序页,他只传播页的编号即可。


X要传播的第101页

W在收到X的纸条后,如果自己的内容不少于101页:

值得强调的是,W和X页面不一致的地方,一定是发生在W的尾部的。也就是说,两人的页面内容,一定是从某一页开始“分叉”的;交错式的不一致,在我们的协议里一定式不会发生的。这里我不打算对原因展开做解释,有兴趣的读者可以自己想一下原因。


分叉型不一致 vs 交错型不一致

有了“页面编号”的概念后,我们的纸条传播规则可以再进一步的简化:每次只传播新产生的一页,并且把它的前序页也一起写到该页的纸条中去。也就是说,每一页纸条的格式是这样的:

页面格式

接收者只需要按照页面前一页组成的链条“顺藤摸瓜”解决冲突就好了。

在比特币中,每个“区块”都会记录其前一区块的编号,从而使得系统中所有的区块都串到某一条固定的链上,就像一个完整的笔记本一样。这样的链就叫做区块链。每个记账人手中的账目,就可以对应到系统中的某一条链中。“最长的链”,就是维持大家账目一致的核心秘密。

有了这个概念后,我们就可以回答下“A给B转账,B如何确认收到”的问题了。B无需向系统中的每个节点进行询问(事实上,B也做不到向每个节点询问),他只要耐心的等待A向他发起的那笔交易被串在链中比较靠前的地方就好了。在比特币中,如果一个区块后面又接了五六个区块,就可以确认交易了。

数字摘要

在上一节中,我们给“考试模型”中的每页纸条引入了一个非常重要的概念:唯一的页编号,也给了“学号+页码”这样一个简单的编号规则。在比特币系统中,每个区块也的确有个“唯一编号”,但是其编号规则却大不相同——其规则叫“数字摘要”。

所谓“数字摘要(也叫数字指纹、密码学哈希)”,是这样一种技术:它可以把给定的普通的电脑文件快速转化成一段固定长度的数字串(严格来说:是16进制数字串),这个数字串就叫做原来文件的数字摘要。并且,这种数字串满足三种性质:

  1. 无论两个文件内容多么相似,他们生成的数字摘要也是大不相同的。而如果两个文件完全相同,那么他们的数字摘要也一模一样。这种特征保证了:一旦一个文件发生了极微小的改动,我们也能通过其摘要快速发现。而不用把源文件的内容进行完整比对
  2. 对于一个给定的文件,你想创造一个新的文件和它有相同的数字摘要,是非常困难的。这种特征保证了:你无法随意伪造一个新的文件来把原来的替换掉
  3. 你难以构造两个文件,使得他们有相同的数字摘要。这种特征保证了:如果你在一个系统中持续的产生新的文件,你可以通过摘要这种技术给不同的文件进行“编号”
    数字摘要技术

数字摘要的这些性质,就跟我们的指纹一样,是我们每个文件独一无二特质的一种证明。如果用人的观点来看这三种性质就是:

  1. 哪怕你是双胞胎,你们的指纹也不相同。
  2. 你想找一个人和你自己的指纹一样,这几乎是不可能的
  3. 你想从人群中抓两个人,让他们的指纹一样,这几乎也是不可能的。

在比特币系统中,区块的“唯一编号”就是它全部内容的数字摘要,而之所以能这么干,就是利用性质3。

数字摘要的引入,也给比特币的账本带来了一个有趣的特性:修改链上任何一个区块的任何内容,必须得顺带将所有后续区块做改正。因为根据性质1:

所以,记账人想改了某条账本且仍旧想维护账本的有效性的话,必须得将所有后继都做一遍改动。现在请大家默默记住这一平平无奇的特性。待后面引入其他一些规则后,该特性将成为比特币系统坚不可摧的最重要基石。

简单小结

到此为止,我们在不考虑“拜占庭问题”的前提下,构建起了保证各节点账本一致的基本方法:

  1. 收到交易时,验证交易的合法性。
  2. 把多个交易打包成一个区块,掷骰子到合适点数后再广播区块,从而减少冲突。
  3. 收到别人发来的区块后,接受合法的区块,且继续广播,加速区块在系统中的传播。
  4. 对于相同深度的区块,只接受最先到达的。
  5. 当接受一个深度更大的区块时,顺藤摸瓜地检测前序区块,产生冲突时丢弃自己那份
  6. 为了支持5,每个区块用数字摘要来给区块编号,且在每个内部记录自己的前序区块

上:原汁原味科普比特币(上)
下:原汁原味科普比特币(下)

上一篇 下一篇

猜你喜欢

热点阅读