張成成
摘要:區(qū)塊鏈挖礦不僅是系統(tǒng)發(fā)行新幣的途徑,還是保障區(qū)塊鏈系統(tǒng)安全穩(wěn)定運(yùn)行最重要的基石。而挖礦算法在設(shè)計的時候為了保證區(qū)塊鏈免受51%攻擊,則挖礦算法就必須保證不同。不同的挖礦算法消耗的主要計算機(jī)資源也不同,本文選擇比特幣、以太坊和Filecoin的挖礦算法為例,它們分別以消耗CPU、內(nèi)存和硬盤資源為主。通過分析這三種挖礦算法的主要過程,得出區(qū)塊鏈安全性和資源浪費(fèi)之間沒有兩全其美的解決方案。
關(guān)鍵詞:區(qū)塊鏈;共識機(jī)制;比特幣;以太坊;Filecoin
中圖分類號:TP309 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9416(2017)10-0108-03
自從2009年1月3日中本聰挖出比特幣的創(chuàng)始區(qū)塊以來,區(qū)塊鏈成為一種新的解決去中心化節(jié)點(diǎn)的信息同步問題的方案,其創(chuàng)新性不斷被人們所認(rèn)知[1]。這其中,最關(guān)鍵的是以PoW(Proof of Work,工作量證明)共識機(jī)制為基礎(chǔ)的公有鏈,這些系統(tǒng)普遍采用不同的挖礦算法來保障整個系統(tǒng)的安全穩(wěn)定性。安全可信是區(qū)塊鏈的基石,在此基礎(chǔ)上人們才能談?wù)搮^(qū)塊鏈的其它應(yīng)用。而為了保障公有鏈的安全性,中本聰提出了挖礦的概念。挖礦是一種通過消耗計算機(jī)資源來提高惡意節(jié)點(diǎn)攻擊網(wǎng)絡(luò)成本的一種方式。挖礦的中心思想起源于Hashcash機(jī)制,該機(jī)制初次提出時主要用來阻止惡意用戶向郵件服務(wù)器發(fā)送垃圾郵件[2]。所有的用戶向郵件服務(wù)器發(fā)送郵件的時候都要在郵件中填充一些隨機(jī)字符,然后計算郵件內(nèi)容的哈希值,只有當(dāng)計算結(jié)果小于設(shè)定的值的時候,該郵件才能滿足郵件服務(wù)器的接受條件。在這個過程中,用戶為了發(fā)送一個郵件,需要消耗一點(diǎn)時間來找出一個隨機(jī)字符,使得整個郵件能被郵件服務(wù)器驗證通過。無論是合法用戶還是惡意用戶,都無法繞開這個過程,這在一定程度上會影響正常用戶的發(fā)送速度,但是影響微乎其微。而惡意用戶為了大量發(fā)送垃圾郵件,就不得不大量計算滿足條件的值,這無疑會增加惡意用戶的攻擊成本。這就是中本聰設(shè)計比特幣的時候,需要礦工計算區(qū)塊頭的哈希值的原因。然而,惡意節(jié)點(diǎn)仍然可以事先花費(fèi)大量的時間來計算滿足條件的隨機(jī)值,然后在極短的時間內(nèi)發(fā)送給郵件服務(wù)器,從而完成DOS攻擊。為了防止這種情況的發(fā)生,Hashcash要求用戶在郵件內(nèi)容中添加一條最近的消息,例如最近一天的博彩結(jié)果等。這樣惡意節(jié)點(diǎn)的提前運(yùn)算行為就被嚴(yán)格限制了。而在區(qū)塊鏈挖礦過程中,礦工計算區(qū)塊哈希值的時候也必須包含前一個區(qū)塊頭的哈希值。這樣就能嚴(yán)格限制惡意節(jié)點(diǎn)提前進(jìn)行挖礦的時間。區(qū)塊鏈挖礦的目的也是為了保障系統(tǒng)的安全穩(wěn)定運(yùn)行,本質(zhì)上以每個節(jié)點(diǎn)的資源消耗來換取系統(tǒng)的高度可靠性。
目前基于PoW的公有鏈采用的挖礦算法主要目的是為了消耗每個節(jié)點(diǎn)的計算機(jī)資源。計算機(jī)資源主要分為以下幾大類:CPU、內(nèi)存、硬盤等。那么相應(yīng)的,區(qū)塊鏈的挖礦算法也存在著以消耗這三類計算機(jī)資源為主要目的的挖礦算法。PoW共識機(jī)制的挖礦算法主要以消耗CPU和內(nèi)存為主。而于今年正式發(fā)布的Filecoin則開創(chuàng)性的提出了一種名為時空證明(Proof-of-Spacetime)的新的共識機(jī)制。該機(jī)制的挖礦算法主要以消耗計算機(jī)硬盤資源為主。由于PoW共識機(jī)制的挖礦算法有很多,所以本文主要介紹兩種具有代表性的挖礦算法。
1 挖礦算法
區(qū)塊鏈挖礦算法種類眾多的原因之一就是為了防止51%攻擊。在區(qū)塊鏈中,PoW共識機(jī)制挖礦的能力與礦工所掌握的算力成正比。區(qū)塊鏈的特性就是每個區(qū)塊都指向前一個區(qū)塊,這樣就環(huán)環(huán)相扣,從最新的一個區(qū)塊就能一次找到創(chuàng)世區(qū)塊。但是如果一個惡意節(jié)點(diǎn)控制了大部分的算力,那么就可以按照下列步驟發(fā)起攻擊:
(1)如下圖1所示,在區(qū)塊鏈上所有的區(qū)塊都環(huán)環(huán)相扣,后面的區(qū)塊包含前一個區(qū)塊的哈希值。惡意節(jié)點(diǎn)A首先在第n個區(qū)塊中進(jìn)行一次交易,將一筆資金發(fā)送給B,交易數(shù)據(jù)寫入到區(qū)塊n中。
(2)然后掌握51%算力的惡意節(jié)點(diǎn)就馬上從第n號區(qū)塊后進(jìn)行挖礦,計算新的n區(qū)塊,但是該區(qū)塊不包含由A到B交易的信息,取而代之的是惡意節(jié)點(diǎn)A把同樣一筆數(shù)額的資金發(fā)送給C的交易信息。之后其它節(jié)點(diǎn)就從n號區(qū)塊后進(jìn)行挖礦驗證,而惡意節(jié)點(diǎn)就在n號區(qū)塊后進(jìn)行挖礦。因為區(qū)塊鏈的特點(diǎn)就是以區(qū)塊數(shù)量最多的鏈作為主鏈,則惡意節(jié)點(diǎn)的算力占了絕大部分后,惡意節(jié)點(diǎn)所在的鏈則很有可能成為主鏈。那么,A發(fā)送給B的交易的區(qū)塊就徹底消失了,這樣就能使得B損失了一部分資金。
正是因為51%攻擊的巨大危害性,則不同的區(qū)塊量系統(tǒng)在選擇挖礦算法的時候就努力避免選擇與現(xiàn)有區(qū)塊鏈系統(tǒng)相同的挖礦算法。這樣就使得其它鏈的礦機(jī)就無法更加高效的在新的區(qū)塊鏈上挖礦,新的區(qū)塊鏈的礦工算力被其它礦工綁架的概率就降低了,從而保障區(qū)塊鏈系統(tǒng)的安全性。
接下來將主要介紹比特幣、以太坊和Filecoin的挖礦算法。
2 挖礦算法分析
2.1 比特幣挖礦算法
比特幣作為最早的區(qū)塊鏈系統(tǒng),其挖礦算法采用的是SHA256散列函數(shù),該函數(shù)屬于SHA2系列。比特幣的挖礦過程很簡單:
(1)礦工收到用戶的交易信息后,首先驗證,然后構(gòu)造交易的默克爾樹,得到一個默克爾樹根哈希值,打包進(jìn)區(qū)塊頭中。對于礦工來說,最優(yōu)的選擇就是先打包手續(xù)費(fèi)高的交易,這樣才能保證其利益最大化。
(2)填充區(qū)塊頭,組成80個字節(jié)的比特幣區(qū)塊頭。區(qū)塊頭的數(shù)據(jù)結(jié)構(gòu)如表1所示。
(3)將80個字節(jié)的區(qū)塊頭信息進(jìn)行雙SHA256運(yùn)算,得到一個32字節(jié)的哈希值。之后判斷得到的結(jié)果是否小于當(dāng)前區(qū)塊的難度值,如果已達(dá)到,則該區(qū)塊就是合法的區(qū)塊。礦工把它加入到主鏈中,之后開始計算下一個區(qū)塊。如果不小于當(dāng)前區(qū)塊難度值,則繼續(xù)更換區(qū)塊頭中的隨機(jī)數(shù)值,重新對區(qū)塊頭進(jìn)行雙哈希運(yùn)算。
這就是比特幣挖礦的完整過程??梢园l(fā)現(xiàn),整個挖礦過程就是不斷計算做哈希運(yùn)算的過程。而整個尋找合適隨機(jī)數(shù)的過程是可以多個核心并行查找計算的。因此,擁有眾多流處理器的GPU芯片逐漸就取代了比特幣的CPU挖礦。然而,無論是CPU還是GPU,其計算過程均是將哈希運(yùn)算的算法過程編譯成底層指令完成計算,指令中并沒有專門為哈希運(yùn)算進(jìn)行專門優(yōu)化,無法充分發(fā)揮芯片的運(yùn)算潛力。隨后,F(xiàn)PGA(Field-Programmable Gate Array,現(xiàn)場可編程門陣列)通過自身強(qiáng)大的自定義硬件過程,使得哈希函數(shù)可以直接通過硬件編程進(jìn)一步提高運(yùn)算效率。而近些年,ASIC(Application-specific integrated circuit,專用集成電路)的發(fā)展促使礦工可以制作專門的硬件結(jié)構(gòu)對哈希運(yùn)算進(jìn)行硬件定制。無疑,這種方式最大可能挖掘礦機(jī)芯片的計算潛力。endprint
但是,這些優(yōu)化操作只會將算力更加集中在某幾個組織手中。尤其是有了ASIC芯片之后,普通用戶使用CPU或者GPU進(jìn)行挖礦已經(jīng)沒有什么利潤可言了。為了防止算力太過集中的情況發(fā)生,以太坊就提出了一種新的以消耗內(nèi)存資源為目的的挖礦算法,這就是Ethash。
2.2 以太坊挖礦算法
Ethash工作過程,其實就是要求從一個巨大的數(shù)據(jù)集中隨機(jī)選擇若干元素,然后對其做哈希運(yùn)算的運(yùn)算過程。具體過程如下:
(1)生成32個字節(jié)的種子。以太坊規(guī)定每30000個區(qū)塊是一個窗口,在同一個窗口期中,種子是相同的。種子的生成過程是這樣的:第一個窗口期的種子是將32字節(jié)的0值做一次Keccak256運(yùn)算,得到一個32字節(jié)的種子。而以后每個窗口期的種子生成方式就是將前一個窗口期的種子做一次Keccak256運(yùn)算。
(2)生成不定長度的緩存。緩存的生成過程是這樣的:每個緩存單元的大小為64字節(jié),即512位。第一個緩存單元是當(dāng)前窗口的種子值做Keccak512運(yùn)算得到的。之后每個緩存單元都是前一個緩存單元的Keccak512值。而每個窗口期的緩存大小隨著窗口期的增加而線性增大。初始大小為16MB,之后每個窗口期增加不到128KB。之后將初步得到的緩存做3個輪次的Rand Memo Hash運(yùn)算。Rand Memo Hash算法將緩存的各個單元進(jìn)行混淆。
(3)生成不定長度的數(shù)據(jù)集合。首先從生成的緩存中隨機(jī)找出256個緩存單元,然后合并做哈希運(yùn)算。這樣得到的數(shù)據(jù)集初始大小為1GB,而后每個窗口期增加不到8MB。注意,在驗證區(qū)塊的過程中,也是同樣的操作。這樣就需要將緩存和數(shù)據(jù)集保存到內(nèi)存中,以方便挖礦或者驗證區(qū)塊的時候頻繁的讀取數(shù)據(jù)消耗過多的時間。
(4)礦工之后就通過PoW機(jī)制進(jìn)行挖礦操作。但是因為每個緩存和數(shù)據(jù)集生成時間需要消耗大量的時間,則為了防止在下一個窗口期到來的時候影響出塊速度,則鼓勵礦工提前計算好緩存值和數(shù)據(jù)集。
Ethash在運(yùn)行過程中需要消耗大量的內(nèi)存資源進(jìn)行密集的查找元素計算工作。而ASIC礦機(jī)運(yùn)行過程中需要競爭大量的帶寬資源,這就使得采用Ethash算法的以太坊很難出現(xiàn)具有實用價值的ASIC礦機(jī)。實際上,當(dāng)前以太坊礦工使用的芯片主要是顯卡芯片,利用GPU的眾多核心加快挖礦速度。
2.3 Filecoin挖礦算法
Filecoin其實存在于IPFS(Inter Planetary File System,星際文件系統(tǒng))的激勵層,而IPFS能夠提供去中心化的數(shù)據(jù)存儲和訪問功能。因此,F(xiàn)ilecoin需要大量的數(shù)據(jù)讀寫操作,這就要求礦工的挖礦過程進(jìn)行數(shù)據(jù)讀寫操作。Filecoin的挖礦共分為存儲挖礦和檢索挖礦兩部分,分別進(jìn)行數(shù)據(jù)的存儲和檢索工作。
2.3.1 存儲挖礦
存儲挖礦分為四部分:抵押、接收訂單、密封和證明。
2.3.1.1 抵押
抵押的主要目的是為了保證存儲礦工能夠為網(wǎng)絡(luò)提供存儲服務(wù)。存儲礦工首先在區(qū)塊鏈上進(jìn)行一次抵押交易,該交易主要通過保存一個抵押品來抵押存儲礦工的存儲容量。而當(dāng)存儲礦工成功生成了他們提交數(shù)據(jù)的存儲證明,那么存儲礦工先前的抵押品就可以退回。如果存儲礦工未完成相應(yīng)的存儲證明,那么將會失去部分?jǐn)?shù)量的抵押品。一旦區(qū)塊鏈上(分配表)出現(xiàn)了一個抵押交易,那么礦工就可以向存儲市場提供他們的存儲空間,并且可以設(shè)置一定的價格,并生成一個賣單掛到市場的訂單賬本中。
2.3.1.2 接收訂單
接收訂單的主要目的是為了從存儲市場中獲取存儲請求。系統(tǒng)就會檢查礦工在存儲市場上的賣單是否與對應(yīng)的來自客戶端的買單相匹配。一旦賣單和買單想匹配,那么客戶就會將自己的數(shù)據(jù)發(fā)送給存儲礦工。而實際上,礦工收到的是一個個數(shù)據(jù)片。當(dāng)存儲礦工收到數(shù)據(jù)片后,就把數(shù)據(jù)存儲到自己的硬盤中,與此同時,礦工和客戶端都會簽署一個交易訂單,并將之提交到區(qū)塊鏈上。
2.3.1.3 密封
密封的目的是為未來的證明準(zhǔn)備數(shù)據(jù)片。存儲礦工的存儲空間被分為幾個扇區(qū),每一部分都包含分配給礦工的數(shù)據(jù)片。網(wǎng)絡(luò)通過分配表對每個存儲礦工的各個存儲扇區(qū)進(jìn)行跟蹤。當(dāng)一個存儲扇區(qū)存儲滿了之后,該扇區(qū)就會被密封。密封操作過程很慢,它需要依次將一個扇區(qū)的數(shù)據(jù)轉(zhuǎn)換保存為一個副本。而每個數(shù)據(jù)的物理拷貝都與存儲礦工的公鑰相關(guān)聯(lián)。
2.3.1.4 證明
存儲礦工需要證明他們存儲了提交的數(shù)據(jù)片。當(dāng)存儲礦工被分配到一個數(shù)據(jù)的時候,他們必須重復(fù)生成數(shù)據(jù)副本證明,以此來保證存儲礦工確實保存了數(shù)據(jù)。該證明將推送到區(qū)塊鏈中,并被全網(wǎng)驗證。
2.3.2 檢索挖礦
檢索挖礦分為兩部分:接收訂單和發(fā)送。
2.3.2.1 接收訂單
索引礦工從索引市場中獲取數(shù)據(jù)請求。索引礦工通過向網(wǎng)絡(luò)中傳播賣單來宣布他們的數(shù)據(jù)片。他們設(shè)置一個價格,然后添加一個賣單到市場的訂單賬本中。然后,索引礦工檢查他們的訂單是否與對應(yīng)的客戶買單相匹配。
2.3.2.2 發(fā)送
一旦訂單匹配,索引礦工將會發(fā)送他們的數(shù)據(jù)片給客戶端??蛻舳耸盏綌?shù)據(jù)片后,礦工和客戶端簽署一個交易訂單并提交到區(qū)塊鏈中。
3 結(jié)語
區(qū)塊鏈,尤其是公有鏈中,為了保障系統(tǒng)的安全性,容錯率達(dá)到50%的PoW共識機(jī)制似乎是個好的選擇。但是它也帶來了嚴(yán)重的能源浪費(fèi)問題。這個能源能源浪費(fèi)問題包含兩個方面,一個指能源浪費(fèi),一個指礦機(jī)的浪費(fèi)。能源浪費(fèi)指的是礦工需要消耗大量的電力來進(jìn)行挖礦。以比特幣為例,當(dāng)前的比特幣網(wǎng)絡(luò)全網(wǎng)算力為5000PH/S,而阿瓦隆即將發(fā)布的Avaon741礦機(jī)單機(jī)算力為8TH/S,所用功率為1150瓦,即使全網(wǎng)礦機(jī)全部更換為最新礦機(jī),全網(wǎng)一天仍要消耗約1700萬度電力能源。無疑,這是一種巨大的能源浪費(fèi)。
礦機(jī)浪費(fèi)指的是廢舊的礦機(jī)無法二次利用。以比特幣ASIC礦機(jī)為例,該種礦機(jī)通過對底層的硬件進(jìn)行定制優(yōu)化,使其做哈希運(yùn)算速度明顯高于顯卡礦機(jī),但是正因為這一點(diǎn),所以導(dǎo)致了比特幣ASIC礦機(jī)在挖礦淘汰后就無法二次利用。而以太坊挖礦主要以顯卡為主,其挖礦淘汰后仍然可以被個人電腦收購使用。同樣,F(xiàn)ilecoin礦機(jī)挖礦淘汰后仍然可以被普通用戶加以利用,這和以太坊一樣,均在一定程度上減少了能源浪費(fèi)。
然而,通過以上三個典型算法的說明,我們發(fā)現(xiàn)區(qū)塊鏈中的挖礦算法既要保證系統(tǒng)的安全,又要盡可能的降低能源浪費(fèi),這是個很難同時滿足的要求。這同時也說明了,區(qū)塊鏈系統(tǒng)的安全性是需要以一定的能源浪費(fèi)為代價的。
參考文獻(xiàn)
[1]Nakamoto S. Bitcoin: A peer-to-peer electronic cash system[J]. Consulted, 2008.
[2]Back A. Hashcash - A Denial of Service Counter-Measure[C]// USENIX Technical Conference.2002.endprint