前篇文章中我們對區(qū)塊鏈已經(jīng)有了基本的了解,這篇文章將帶領(lǐng)大家深入理解區(qū)塊鏈背后的底層原理八毯。
在了解區(qū)塊鏈的具體原理之前,我們需要知道很重要的一點就是區(qū)塊鏈的組成瞄桨,如果從字面意思理解话速,區(qū)塊鏈是由“區(qū)塊”組成的鏈條,從技術(shù)的角度理解芯侥,區(qū)塊鏈是一種分布式數(shù)據(jù)庫泊交。
簡單來說,區(qū)塊鏈是由無數(shù)個“區(qū)塊”這個基本單元所構(gòu)成。如果把區(qū)塊鏈比作一支賬本活合,那么區(qū)塊就是這個賬本的一頁雏婶。
“區(qū)塊”如此重要,以至于我們只有了解了“”區(qū)塊“”白指,才能真正的理解區(qū)塊鏈留晚。
話不多說,原理篇我也會分為三個部分告嘲,分別為:
- Hash算法
- 區(qū)塊結(jié)構(gòu)
- 核心算法
1错维、 區(qū)塊鏈原理—Hash算法篇
Hash算法是區(qū)塊鏈中最核心也是用法最廣泛的算法,實際上大家對它并不陌生橄唬。在整個區(qū)塊鏈中它有著貫穿全場的作用赋焕,這里給大家再做幾點詳細介紹。
1.1. Hash的種類:
Hash算法有很多種仰楚,如MD5隆判、SHA系列等等,而SHA算法又分為SHA-1僧界、SHA-224侨嘀、SHA-256、SHA-384和SHA-512五種變體捂襟,區(qū)塊鏈中用到的是SHA256咬腕,所以我們在這里會重點關(guān)注,后面會講到葬荷。
1.2.Hash算法的特點:
(1)輸入任意長度的字符串(x)可以得到長度固定的結(jié)果(H(x)),例如使用MD5算法:
MD5("version1") = "966634ebf2fc135707d6753692bf4b1e";
MD5("version2") = "2e0e95285f08a07dea17e7ee111b21c8";
(2)輸入敏感涨共,輸入數(shù)據(jù)的稍微改變就會引起Hash運算結(jié)果的面目全非,上面的例子中“version1”和“version2”僅僅是最后一位“1”和“2”的區(qū)別宠漩,得出來的結(jié)果卻截然不同举反。
(3)免碰撞,即不會出現(xiàn)輸入x≠y但是H(x) = H(y)的情況哄孤,也就是強抗沖突性照筑。
(4)原像不可逆,通俗地說瘦陈,指的是知道輸入值凝危,很容易通過哈希函數(shù)計算出哈希值;但知道哈希值晨逝,沒有辦法計算出原來的輸入值蛾默。
(5) 難題友好性,不存在比窮舉更好的方法捉貌,以使哈希結(jié)果H(x)落在特定的范圍支鸡,換一種說法就是冬念,沒有便捷的方法去產(chǎn)生一滿足特殊要求的哈希值。
哈希函數(shù)的難題友好性構(gòu)成了基于工作量證明的共識算法的基礎(chǔ)牧挣,例如急前,給定字符串“blockchain”,并在這個字符串后面連接一個整數(shù)值串x瀑构,對連接后的字符串進行SHA256哈希運算裆针,要求得到的哈希結(jié)果(以十六進制的形式表示)以若干個0開頭的。按照這個規(guī)則寺晌,由x=1出發(fā)世吨,遞增x的值,我們需要經(jīng)過2688次哈希計算才能找到前3位均為0的哈希值呻征,而要找到前6位均為0的哈希值耘婚,則需進行620969次哈希計算。也就是說陆赋,沒有更快捷的方法來產(chǎn)生一個滿足要求的哈希結(jié)果沐祷。
1.3、SHA-256算法
SHA-256屬于Hash算法中的一種攒岛,由美國國家安全局研發(fā)戈轿,又屬于SHA算法的變種之一,是SHA-1的后繼者阵子。
SHA256相對于其他的Hash算法來說,特點是對于任意長度的消息胜蛉,SHA256都會產(chǎn)生一個256bit長的哈希值挠进,稱作消息摘要。這個摘要相當(dāng)于是個長度為32個字節(jié)的數(shù)組誊册,通常用一個長度為64的十六進制字符串來表示领突。
準確來說,SHA-256算法才是區(qū)塊鏈的核心算法案怯,區(qū)塊中的共識挖礦君旦、錢包的創(chuàng)建等等使用的都是SHA-256算法。
1.4嘲碱、Hash算法的運用金砍。
現(xiàn)在假設(shè)一種場景:
網(wǎng)絡(luò)傳輸數(shù)據(jù)的時候,A收到B的傳過來的文件麦锯,需要確認收到的文件有沒有損壞恕稠。如何解決?
最簡單的方法是對整個原始數(shù)據(jù)做Hash運算得到固定長度的Hash值扶欣,然后把得到的Hash值公布在網(wǎng)上鹅巍,這樣用戶從可信的渠道下載到公布的Hash值之后千扶,對數(shù)據(jù)再次進行Hash運算,比較運算結(jié)果和網(wǎng)上公布的Hash值進行比較骆捧,如果兩個Hash值相等澎羞,說明數(shù)據(jù)在傳輸過程沒有損壞(篡改),反之說明數(shù)據(jù)經(jīng)過篡改或損壞敛苇。
如果從一個穩(wěn)定的服務(wù)器(可信的渠道)進行下載妆绞,采用單一Hash是可取的。但如果數(shù)據(jù)源不穩(wěn)定接谨,一旦數(shù)據(jù)損壞摆碉,就需要整個數(shù)據(jù)重新下載,這種下載的效率是很低的脓豪。
為了解決這個問題巷帝,在P2P網(wǎng)絡(luò)中做數(shù)據(jù)傳輸?shù)臅r候,往往需要把文件拆分很多小的數(shù)據(jù)塊各自傳輸扫夜,同時從多個機器上下載拆分過后不同的小數(shù)據(jù)塊楞泼,這樣的好處是,如果小數(shù)據(jù)塊在傳輸過程中損壞了笤闯,那么只要重新下載這一塊數(shù)據(jù)就行了堕阔,不用重新下載整個文件。
但是這么做的話颗味,新的問題又來了超陆,怎么去驗證小的數(shù)據(jù)塊有沒有損壞?
答案是浦马,下載之前我們會對每個小的數(shù)據(jù)塊分別做Hash運算最終得到一個Hash List时呀。在下載到真正數(shù)據(jù)之前,我們會先下載這個Hash List晶默,對hash list中的每一個hash值進行比對谨娜。
同樣的問題又來了,怎么確定這個Hash List是正確的呢磺陡?
有一種辦法是對所有的小數(shù)據(jù)塊進行Hash運算趴梢,得到每個小數(shù)據(jù)塊的Hash值然后再用遍歷的辦法與原數(shù)據(jù)塊的Hash值做一一對比,只有下載下來的hash list 和本地計算的hash list中的每一個hash值完全一直币他,我們才會認為這個hash list是有效的坞靶,嗯,好像是可以圆丹,但這種方法代價是不是太大呢滩愁,正常場景下數(shù)據(jù)量可是相當(dāng)巨大的,這種方法的效率比較低下辫封。
為了解決這個問題硝枉,最開始在生成HashList的時候把每個小塊數(shù)據(jù)的Hash值拼到一起廉丽,然后對這個長字符串再做一次Hash運算,這樣就能得到一個最終的hash妻味,這個最終的Hash值我們稱之為Hash Root(Top Hash)正压。
所以,最終處理就是责球,下載數(shù)據(jù)的時候焦履,首先確保從可信的數(shù)據(jù)源得到正確的根Hash,用它來校驗整個Hash List雏逾,然后通過校驗后的Hash List校驗整個數(shù)據(jù)塊嘉裤。
使用迅雷下載電影時,有時候會先讓我們下載一個“種子”文件栖博,這個種子文件的用處是什么呢屑宠,大家可以好好想想?