到底什么是哈希运算 --- 理解区块链的关键一环(2)

原本打算着再歇两天,但是今天早上收到了一条催更的消息。我此时已经按捺不住我内心的激动,虽然只有一个人,虽然我知道他可能期待的只是我笔下的小红。

我其实从小就知道,我的文笔是那种好不了的类型,因为我自己看书比较少,写不出凄美的文字,打不了形象的比方,大学时学校要做presentation,就我的PPT是白底黑字对不齐的那种。之后创业了写BP,仍然延续着这种风格。BP做成那样自然是融不到钱的,也好,安心写专栏,届时哪位读者落地了一个区块链项目,给我些币作为感谢,可能那时就有钱去实现自己的梦想了。

上一篇文章,我写了一些关于哈希算法的基础理论,还是有同学看完跟我说不理解。那这里就再总结一下,哈希就是个密码学的一个算法而已。密码学怎么理解?上面提到我读书不多,但还是读了一些的。我比较喜欢网文,比如这篇由某LY写的优美软文。

XL今天晚上和同事吃饭,酒过三巡,JCSN。驱车前往XXXXX(回复可见),来到XX路,真是山重水复疑无路,柳暗花明又一村。XL立刻泊车切换成步行模式。眼前一排排的FL里,可以用琳琅满目来形容。此时,一位白衣JS映入了我的眼帘……

朋友告诉我,写专栏的人得懂得点到即止,不然专栏是看不见明天的太阳的。上面这段文字呢,女生大概率不能全懂,男生呢可能有一半能读懂。这就是密码学!哈希只是一种比拼音首拼更复杂的加密算法而已。

今天呢,我打算具体讲一些哈希算法在比特币中的运用。在遇到困难时,我还是会争取用女神小红的例子来尽可能清晰地解释,这样不但你们可以理解起来更容易,小红也会是贯穿全专栏的一条线索,看上去屌屌的。

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

哈希和区块数据结构

2.1 指针(Pointers)

在码农的世界里,Pointers是一个储存其他变量地址的变量。Eg. int a = 5 这是一个给变量a赋值的动作,但是pointers是赋予变量a其他变量在内存中的地址,地址大概长这样:0x8130。Pointers可以被翻译为指针,因为它们指向的是其他变量的地址。

2.2 链表(Linked Lists)

链表是一连串的区块,每个区块存有自己的数据(比如2000个女朋友的电话号码),并且区块和区块通过指针相连。看一张图:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

每个区块就向上图这样相连。注意最后一个区块,因为没有指向了,所以pointer是null。再注意,因为每一个区块的指针都包含了下一个区块的地址,那你可能会好奇,第一个区块的Pointer在哪里呢?第一个区块被称为’Genesis Block'(玩过FF7的还记得杰尼西斯吗,他就是创世的意思),它的pointer不在链上,但是在系统内部,大概长这样:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

这里的Hash Pointer,我们一会儿就会解释。现在你也大概猜到了,区块链其实就是基于链表的格式,所以我们先来看一下区块链到底长什么样子:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

这么看区块链即一目了然。区块包含了数据,并且通过哈希指针连接了前一个区块,如此形成了区块链。一般的指针只储存前一个区块的地址,哈希指针就多做了一件事,它还储存了前一个区块的数据的哈希值。就是这么一个小小的指针,赋予了区块链技术可靠性和革命性。

想象一下这个场景,黑客小A想更改在上图1号区块的数据,他在1号区块里的真实数据是付了10000个比特币买了一个披萨,他想把10000改成1。试想下后果,我们在上篇文章中说到,即使A只有少量变化,H(A)会变得面目全非。所以因为1号区块的数据被更改了,导致2号区块的hash pointer改变了,所以小A又不得不继续修改2号区块,接着再修改3号区块,直到……因为整个网络(所有节点)只承认最长的链子,所以小A必须不停地修改区块,直到假链变成最长的链为止。但在整个这个过程中,小A面对的算力是整个网络的其他算力,想要成功的概率几乎为0。这让我想起了前几天朋友发给我的一张图,一起感受一下:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

(具体的计算会在之后的白皮书解释中列出)这就是为什么区块链支付安全的原因。当然,10000个比特币买披萨的老哥不是我捏造出来的,历史上确有其人,他买的披萨在2017年大概市值1.4亿人民币。我想说,他是伟大的,他是第一个将比特币支付落地的勇士,让我们记住他的名字 Laszlo,Hanyecz。也让我们记住他的支付日期,5月22日,也因为他,这一天也是世界披萨日。(我发誓我没有笑)

2.3 区块标头(Block Header)

观察仔细的同学会发现,上图的区块里,有个东西叫’Header’,那Header又长什么样子,它包含了哪些东西:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

一个区块标头包含:

  1. 一个区块的版本号
  2. 时间:目前的时间戳
  3. 目前的难度目标(后文会解释)
  4. 前一个区块的哈希值
  5. Nonce: 随机字符串(后文会解释)
  6. 默克尔根的哈希值

让我们我们先把注意力放在6,默克尔根的哈希值。在这之前,我们先看一下什么是默克尔树(Merkle Tree)

什么是默克尔树

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

在每一个区块中,会存有成千上万比交易,如果把这些所有的交易记录都储存在区块中,将会浪费很多的时间。同样确认过去的具体某一比交易是否属于它的当前区块,也会非常耗时耗力,但是利用默克尔树,验证一笔交易是否属于它的区块,将会大大减少耗时,增加效率。举个简单的例子,有个小朋友,通过我对女神小红的描述,特别想见女神一面,于是他就在全世界范围内找了起来,大家都知道,这几乎不可能实现。但是如果我告诉他,小红就在上海中学三年二班的乒乓球队里,那我想想见小红一面还是不难的。默克尔树做的大概就是这样的事。

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

