全民新游榜--GET好游戏
当前位置:18183首页 > 产业频道 > 最新新闻 > 最新资讯 > 正文

【深度】一个故事看懂区块链网络节点如何通信!

来源:chanye.18183.com作者:游民老赵 时间:18-05-21 分享到:

只要绝大多数节点不作恶,每个节点尽力广播自己的消息,使用工作量证明(POW)的方法,全网就会形成正确共识。

只要绝大多数节点不作恶,每个节点尽力广播自己的消息,使用工作量证明(POW)的方法,全网就会形成正确共识。

你我是两支部队的将军,分立两座山头,围剿山谷中的敌城。敌城很牢固,如果我们独立攻城必输,但是合力出击必胜。

【深度】一个故事看懂区块链网络节点如何通信!

看来很简单,我们一起轰上去就能搞定。但是有一个小问题:山上没有信号,传递消息只能靠通信兵,而通信兵必须经过山谷中的敌城才能传递消息。

假设:

你看到一个信使,带来我的消息:“今夜23点攻城”。请问,你敢信么?

如果你信了,半夜出兵,结果被灭了也千万别奇怪,因为我发给你的消息是:“明天早上6点攻城”。

但是,我的通信兵被敌人截杀,他们换了个新的,骗你早点出来。如果你被灭了,敌人就赢了,因为我单独攻城也是被灭的命。

只传输文字信息带来两个问题:

1)原文易被篡改;

2)收信人无法验证原文是否被篡改;

那该怎么办?两个办法:

一是我们熟悉的数字签名,但这只适用于一对一传输的场景。

如果要把消息向全军广播,就得用到第二种方法:工作量证明。

一、什么是工作量证明?

工作量证明(proof-of-work)指通过完成一定工作量以阻止网络恶意攻击的方式,简称POW

你可以把“一定的工作量”理解为简单体力劳动,相当于去猜福利彩票的中奖号码:你只要趴在桌上写啊写,就一定能够写中下一期的中奖号码,只是要花点力气而已。

【深度】一个故事看懂区块链网络节点如何通信!

但在工作量证明中,猜的可不是号码,而是猜一个普通数字,这个数字添加在原文消息后,使得整个结果的哈希值前面有很多个0。

回到开头的场景,我要发给你的消息是:明天早上6点攻城。但是我不能直接发,因为容易被敌人截杀。

你我之间可事先约定:

我找一个幸运数字,加在消息后面,使得“消息+幸运数字”的哈希值以5个0开头。如果不是这样,那你收到的消息就肯定不是我发的。

在这里,“5”代表难度,哈希值前缀的“0”越多代表这个幸运数字越难找。

二、用工作量说明“工作量证明”

下面,我用简单体力劳动演示简单体力劳动的全过程:

下图左侧是14种不同的哈希算法,右侧是不同算法的哈希值结果,我们选用群众喜闻乐见的SHA-256的哈希算法(来源网址:文末链接[1])。

【深度】一个故事看懂区块链网络节点如何通信!

一般的哈希值都不以“0”开头,比如:“明天早上6点攻城”的哈希值以“6600c”开头。

我们的任务是找一个幸运数字,把这个数加在原文消息后面去哈希,当哈希值前面出现5个0的时候,这个幸运数字就是我们要的值。

我们从0开始:把0加在消息“明天早上6点攻城”之后,变成:“明天早上6点攻城0”,得到哈希值:0593feea85b5cc51……

这个哈希值不以5个“0”开头,所以0不是符合要求的幸运数字。

哈希值长度为64位,考虑到你手机屏幕的宽度,所以只列前N位哈希值。找到1个“0”开头的哈希值很容易,冲上来就找到了。但别忘了,我的任务是找5个“0”开头的哈希值。

开始体力劳动:

你只需注意以0开头的哈希值出现的频率。

消息+幸运数字 哈希值(前N位)

明早上6点攻城0 0593feea85b5cc51

明早上6点攻城1 5c14326badbde132

明早上6点攻城2 434fe85e6c397d38

明早上6点攻城3 ea1ee28cb2827fa9

明早上6点攻城4 8559db7af65e2bc9

明早上6点攻城5 6ec12acfe954ffe43

