1. 程式人生 > >精讀比特幣論文

精讀比特幣論文

公私鑰 計算 相同 特殊 傳統 ash 自己的 led root

上一次讀比特幣論文還是幾年前,在區塊鏈大火的今天,決定仔細重讀一下,並寫下讀後感。

本文試圖以一種從宏觀到微觀,先靜態後動態的敘述方式,描述比特幣系統,文中絕大多數內容來自於中本聰的比特幣論文,加上了一些自己的理解。

世界地圖上看比特幣

時至今日,比特幣在物理上已是包含一萬兩千多個節點的,遍布全球的分布式系統。其中的每一個節點可能是普通的筆記本電腦、臺式機、服務器、也可能是專用的“礦機”,歸根結底,是一臺具備計算和存儲能力的計算機。這些節點通過Internet連接在一起,使用TCP/IP協議通信。

技術分享圖片

節點

每一個比特幣節點上存儲的數據是相同的,或者說是大致相同的。換句話說,比特幣系統裏面的每一個節點,都擁有所有的比特幣數據。這些數據以一種叫做區塊鏈的數據結構組織在一起,使得數據一旦存儲到鏈上,就不容易被篡改。

技術分享圖片

區塊的大小是最大1MB,由一些不同類型的數據組成,其中一部分是它前一個區塊Hash值,這樣每一個區塊都包含一個指向前一個區塊的Hash,構成了一個非常普通的數據結構,鏈表,稱之為區塊鏈。區塊鏈的巧妙之處在於難以篡改數據,如果要修改鏈上某個區塊內的數據,它的Hash值就會變,這樣其後的每一個區塊都會變。

區塊

區塊由header和body兩部分組成,整體大小的最大值為1MB,其中header占80個字節。header中包含了前一個區塊的Hash值、本區塊body內容的hash值、以及填充數據Nonce。其中填充數據Nonce用來調整控制當前區塊的Hash值,其作用,在接下來描述區塊如何生成時再介紹。

技術分享圖片

事實上,所謂區塊的Hash值,指的是區塊的80字節大小的header的Hash值。那區塊鏈如何保證body的內容不被篡改呢?是使用了一種名為Merkle Tree的數據結構。

In cryptography and computer science, a hash tree or Merkle tree is a tree in which every leaf node is labelled with the hash of a data block and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes. Hash trees allow efficient and secure verification of the contents of large data structures. Hash trees are a generalization of hash lists and hash chains.

這樣,通過在葉子節點存儲實際數據,逐層計算Hash,最終將根節點Root Hash保存到區塊header中,使得任何一個葉子數據發生變動,從根節點到該葉子節點路徑上的Hash值,包含Root Hash在內都要發生變動。從而保證了數據不被篡改。

那麽這樣做帶來了什麽好處呢?這給區塊鏈帶來了刪除數據的能力,即Merkle Tree葉子節點的數據不能被修改,但可以直接刪除不再保存,而其Root Hash不變,區塊的Hash也不會變。這一點保證了區塊鏈在不斷增加新區塊的過程中,數據不會爆發性增長,使得區塊全都存儲在一個單計算機節點上,成為可能。

在比特幣系統裏面,組成區塊body的Merkle Tree的葉子節點存儲的,是一個交易。

交易

比特幣裏面交易用來將比特幣從一個人傳遞給另一個人,跟現實世界一個人付錢給另一個一樣。不同的是,現實世界需要錢這個實體,需要錢背後的政府背書,而比特幣世界裏面,交易既表達交易本身,又代表了比特幣的持有權。

技術分享圖片

所以每一筆交易都包含了之前一筆交易的Hash值,用來做輸入;同時包含交易對象的公鑰,用來做輸出。這樣比特幣的所有權就從之前一筆交易包含的公鑰所對應的私鑰的持有人,轉移到了當前這筆交易包含的公鑰對應的私鑰的持有人。

當然,因為私鑰代表了對一筆交易的所有權,每一筆交易都必須要使用作為其輸入的交易包含的公鑰對應的私鑰進行簽名,才生效。

持有私鑰就可以交易,那麽怎麽避免持有人將一個比特幣,支付給多人,也就是說怎樣解決雙花問題?答案是,所有交易數據都是公開的,存儲到區塊鏈上,不能篡改的,這樣在驗證一個新交易時,通過遍歷已有交易,可以判斷出是否存在雙花現象。

交易鏈

論文中將比特幣定義為一個交易鏈,其所有權在交易中流轉,持有最後一筆交易中公鑰所對應私鑰的人,擁有該交易鏈所代表的比特幣的所有權。

技術分享圖片

現實中的交易,可能有一次消費多個幣,可能有找零,等需求。考慮到這一點,論文中將交易擴展為支持多個輸入交易和多個輸出公鑰,至此,一次可以消費多個幣,一個幣也可以掰開來花。

