這一節(jié)我們會涉及到比特幣一個很關(guān)鍵的問題抚笔,工作量證明扶认。這部分的內(nèi)容偏多,我會拆分成幾個小塊分析殊橙。
本系列歷史文章列表
從零開始區(qū)塊鏈:對等網(wǎng)絡(luò)與電子現(xiàn)金是什么蝠引?——比特幣經(jīng)典論文研讀 (1)
從零開始區(qū)塊鏈:如何防止一筆錢花兩次阳谍?——比特幣經(jīng)典論文研讀 (2)
6.時間戳服務(wù)器
在郵政領(lǐng)域里,有一個概念叫“郵戳”螃概, 一般標(biāo)明郵件寄出或者收到的時間地點(diǎn)矫夯。時間戳就是服務(wù)器給數(shù)據(jù)塊加上時間標(biāo)記,用于標(biāo)識數(shù)據(jù)和時間的關(guān)系吊洼。時間戳服務(wù)器把當(dāng)前數(shù)據(jù)塊的哈希值打上時間戳后训貌,發(fā)布到網(wǎng)絡(luò)中。這就證明了在標(biāo)識的時間刻度下冒窍,這個數(shù)據(jù)是存在的递沪。每一個時間戳對應(yīng)的數(shù)據(jù)塊中,包括了前一個數(shù)據(jù)塊的時間戳哈希综液,于是這樣可以形成數(shù)據(jù)鏈款慨。
關(guān)于這一部分作者并未作詳細(xì)論述,我們接著往下走谬莹。
7.工作量證明(1)
這一段講的是工作量證明的問題檩奠,有幾個知識點(diǎn)需要儲備:
(1) 設(shè)計原型 HashCash
作者提到了一個叫HashCash(哈希現(xiàn)金)的工作[12]附帽。HashCash最初設(shè)計的目的是為了防止DoS(拒絕服務(wù)攻擊)埠戳。
拒絕服務(wù)攻擊的意思就是,如果你要攻擊一個服務(wù)蕉扮,就發(fā)起虛假的服務(wù)請求整胃,讓服務(wù)不得不響應(yīng),消耗了資源喳钟,讓真正需要服務(wù)的人得不到服務(wù)屁使,于是“拒絕服務(wù)”了。比如奔则,如果你開了一家小賣部屋灌,有一天來了很多人,擠滿你的店应狱,只詢問不購買共郭,你忙著招呼這些人,那真正要買東西的人就進(jìn)不來疾呻,于是對他們而言除嘹,店面就癱瘓了。
但是你開店的目的就是為了接客賣貨賺錢岸蜗,所以你還不能把店給關(guān)了尉咕。就像網(wǎng)絡(luò)上的服務(wù)一樣,服務(wù)設(shè)立的目的就是為了接收請求的璃岳,而當(dāng)你受到DoS攻擊干擾的時候怎么辦年缎?于是你只能想大致檢查一下悔捶,這個請求是不是真正的請求,客戶是不是真的要買東西单芜,還是在搗亂蜕该。
那要怎么檢查?在網(wǎng)絡(luò)上洲鸠,就讓請求者做一些事情堂淡,這些事情要有這樣的特征:做到這件事情要付出一些代價,檢查有沒有做到扒腕,只要很少量的代價绢淀。因為攻擊者的資源也有限,所以發(fā)起的攻擊也不能完全模擬成像真的一樣瘾腰,有很多虛假的攻擊可以通過一些方法過濾掉皆的。我們生活中的驗證碼其實也是這個思路,你把在一堆亂花叢中的文字挑選出來蹋盆,需要花費(fèi)功夫费薄,服務(wù)器只要對個答案就好了。
HashCash設(shè)計了一個“代價函數(shù)(cost-function)”怪嫌,這個函數(shù)的特點(diǎn)就是,要計算出結(jié)果工作量較大柳沙,但是要驗證起來很容易岩灭。具體而言,就是代價函數(shù)讓發(fā)起請求的人赂鲤,算出一個“token”出來噪径。這里的token取了雙關(guān)的含義:一方面,這是一個符號或者標(biāo)識数初,另外一方面這個和區(qū)塊鏈里的“代幣/通證”對應(yīng)一個英文找爱。下文如無特殊注明,我統(tǒng)一用“通證”代表token泡孩。
HashCash把計算這個通證的函數(shù)取名叫作Mint()车摄,記得比特幣論文前面作者也用了mint這個詞么?這個詞有造幣廠的含義仑鸥,在第2篇文章的第5部分里吮播,我先沒有譯出,而是選用了“權(quán)威機(jī)構(gòu)”來表示眼俊。到這里就能串起來意狠,因為在HashCash中,采用了“造幣廠”的隱喻疮胖,來代表“代價函數(shù)”生成一個通證环戈。你想一下闷板,在生活中,造出一枚硬幣院塞,或者印出一張鈔票遮晚,是不是也是一件不容易的事情?但是驗證鈔票的真?zhèn)纹扔疲鋵嵰仍斐鲡n票鹏漆,容易許多。密碼學(xué)家忙活半天创泄,本質(zhì)就是為了在網(wǎng)絡(luò)上艺玲,構(gòu)建出和現(xiàn)實世界想同屬性的數(shù)學(xué)結(jié)構(gòu)。
于是HashCash就可以總結(jié)出如下模式:
對應(yīng)到防止拒絕服務(wù)攻擊的場景下鞠抑,就這樣用饭聚。如果我要驗證客戶的身份,我就讓客戶通過Mint()函數(shù)給我一個通證T搁拙,這個通證的參數(shù)w就代表了工作量的大小秒梳,s可以理解為自定義的參數(shù),這里先不考慮箕速。然后我就可以通過Value()函數(shù)檢查一下酪碘,到底是不是正確的,也就是盐茎,到底有沒有包括這么多的工作量兴垦。
這個“做到困難,驗證容易”的現(xiàn)象字柠,在我們生活中其實很常見探越。
(1)?你高中刻苦三年,最后拿到了一張清華錄取通知書窑业,這個很難钦幔;但是拿著你的通知書編號去檢查一下真假,這個很容易常柄。
(2)?你辛辛苦苦地解出一道數(shù)學(xué)方程鲤氢,這個很難;但是拿著你的答案西潘,代入驗算一下铜异,這個很容易。
(3)?你經(jīng)歷各種磨難秸架,做了很多事情揍庄,最后領(lǐng)悟到成長的幾條真諦,這個很難东抹;別人看了你的文章蚂子,感覺很有道理沃测,這個很容易。
你有沒有發(fā)現(xiàn)食茎,生活有很多類似的“非對稱”的結(jié)構(gòu)蒂破,從一頭到另一頭,其實挺難的别渔,但是反過來看附迷,卻容易許多。我們在網(wǎng)絡(luò)空間構(gòu)建信任哎媚,其實就是要利用這樣的“非對稱”的數(shù)學(xué)現(xiàn)象喇伯。
(2) 哈希函數(shù) Hash Function
哈希函數(shù)又稱為散列函數(shù)。在我大一接觸這個概念的時候拨与,其實很喜歡“散列函數(shù)”這個譯法稻据,感覺有。學(xué)到后面發(fā)現(xiàn)买喧,在科技領(lǐng)域里“有技術(shù)捻悯、沒文化”是普遍現(xiàn)象,于是也隨波逐流地用“哈希函數(shù)”了淤毛。
哈希函數(shù)在密碼學(xué)里有廣泛的作用今缚,甚至可以說是密碼系統(tǒng)安全性的基石。簡單的理解低淡,哈希函數(shù)具備一個功能姓言,可以把任意長度的數(shù)據(jù)(字符串、文件查牌、數(shù)字事期、內(nèi)存區(qū)塊)滥壕,歸一到一個相同的長度纸颜。因為在計算機(jī)里,即使是文件绎橘,也是二進(jìn)制胁孙,也是可以最終轉(zhuǎn)換成數(shù)字的。經(jīng)過哈希函數(shù)算出的結(jié)果称鳞,我們稱為哈希值涮较,也會叫作消息摘要(digest)。
如果是初次接觸這個概念冈止,就把握好這么幾個要點(diǎn):
(a) 把變長轉(zhuǎn)換為定長狂票。不管是什么數(shù)據(jù),經(jīng)過哈希函數(shù)處理后熙暴,長度都是一樣的闺属。
(b) 計算容易倒推難慌盯。給定一串字符,算出一個哈希值很容易掂器,但是根據(jù)哈希值反推字符內(nèi)容亚皂,很難。
(c) 哈希值對細(xì)節(jié)敏感国瓮。如果把字符串修改一個字母灭必,算出的哈希值都完全不一樣。這個再延伸一下乃摹,你可以認(rèn)為哈希的結(jié)果近乎是隨機(jī)數(shù)禁漓。
如果你是一個會思考的讀者,你可能會有一個問題:任意長度的數(shù)據(jù)可以有無限多個峡懈,但是轉(zhuǎn)換到固定長度璃饱,卻是只有有限個,那會不會出現(xiàn)兩個不同的字符串算出來是一個哈希值肪康?
的確是會有的荚恶,這個叫作哈希函數(shù)沖突或者哈希碰撞。在密碼學(xué)里面磷支,這個需要通過分析并且將概率嚴(yán)格控制到一定比例以下谒撼,以至于用現(xiàn)有的計算條件無法輕易地找到相同的哈希值。這就像你家里的鑰匙雾狈,其他人的鑰匙一般不能打開你的鎖廓潜,如果兩個人分別買兩把鎖,鑰匙卻能通用善榛,那說明鎖有問題辩蛋,安全性就得不到保證了。
哈希函數(shù)是一種數(shù)學(xué)上的構(gòu)想移盆,現(xiàn)在有很多不同的實現(xiàn)悼院,有的因為年代久遠(yuǎn),安全性已經(jīng)不能保證咒循,已經(jīng)不建議采用据途,例如MD5;但是有的現(xiàn)在仍然會使用叙甸,比如比特幣就SHA-256來做工作量證明颖医。至于具體這些函數(shù)是怎么算出來的,有相關(guān)的文檔裆蒸,如果有興趣熔萧,在互聯(lián)網(wǎng)上可以找到算法,讀完以后你會更加懷疑自己的智商。
(3) 通過哈希碰撞難度佛致,控制計算機(jī)工作量
有了以上知識的鋪墊遂赠,下面要講到怎么利用哈希函數(shù)來控制工作量了。
我們已經(jīng)知道晌杰,可以通過讓某個程序來計算出一個通證的方式跷睦,來驗證工作量。這就是HashCash做的設(shè)計(HashCash也不是首創(chuàng)肋演,只是比特幣的參考)抑诸,現(xiàn)在簡單梳理一下HashCash怎么通過參數(shù)的方式來控制工作量。
這個公式看上去有點(diǎn)復(fù)雜爹殊,其實本質(zhì)比較簡單蜕乡。
Mint()函數(shù)就是計算能代表w工作量的通證,這里表示成一個哈希函數(shù)梗夸,要求結(jié)果左邊有w個零比特层玲。前文已經(jīng)說了,哈希函數(shù)算出的結(jié)果幾乎可以看成一個隨機(jī)數(shù)反症,現(xiàn)在要求這個隨機(jī)數(shù)的二進(jìn)制辛块,前w位都是0。
那有什么辦法可以快速算出通證T來么铅碍?沒有润绵。只能一個一個試。這就叫暴力破解胞谈。在密碼學(xué)尘盼,暴力破解幾乎算一種最管用但是也是最笨的方法。如果你把需要遍歷的空間搞得很大烦绳,那猜到的概率就很小卿捎。
這就像生活中的密碼是一樣的,如果密碼是四位數(shù)字径密,那我平均試1萬次就夠了午阵,多加一位,次數(shù)多10倍睹晒。這個道理可以遷移趟庄,我在自己的《刻意學(xué)習(xí)[13]》這本書里也講了“暴力破解”攻破你的成長問題括细。
好伪很,那么到現(xiàn)在,我們就可以用這個參數(shù)w來控制Mint()函數(shù)算出通證T的工作量了奋单。
比如锉试,假如我把w設(shè)置成1,那任意一個哈希值览濒,第1位要么就是0呆盖,要么就是1拖云,最多試兩次就搞定了,這是一個簡單工作应又。
假如我把w設(shè)置成2宙项,那任意一個哈希值,前兩位最多有00株扛、01尤筐、10、11四種情況洞就,平均要試四次盆繁,工作量翻番。
如果我把w設(shè)置成k旬蟋,那就是要從個可能結(jié)果里油昂,找出一個全部是0的結(jié)果。
如果k就等于哈希值的全部長度倾贰,就變成前面說的哈希碰撞了冕碟。
計算結(jié)果的難度可以通過上述的示例展示,但是計算結(jié)果的驗證呢匆浙?
假設(shè)我們的計算機(jī)拿出一個通證鸣哀,這個通證代表著前6位都是0的工作量。那我要驗證到底是不是有這么多的工作量吞彤,怎么辦呢我衬?我就只要算一次哈希,看一下結(jié)果是不是前6位都是0饰恕,就搞定了挠羔,對吧?這就是Value(T)做的事情了埋嵌。
于是你可以看到破加,計算出一個通證,和驗證一個通證的難度是不一樣的雹嗦。而計算通證的難度范舀,通過一個參數(shù),就可以控制了罪。
這有沒有點(diǎn)像在小學(xué)的時候锭环,班主任布置作業(yè),“課文抄5遍并背誦全文泊藕,家長簽字”辅辩,然后你要做很長的時間,才能拿到家長簽字的通證。所以你當(dāng)天晚上能不能睡覺玫锋,就取決于老師讓你抄5遍還是抄50遍蛾茉。
在工作崗位中,我們往往會通過產(chǎn)出量撩鹿、加班時間來看一個員工的工作量谦炬。在馬克思的《資本論》里,建立了剩余價值的理論體系节沦,揭露了資本對于勞動的壓榨剝削吧寺;在這一節(jié),我們發(fā)現(xiàn)了一種虐待計算機(jī)的方法散劫,通過讓計算機(jī)去算通證稚机,用來作為計算機(jī)的工作量證明。假如有一天获搏,機(jī)器之間也存在價值剝削與等級關(guān)系赖条,工作量證明可以不失為一項有效的衡量手段。
下一節(jié)我們繼續(xù)討論比特幣的工作量證明常熙。
參考文獻(xiàn)
[12] Back A, Others. Hashcash-a denial of service counter-measure[J]. 2002.
[13] Scalers. 刻意學(xué)習(xí)[M]. 北京聯(lián)合出版社, 2017.