明早上6点攻城6 53bd9133146631a

明早上6点攻城7 d348d29e9398d88

明早上6点攻城8 276cfca1386ffba0d

明早上6点攻城9 f78628f2b0e4941c6

明早上6点攻城10 f92e8cd090f34feb2f

明早上6点攻城11 5cc0bc8a34f5fb81b

明早上6点攻城12 764154add623fee9c

明早上6点攻城13 96c3bcb245fd955f1

明早上6点攻城14 7c18fb827e48ea685

明早上6点攻城15 283f7de03f0165fac5

明早上6点攻城16 bce71436c4907d14

明早上6点攻城17 4f76be60fb2b0da75

明早上6点攻城18 182530c711a1cd98

明早上6点攻城19 6d59c71c30c17f378

明早上6点攻城20 b0161336bbbe8671

明早上6点攻城21 a1f35a0522b3a7ff8e

明早上6点攻城22 e118e2ce041d2a7f4

明早上6点攻城23 652083fffd51d0ae7f

明早上6点攻城24 678aa3a7ce73b5c9

明早上6点攻城25 f4a1f9d9b2fb9b1b4

明早上6点攻城26 c87c2c4e884ea133

明早上6点攻城27 2b3fb751465404de

明早上6点攻城28 227bac9dc398936e

明早上6点攻城29 888b7a21af071d5c

明早上6点攻城30 f4e9bb78cab0ff886

明早上6点攻城31 91594c8e41636a55

明早上6点攻城32 a7e8e2259ef52af4f

明早上6点攻城33 8b55a6ac71191a0e

明早上6点攻城34 a8304e90a8af8c7u

明早上6点攻城35 d57a2113827cbcdd

明早上6点攻城36 09c1eeaff85866243f

寻找“0”开头的哈希值相对容易,一下找到2个,对应的数字分别是0和36,但没有“00000”开头的哈希值,甚至没有“00”开头的。

继续:

明早上6点攻城37 7dfb6f433c3645462

明早上6点攻城38 7572b6a6aa98910a

明早上6点攻城39 5ac0d7c30d2890ca

明早上6点攻城40 9be18e61d82d1752

明早上6点攻城41 9541e2a4326e26a2

明早上6点攻城42 808f9e53e2fdfcde4f

明早上6点攻城43 cf9158dec66779f89

明早上6点攻城44 58c9b2b0b9e0c851

明早上6点攻城45 0e35034199718f0fd

明早上6点攻城46 6684da32f8dd10b17

明早上6点攻城47 53e75d1bf17a577ef8

明早上6点攻城48 49f5ea6a963c63620

明早上6点攻城49 14532b88606aeaad5

明早上6点攻城50 2b421e6ca5e184c21

明早上6点攻城51 32f6b4dc0e6c4d534

明早上6点攻城52 7b61def8dd77f08c25

明早上6点攻城53 59ec7fdd8457aa39f2

明早上6点攻城54 ba9697b6b4bbada44

明早上6点攻城55 130d07e46333ab39a

明早上6点攻城56 a7a3e432ac5660fb7c

明早上6点攻城57 ab72f349e783a2a4b8

明早上6点攻城58 039c996ace6dbc7d4

明早上6点攻城59 105626ff7234569223

明早上6点攻城60 b182960d7c0a6668

明早上6点攻城61 48233ba8877b40ead

明早上6点攻城62 d286d115c912c6205

明早上6点攻城63 fbf8e794aca4a2f8a92

明早上6点攻城64 4192c87e6911f9d8ea

明早上6点攻城65 fa5f19484c040ded83

明早上6点攻城66 42956b52051f1242be

明早上6点攻城67 68ecab13753c945671

明早上6点攻城68 70895ad85e9cf99407

明早上6点攻城69 d4ae89d8c6c968f035

明早上6点攻城70 4a6eb62c842417fe6a

明早上6点攻城71 2676fbd40437e60219

明早上6点攻城72 540e4a3347171077d

明早上6点攻城73 21be059d3c4dba03d

明早上6点攻城74 0d359bbca099eb63c1

明早上6点攻城75 255b4ff42e9a52830c6

明早上6点攻城76 55da96691231c2b921