简单的说,每个区块里只保存树梢,也就是图中的Top Hash,也就是要解释的6咯。当我想验证某笔交易是否属于这个区块时,我只需要沿着上图箭头做3次哈希运算,看看哈希值是否匹配即可。就像这样:

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

然后,我们再去解释目标难度和Nonce,因为他们是挖矿中的运用。

2.4 挖矿

在区块链的世界里,当我们说到挖矿,我们指的是全部网络的节点,通过算力的比拼,找到一个新的区块,并且获得这个区块的加密数字货币奖励的过程。

2009年,世界上第一个区块非常容易地被比特币之父中本聪用电脑CPU发现了,他也理所应当地获得了50个比特币的奖励。随着比特币价格的飙升,越来越多的人参与到挖矿这个活动中来。矿工们从CPU挖矿,到GPU挖矿(吃鸡的小伙伴可能现在明白了为什么显卡越来越贵了,可不是因为吃鸡火),到用GPU组成矿机挖矿,到现在的矿池,矿厂。值得骄傲的是,我们中国已经占据了整个比特币网络80%的算力,可谓相当惊人。

假想,按照最初的速度挖矿,我们在白皮书已知比特币的总量只有2100万个,比特币会很快被挖掘完毕,这不是中本聪想看到的,所以中本聪设定了一个浮动的难度目标,也就是上文未解释的3。他运用Nonce(也就是上文未解释的5),设计了一个解谜游戏,只有第一个解开谜题的矿工,才能真正获得新区块的拥有权,并顺理成章地获得比特币奖励。那这个游戏具体是怎么设计的呢?

了解游戏规则之前,我们先了解难度目标,难度目标和SHA256哈希值一样,是一个256bit的字符串,大概长这样: 0000xusjwak5sfxsa4xfj……(共64位),好了,记住这个字符串的样子,我们了解中本聪的挖矿游戏规则。

游戏规则是这样的:

当一个区块生成时,所有这个区块的内容会做一次哈希运算。系统会比较这个哈希运算值和难度目标的两个字符串大小,如果小于难度目标,则新区块就生成了。拿上文难度目标距离,如果新区块的哈希值是00000000h2gs98gjodspfiu……(共64位),很显然小于了目标难度的0000xusjwak5sfxsa4xfj……(共64位),此时新区块就成立了。

但是事实是残酷的,瞬间得到一个比目前难度的还小的区块哈希值,概率非常非常非常非常小。于是,我们再来看一下这个解谜游戏的过程是什么样子的:

  1. 新区块做哈希运算,如果哈希值>目标难度,则到步骤2,否则区块直接生成
  2. Nonce(随机字符串)加到1里面的哈希值
  3. 对新的字符串运算,生成新的哈希值
  4. 如果新的哈希值<目标难度,则新区块生成,并广播给网络上的节点,生成新区块的矿工获得比特币奖励
  5. 如果新的哈希值>目标难度,则回到步骤2

我退10000步解释,中本聪手里有个数字是10。矿工开始挖数字,挖到11,继续挖。挖到13,还是不行,继续挖。挖到8,诶!成了,中本聪把新的区块给你了,你得到了50枚比特币奖励。

还记得我们上一篇文章说到的哈希运算的解谜性吗?对于任意一个输出值Y,如果k是从一个high min-entropy上取的字符串,几乎不可能找到一个x,使得 《到底什么是哈希运算 --- 理解区块链的关键一环(2)》 。运用到挖矿的例子上,这里Y 就是目标难度,k就是Nonce,x就是区块的哈希值。

整个这个过程又被称作工作量证明,PoW(Proof of Work),PoW有两个特性:

  1. 矿工挖矿需要通过很强的算力和较长的时间。
  2. 验算矿工是否正确却耗时极短,且每个人验算起来都很简单。

当然,现在的矿工已经没有那么高的报酬了。因为浮动的难度目标会让每个新区块生成的时间大概是10分钟,且中本聪设计了每210000个区块,比特币奖励减半,那我们就可以计算一下,210000*10/60分钟/24小时/365天 ≈4年。因此比特币每4年,奖励就减半了。截至本文发稿时间,一个新区块的比特币奖励为12.5个(50个/2/2)。这个模型也让我有了一点自己的思考,所以不久的将来,我会写一个番外篇,说些自己的理解,为什么比特币恰好在2013年(2009+4), 2017年(2009+8)暴涨了,也算可以蹭一下币圈的热度。最后再给大家一个数据,比特币的挖矿难度,是每2016个区块生成,自动调节一次。算一下,2016*10/60/24,大概是4天变动一次难度。

这里留下一道简单的思考题,假设在矿工越来越多,全网算力越来越强的情况下,我们仍然希望区块按照每10分钟生成一个新的节奏继续下去,那按照我们上面的例子,当前区块的目标难度为 0000xusjwak5sfxsa4xfj……(共64位),下一个区块大概是什么样子呢?

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

总结

今天我们具体讲解了区块链的结构,包括(版本号,时间戳,难度目标,前一个区块的哈希值,Nonce和默克尔根的哈希值)。也说了默克尔树的运用,以及最重要的矿工挖矿时到底是在干嘛,什么是工作量证明。在理解了这些概念之后,下一篇文章,我们会回到白皮书。那时候,你就会觉得,白皮书也不是这么难理解嘛!最后的最后,按照惯例,你懂。

《到底什么是哈希运算 --- 理解区块链的关键一环(2)》
《到底什么是哈希运算 --- 理解区块链的关键一环(2)》

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