【基础篇】理解区块链的结构设计机制

国内目前已经有众多关于区块链、比特币等的新闻和文章,但大多只是粗浅的讲述了“区块链是去中心化的分布式账本”等概念,且在去中心化、加密货币等方面大做文章。“三点钟区块链微信讨论群”和众多大佬类似娱乐圈般的加入和讨论更是增添了新的一把火。

对比国外在区块链技术原理、技术改进和内在逻辑等的讨论,国内的新闻媒体、大佬和所谓的三点钟区块链群等,还多集中在绿皮火车化的讨论,一些深层次的讨论文章实在是少之又少。

当一群人在狂欢于三点钟区块链讨论群时,我却觉得以下评论很好的概括了其观点和内容,个中含义可以细细体会。

1、技术讨论阶段:XX最初甩出了几个偏技术类话题,涉及TPS、UTXO等,比如以太坊的对手会是什么样的项目之类。这激发了一些有实操经验的数字货币的专业投资人、媒体人、以及程序员加入话题:此时,周围围观的各路大佬们看着热络的气氛,却硬是插不上话,似乎有点着急,但大佬到底是大佬,话锋一转,把以太坊的“对手”一下甩到了币圈之外的监管上,自此逐渐进入了他们如鱼得水的话题领域:

2、投资讨论阶段:大佬加入之后,有关区块链的话题开始被掰向投资、募资等领域。上一阶段的区块链从业者发言频率逐渐降低,群聊气氛VC化。

3、家国大事阶段:再后,群聊风向再变。话题开始转向“数字货币在金融中的作用”,比如货币、外汇等等,各位读者如果参加过各类线下聚会的话,对这类话题一定不会感到陌生,此时的群聊气氛,已经开始绿皮火车化。

4、工业历史阶段:再后来,群聊方向开始转到区块链对生产关系的改造上。群聊气氛哲学化。

以上。

我每每在回顾并感慨区块链近几年的快速发展时,总是在思考:如果我是中本聪的话,当初为何会想到要提出区块链的概念?我为何会引入哈希(Hash)函数、创造比特币呢?又为何会想到用PoW的共识模型和方法?最后,怎么把上述几个概念结合成一起,形成区块链的逻辑?

以下的正文均是依据上述的逻辑展开的。

需要提醒的是,以下的正文需要对经济、数学有一定的了解和兴趣,尽管问题是“如何简单易懂的介绍区块链”,但是,对于区块链这样一个复杂又有意思的新事物而言,仅用活泼的语言和简单的例子来解释,尽管对于普通读者可以达到简单易懂的作用,但是要想真正的理解区块链的原理和实现的机制,不了解背后的理论,绝对是远远不够的。

下面进入正文。

一、中心化的Electronic Cash System

对于一个电子现金交易系统(Electronic Cash System)而言,常见的交易情景如下:

A现在要去购买一台电脑,并支付1万元给商户B。

1. A的账户里有1.5万元;

2. A将自己账户里的1万元通过网络发送给B;

3. B确认A发送的这笔“电子现金(Electronic Cash)”真实无误后,将电脑给A;

4. 最后,A账户里只剩下5千元,B账户里增加了1万元。

如果是线下交易,A和B之间“一手交钱、一手交货”,B能轻而易举的验证这笔钱的真实性,然而对于上述的电子现金交易,最明显的一个问题为:(1)B无法确认A这笔电子现金是否是真的,即A的账户里是否有足够的1万元来支付;(2)A账户里支付给B的1万元之前是否已经支付给了其他人C,即“双重支付(Double-Spending)”的问题。

通常,为了解决这个问题,现实中往往引入一个值得信任的第三方(往往是政府、银行等机构),来担当中间人的身份。此时的交易情景如下:

1. A向银行账户里存入1.5万元现金,银行会在A的电子账户中增加/“发行”1.5万元的Electronic
Cash;

2. A将自己账户里的1万元Electronic Cash通知银行发送给B;

3. 银行确认A发送的这笔Electronic Cash真实无误,支付给B;

4. B确认收款,并将将电脑给A;