技術分享圖片

比特幣的誕生

代表比特幣的交易鏈中每一筆交易都至少要有一筆交易作為輸入,那第一筆交易哪來的呢,也就是說,比特幣何時誕生呢?

區塊的body由交易組成的Merkle Tree組成,而每一個區塊內的第一筆交易,是一筆特殊交易,特殊之處在於沒有輸入,用來獎勵該區塊的生成者。這樣隨著交易增多,區塊就增多,而隨著區塊增多,比特幣/交易鏈也增多,相當於貨幣不斷增發。

誰來生成區塊

第一個區塊是中本聰生成的,稱之為創世區塊,也是唯一一個不含其它塊的Hash的區塊。其余的區塊都是由比特幣節點生成,節點收集網絡上尚未被確認的交易,進行確認後組成區塊,同時將區塊添加到區塊鏈上。

一萬兩千多個節點,由哪一個節點來生成呢?比特幣使用一種較為POW的機制來達成共識,比特幣規定了每個區塊的Hash值末尾的幾位必須為0,這樣節點在計算區塊header的Hash值時,就必須不斷調整填充字段Nonce的內容,以滿足Hash值要求。由於Sha256這種Cryptographic hash的特性,計算特定的Hash值十分困難,需要大量的計算資源。而當一個節點找到符合條件的Nonce時,其它節點驗證起來又特別的容易。

節點都在不斷的計算新的區塊的Hash值的過程,就稱作挖礦,新區塊的獎勵交易,也就是挖礦的收益了。因為網絡上的節點都在挖礦每個節點都有挖到的可能,並且網絡也存在分區的可能(比如海底光纜被挖斷、遭到了網絡攻擊等),網絡上可能存在多條合法的區塊鏈,當出現這種情況時,論文規定,長鏈勝出,短的被拋棄,其上與長鏈不一致的交易,也會被取消。

如果節點在某一時刻,收到了兩條長度相當的區塊鏈,那麽它會同時保存兩條鏈。同時,在收到的第一條上進行挖礦,直到隨著交易進行,兩條鏈有一條勝出,則拋棄失敗的那條。

貨幣發行政策

作為一種貨幣,比特幣也有其貨幣政策,前面也提到隨著區塊生成,貨幣不斷增發。有一個問題是,隨著比特幣網絡不斷壯大,節點越來越多,生成新區快的速度也會不斷增加,這會導致比特幣數量不斷增多。為了解決這個問題,論文中描述了一種Hash值計算難度自動調節的機制,通過根據區塊生成速度,自動調整Hash值末尾0的個數,使得貨幣發行速度不受全網算力的影響。

按照論文的設計,當發行到一定數量後,計算出新區塊不再受到比特幣獎勵,即不再有貨幣發行。比特幣數量維持穩定,生成區塊的節點,只收到交易手續費用的獎勵。交易手續費,指一筆交易中,輸入大於輸出,則多余的被當做交易手續費,相當於打賞比特幣節點的小費。小費高的交易,更容易吸引節點,因此更容易被確認,交易速度更快。

隱私保護

跟傳統銀行交易只提供給本人查詢不同,比特幣的交易是對所有人公開的。但比特幣的所有權是靠RSA密鑰來證明的,即比特幣系統不保證交易的隱私性,但保證了比特幣持有人的匿名性。

安全驗證

只要掌控一定數量的算力,就可以攻破比特幣共識協議,使得已確認的交易能夠被撤銷。論文中,對安全問題進行了論證,主要是討論了,在不同的算力比例下,需等待多少個區塊領先後,交易就可以被認為是安全的。此處不再贅述了,有興趣去論文詳讀。

相比算力攻擊,網絡攻擊似乎更容易些。只要刻意制造一個小的網絡分區,就很容易使得分區內的交易被撤銷。但論文中也提到,即便黑客控制了更多算力等,也只能撤銷交易,進行欺詐。受益於交易鏈公私鑰的所有權證明,黑客並不能花別人的錢。

比特幣為什麽值錢

因為大家相信它值錢。法幣的背後是國家政府信用,比特幣更多靠信仰吧,跟黃金一樣。

總結

論文描述了比特幣系統的整體設計,一個非常精致的分布式計算系統。當然有一些工程和安全上的問題沒有討論到,但已經足夠精致了,很聰明,讀起來過癮。

熟悉分布式存儲系統,分布式共識算法的人應當對文中的很多概念特別熟悉,我覺著也會有一些疑惑,覺著有一些問題,比如對網絡的假設太簡單,只考慮replication沒考慮sharding等等。後面我會找機會去讀下代碼和衍生系統,期待更多的驚喜。

精讀比特幣論文