明早上6点攻城77 d96bea5b456fbb080b

明早上6点攻城78 cd814aeb96ab6a795c

明早上6点攻城79 86ae1b4298637efb56

明早上6点攻城80 5b03962a07fe916c79

明早上6点攻城81 4b219e4e26e5883216

明早上6点攻城82 b64488ed650ce928df

明早上6点攻城83 a361cb170b37a57a61

明早上6点攻城84 e6f543f7c5665857088

明早上6点攻城85 468db8901982df4c14

明早上6点攻城86 e13fac9a65fa76e477b

明早上6点攻城87 1821cb6741f34ea5554

明早上6点攻城88 fda69eae2282f6c049fb

明早上6点攻城89 83bd626cb8fc04662cc

明早上6点攻城90 5a7cb656e9957de9c2

明早上6点攻城91 e4813bc08139e59e7d

明早上6点攻城92 ad70094cf25902427a

明早上6点攻城93 20d92beaef0f1dac96f

明早上6点攻城94 13dce00f7477d70a9e2

明早上6点攻城95 e8e711a4d6eb00341e

明早上6点攻城96 9cfde03631631dfba67

明早上6点攻城97 ce78f0ead3cd569d1d

明早上6点攻城98 ca9ab59025aeceb608

明早上6点攻城99 37c2e33202248931b4

明早上6点攻城100 4310137ff5e2329929f

以0开头的哈希值很稀薄,100个后缀数字只有五个以1个“0”开头的哈希值。为节约你的时间,以下省略所有不以“0”开头的哈希结果。

......

“00”开头的哈希值难能可贵,找遍300以内的数,竟然没有,继续:

明早6点攻城308 05977df5bd690958ed

明早6点攻城345 08884879b8f802455

明早6点攻城346 0ae905eb78cb562cc0

明早6点攻城347 00254b20c9cea56987

遍历到347,终于出现连续一个“00”开头的哈希值,难能可贵,但我们要找的是“00000”开头的哈希值,所以继续:

……

……

一直找

……

百折不挠

……

如果不靠省略号的帮助

你的屏幕已经下拉了10公里

……

屏幕已经拉穿了地球

……

字字读来都是血,十年辛苦不寻常

苦心人,天不负。

终于,天开眼了……

我发现:用894578149接在原文后面,“明天早上6点攻城894578149”的哈希值符合要求:00000a392277b16……。

“894578149”就是我们要找的幸运数字,找到它就像中彩票一样梦幻。因为我无法通过哈希值倒推,只能苦算[2]。

你见过的那些灰字和省略号,就是我的工作量证明——虽然每次哈希运算很简单,只要0.001秒,但8.9亿次哈希运算,却需要10天时间。如果想在1天时间内算出来,得买10台计算机。

如果敌人截获消息,篡改成“后天15点攻城”,那么他得重新算幸运数字,并且,你知道只有你和我约定过“00000”的事。

我把“明天早上6点攻城894578149”发给你,你把原文一哈希,得到“00000a392277b16……”,五个零的前缀让你大喜过望。

你准备明天6点起兵攻城。

但是,你真的可以这样吗?

不可以,因为敌人也懂哈希。

你看,理论上我的信息会被截获,敌人拿到原文“明天早上6点攻城894578149”,一哈希,就能发现前面有五个零。

然后敌人为你编了条假消息:“后天13点攻城”。并且如法炮制,用工作量证明算出了一个幸运数字238925022。你收到消息:“后天13点攻城238925022”,一哈希,发现哈希值前缀也是“00000”。

如果你信了,后面的剧本就是:我明天一早攻城,比你先死一步。因为我的消息没能发给你,你被敌人蒙蔽了。

所以,你还是不能轻信你亲眼看到的消息,因为传输通道不可靠。

横竖都死,如何破局?

三、解开真正的难题

答案是增加通信兵和提高难度。

增加通信兵容易理解:我派出10个通信兵,被拦截的可能性低于派1个兵。

增加难度指:从连续5个“0”的哈希值前缀变成连续6个、7个、甚至更多“0”,可以提高敌人的破解难度。

这样,即使通信兵被拦截,敌人哈希一下发现前面有7个零,一下就傻了,因为敌人明白,要哈希出7个“0”开头的结果得花几年时间找一个幸运数字。