5. A账户里只剩下5千元Electronic Cash,B账户里增加了1万元Electronic Cash;

6. 如果A账户里不足1万元Electronic Cash,则银行会提示A付款失败;如果A之前已经把这1万元支付给了C,则银行会提示A存款不足。

可见,作为第三方的银行解决了交易验证及Double-Spending等问题。

那么问题来了:

Q1:如何在没有第三方机构的情况下,解决上述问题呢?更进一步说,是否存在一个去中心化的Electronic Cash System,使得交易双方可以进行直接的点对点货币交易?

二、银行的总账和区块链的总账

银行的做法能为我们提供一个基本的思路,那么银行是通过怎样的办法,解决上述问题的呢?

一般而言,银行自己对每一笔交易都有一本“总账”,在这笔总账上,记录着每一个人的交易记录(收入+支出)、余额、时间等基本信息。每“确认”一笔收入,则加盖相应“时间戳”,对这笔交易做“+”处理;每“确认”一笔支出,则加盖相应的“时间戳”,对这笔交易做“-”处理。因此,每一个人的账户余额,是按照时间顺序进行加减得到的最终结果。

在前述提到的A和B之间的交易情景中,当A需要向B支付1万元的Electronic Cash时,银行把A的账本从“总账”里拿出来进行对比,如果A账本中在考虑了所有已“确认”的交易后,账户余额足以支付1万元,则认为交易无误且支付给B,B银行在收到Electronic
Cash后通知B到账成功,B则可放心交货给A。

银行的做法有几个重要逻辑:

1. 有一笔总账,记录着每一个人的账本,以供查询并对账;

2. 这笔总账只有银行有权利记账(银行是有公信力的机构);

3. 每一个人的账本都详细记录着每一笔交易、相应的时间戳、余额等信息;

4. 只有当一笔交易被“确认”后,才会作为收入/支出记录在账本中。

参考上述银行的做法便可得知:若要解决Q1“去中心化”,核心是有一个

(1)公开透明的、

(2)可供所有人查询并对账的、

(3)记账权力是公平且安全的、

(4)记录了所有人已确认交易记录的、

“总账本”

试想,如果现实生活中有一个满足上述四个条件的“总账本”,此时,A和B的交易情景将会如下:

1. A的电子账户中有1.5万元Electronic Cash,该信息记录在“总账本”中,可供所有人查询;

2. A购买电脑,并将自己账户里的1万元Electronic Cash通知网络发送给B;

3. B查询该“总账本”,验证得知A的这笔钱没有问题,并确认收款;

4. A账户里只剩下5千元Electronic Cash,B账户里增加了1万元Electronic Cash;

5. 如果A账户里不足1万元Electronic Cash,B验证得知后将拒绝A提货;如果A之前已经把这1万元支付给了C,B同样也会验证得知并拒绝A。

可见,如果真的存在上述这样一个账本,那么第三方公信力的机构似乎没有了存在的价值,我们便解决了Q1的疑问:的确存在一个去中心化的Electronic Cash System,使得交易双方可以进行直接的点对点货币交易。

三、哈希函数和公开总账本的安全性

但要实现上述逻辑并不简单,进一步的问题是:

Q2:谁有权利记账? 
Q3:如何保证记账人不会为了自己的利益篡改记录(即如何保证记账人有银行一样的公信力)?
Q4:如何保证账本不被其他人篡改记录(即如何保证账本的安全性)?

而为了保证记录不被篡改,又引出了另一个问题:

Q5:谁有权力对交易进行确认和验证(即证明该交易是真实有效的)?

既然我们要设计的Electronic Cash System是去中心化的,显然我们不能把记账的权力交给某一个第三方,所以一个容易的推导是:

所有人都可以记账,任意一笔记账都需要绝大多数人进行确认和验证,且只有在绝大多数人同意的前提下才能被认为是真实有效的(即达成一致consensus)

我们可暂且将这个推导具体的技术原理放在一边,但如果这是能做到的,那么问题Q2和Q5也就解决了。在这个前提下,我们又该如何解决问题Q3和Q4,即如何保证历史记录不被篡改呢?

保证历史记录不被篡改,有两个容易想到的思路:

一是给历史记录加上一把复杂的密码锁,任何人要修改账本的历史记录需要解开这把锁。这个思路的前提是,这把锁不会妨碍人们对历史记录的查询和验证,且不会妨碍人们添加新的交易记录(即新的记账)。这个思路的缺陷在于,这把锁的钥匙归谁保管呢?

第二种思路是,但凡有人对历史记录的进行了修改,哪怕只是一点点修改,都会被人们发现且拒绝。同时,对历史记录的修改的需要花费的成本巨大,且随着时间的推移越来越大,大到普通的人无法承受。这个思路的缺陷在于,你永远都不知道富人究竟有多富。

数学家们对这个世界做出了无比重大的贡献,而此时他们发明的“哈希函数”将在我们的Electronic
Cash System中发挥巨大的作用。先简单介绍一下哈希函数:

哈希函数,一般也叫做散列函数,是把任意长度的输入变换成固定长度的输出,该输出就是散列值。简单地说,就是一种将任意长度的消息压缩成某一固定长度的信息摘要的函数。

一个良好性质的哈希函数h必须具备以下特征:

1. 任何大小的数据分组,h函数都能产生固定长度的输出

2. 对于任何给定的key,h(key)要相对容易计算

3. 单向性:指的是其操作方向的不可逆性,即只能从输入推导出输出,而不能从输出计算出输入。即:已知key1,可以计算出h(key1)=h1;但已知h1,找到对应的key1,在计算上不可行。

4. 碰撞约束,也可分为弱抗碰撞和强抗碰撞。所谓弱抗碰撞,指的是对于给定的key1,寻找不等于key1的key2,使得h(key1)=h(key2)在计算上不可行;所谓强抗碰撞,指的是寻找任何的(key1, key2)使得h(key1)=h(key2)在计算上不可行。

上述提到的“在计算上不可行(Computationally Infeasible)”意思不是不可能,而是很难,或者说在有限时间内计算不可能。

目前常用的HASH函数主要有两个系列,MD和 SHA系列。其中,MD系列主要包括 MD2,MD4,MD5,但这类HASH函数已经被证实不够安全(我国山东大学教授王小云在有限的时间内成功地破解了MD2和MD5算法)。SHA系列主要包含SHA1和 SHA2(SHA224, SAH256, SHA384,SHA512)系列,其中224,256,384,512都是指其输出的位长度。目前大多数应用场景推荐使用SHA256以上的算法。目前以超级计算机的算力,产生比特币SHA256哈希算法的一个哈希碰撞大约需要2^48年。

假设交易的历史记录为key1,哈希函数的上述性质告诉我们,很难找到一个不等于key1的key2,使得h(key1)=h(key2)。这也意味着:

(1)对于key1的任何变动,哪怕是一点点,都将使得哈希值/输出值与原输出值h(key1)完全不相等或者差异巨大;

(2)如果后一个哈希函数的输入是基于前一个哈希函数的输出,那么,如果要修改任何一个时点的历史记录,就要把前面所有时点的历史记录及其对应的哈希值都进行修改,并找到相应的哈希碰撞,而哈希函数的性质告诉我们,这在计算上是相当难实现的。

基于以上,我们很容易想到,这个性质如果能应用到我们前面提到的第二种思路,那将是非常完美的。如果能把某一时点的交易记录进行哈希,且该哈希的输出是以后时点的交易记录哈希的输入,这就意味着,不同时间点的交易记录之间将通过哈希进行紧密联系,任何一处的变动不仅将改变其自身的哈希,还会改变以他为参数之一的后面交易记录的哈希。也就是说,对历史记录的修改将随着时间的推移越来越难、成本越来越高。

四、推理出区块链结构

因此,我们很快能推导出区块链结构的初步框架:

1. 以块为单位,每一个块Bn需要至少包含以下内容:

(1)块对应的时间即“时间戳”tn

(2)包含的所有交易记录TXn

(3)上一个区块的哈希值B(n-1)。

即:Bn=H(tn, TXn, B(n-1)),
其中H(key)是对Key进行哈希。