当敌人知道你会派10个通信兵传递消息,而只拦截到1个兵时,敌人甚至都懒得做工作量证明。因为他知道,即使拦截篡改了,也没有什么卵用。

因为敌人知道:第一,找幸运数字要花很长时间;第二在千万次哈希过程中已经有9个兵把消息传到了,即使找到了幸运数字,我也没办法混淆视听。

所以,你我必胜,敌人必输。

拓展今天的故事:左右山头分别有五个将军准备攻城,信息传递只能靠信使,每个将军都有自己的想法,但只有当超过半数的将军一起攻城时才能获胜,如何敲定攻城时间?

【深度】一个故事看懂区块链网络节点如何通信!

就是“拜占庭将军问题”,如果你去翻比特币或区块链的书,作者十有八九会摇着你的衣领向你讲述,然后你百有九十九会蒙圈。

它真的很难理解,因为在我们生活的世界没有对照物,它甚至没有发生过,它只是计算机科学家Lamport在1980年提出的思想实验。

如果你已经理解两个将军攻城的问题,那么就能解出拜占庭将军问题。

很简单:

把一座山头上所有将军的攻城意向时间汇总打包:

将军1:明天1点;

将军2:明天3点;

将军3:明天3点;

将军4:后天5点;

将军5:后天7点;

找出一个幸运数字,使得“信息+幸运数字”的哈希值前缀是“00000000”,派10个通信兵送信。

即使有1个通信兵被拦截,另一个山头的将军也能收到9条“消息+幸运数字”,哈希后发现有8个“0”,8代表难度已经很高了,敌人破解的概率是万亿分之一。于是果断相信,并采用同样方式回信:

将军6:明天3点;

将军7:明天3点;

将军8:明天1点;

将军9:后天7点;

将军10:明天3点;

找出一个幸运数字,使得“信息+幸运数字”的哈希值前缀是“00000000”,派10个通信兵送信。

来回几次确认后可达成一致:明天3点攻城。

这样,拜占庭将军们必胜,除非敌城能用更短的时间找出幸运数字,而这却是极小概率事件,比中六合彩都难上一亿倍。

结语

在现实世界,通信不是问题,毕竟没有手机信号还有无线电、信号弹,甚至隔山吹口哨都能解决;但在互联网世界,信号传输只能依靠节点。

所以,是一个隐喻:山谷里的敌城是互联网,你我和各路将军是网上的节点,通信兵指传递消息的动作,消息指区块,而幸运数字在区块链世界里,有个术语:随机数(Nonce)。

解决拜占庭将军问题后,就有了比特币。记录交易信息和找随机数的过程,就是比特币挖矿[3]。

在此之前,“信道不可靠”曾是个天大的难题:

网络上每个节点很疑惑:我应该听谁的?

答案是:谁都不用听,听到啥就广播啥,当好通信兵。

全网系统也很疑惑:通信渠道不可靠,如何保证传递的信息最终可靠?

答案是:只要绝大多数节点不作恶,每个节点尽力广播自己的消息,使用工作量证明(POW)的方法,全网就会形成正确共识。

而这一切的基础就是数学。

我们不能轻信网络中的任何节点,但是我们可以相信数学,相信概率是百万亿分之一的事情不可能发生。

附:

[1]哈希网址

http://www.fileformat.info/tool/hash.htm

[2]弱弱地说一句:随机数894578434是我乱说的,截至发稿时我没算出以“00000”开头的哈希值,但这个数字一定能被某台计算机算出来。这就像你只要足够卖力,一定能在纸上写出下期的中奖号码。

比特币第1个区块和第495661个区块的哈希值,请注意比较前面的0的数量

 
【深度】一个故事看懂区块链网络节点如何通信!

哈希值前缀从8个“0”到18个“0”,你可以闭眼体会下难度——如果把计算结果都显示在你的手机屏幕上,那要找到18个“0”的结果,你的屏幕可能要拉出银河系了。

    18183手游网发布此文仅为传递信息,不代表18183认同其观点或证实其描述。

    区块链内容转载、投稿、商务合作等相关事宜请联系QQ:2664083315