2. 由于交易记录众多,为简化交易记录的输入且同时保证交易记录的安全性,我们可以对交易记录哈希。

一个巧妙的方法是以“默克尔树(Merkle Tree)”来验证并记录交易。Merkle Tree也称为Hash Tree,本质是存储哈希值的二叉树。从下图可看出,Merkle Tree的每个叶子节点是每个交易信息的哈希值,往上对相邻的两个哈希值再哈希,一直到顶部只剩下一个节点,称为Merkle根。将数据以Merkle树的方式存储的好处是,可以单独拿其中的一个小分支对部分数据进行验证,而无需对所有数据都进行审阅,提高效率。

《【基础篇】理解区块链的结构设计机制》
《【基础篇】理解区块链的结构设计机制》

由此可见,我们只需要把每一个区块中所有被包含交易的Merkle根计入哈希函数,即可包含所有交易数据。

即:Bn=H(tn, Merkle-n, B(n-1)),
其中Merlke-n=H(TXn)

3. 至此,还有一个需要解决的是,怎么来分配记账的权力呢?也就是说,基于什么原理来决定由谁记账?

前面曾提到过,既然我们的设计方案是去中心化的,显然不能将记账的权力交给某个单一的第三方,但即使是所有人都有权利记账,也依然需要解决每一笔账具体由谁来记的问题(因为不可能每一笔账都要所有人来参与,那将太麻烦也没效率)。

比特币区块链的做法是,每一个区块对下一个区块的哈希值有要求(成为“目标哈希”),需要下一个区块的哈希值不大于某个规定的数,而根据前面的公式,Bn=H(tn, Merkle-n, B(n-1)),计算出来的Bn不一定能满足前一区块(也称“父区块”)的要求。此时,在函数中引入一个随机数nounce,让所有人“公平”地去寻找这个随机数,谁找到了这个随机数谁就获得权力进行记账,而找到这个随机数的唯一方法在数学上只能通过穷举,也就是谁的计算速度快,谁就能先找到这个随机数。为了补偿使用算力造成的成本,这个账本将会凭空生出一个“代币”——比特币(Bitcoin)——发放给运行算力的“旷工”。以上过程就是“挖矿”和“奖励”,而该过程被称为工作量证明(PoW,Power of Stake)。

基于此,我们进一步得出:

Bn=H(tn, Merkle-n, B(n-1), nounce),

其中,Merlke-n=H(TXn), nounce是随机数,

即找到nounce,使得Bn<目标哈希。

五、画出区块链结构

基于前面的函数,我们基本可以清晰的画出区块链的结构(如下图)。我们把区块链分为两部分,分别为“区块头”和“区块体”,区块头包括了前面提到的所有参数,例如前一区块的哈希、时间戳、随机数、目标哈希和Merkle根;区块体则包含了具体的交易数据和交易数量,其决定了区块头中的Merkle根。

《【基础篇】理解区块链的结构设计机制》
《【基础篇】理解区块链的结构设计机制》

《【基础篇】理解区块链的结构设计机制》
《【基础篇】理解区块链的结构设计机制》

根据http://Blockchain.info提供的信息,第512352个区块如下。下图左边一栏显示,该区块中包含1669笔交易,时间戳(Timestamp)为2018年3月7日2点52分27秒,由http://BTC.com进行记账。该区块大小为1099.549kB,随机数nounce为1152756558,旷工得到了12.5BTC的奖励。右边一栏的前两行显示了该区块的Hash值以及上一区块(即父区块)的Hash值,第三行要求下一个区块的Hash不得大于

00000000000000000011d9deb41bfd546610de982fcbedfa251b52e2eec8719c,最后一行显示了该区块交易记录的Merkle根。

《【基础篇】理解区块链的结构设计机制》
《【基础篇】理解区块链的结构设计机制》

至此,区块链的结构设计工作已经有个基础模型了。

到这里,基本上就能理解:

(1)为什么会创造出区块链

(2)为什么会把区块链和哈希函数结合起来

(3)区块链结构设计的逻辑

以上三个问题了。

    原文作者:李迪一
    原文地址: https://zhuanlan.zhihu.com/p/34385708
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