為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹

      隨著比特幣接近主流采用和認可,其以挖礦為特征的基本安全模型每天都受到越來越多的關注和審查。人們越來越關注和關注比特幣挖礦對環境的影響、底層模型的安全性和去中心化程度,甚至量子計算突破對比特幣和其他加密貨幣未來的潛在影響。

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      很多時候,工作量證明被描述為“密碼學難題”,但真正的難題是什么?為了真正理解這些問題(以及任何可能的答案),您需要對比特幣挖礦本身及其演變有一個基本的了解。本文將探討工作量證明的所有技術組件和移動部分,以及它們如何相互無縫同步以使比特幣成為今天的去中心化平臺。

      為什么挖礦有效:加密單向哈希

      比特幣區塊鏈通常被描述為加密安全的數據庫,因此是不可變的。支持這種不變性和安全性的底層技術是加密哈希。密碼散列函數是一種數學函數,簡單地說,它接受任何輸入并將其映射到固定大小的字符串。

      然而,這些函數有四個特殊屬性,使它們對比特幣網絡非常寶貴。他們是:

      1. 確定性——對于加密散列函數的任何輸入,結果輸出將始終相同。
      2. 快速——在給定任何輸入的情況下,計算散列函數的輸出是一個相對較快的過程(不需要大量計算)
      3. 唯一——函數的每個輸入都應該產生一個完全隨機且唯一的輸出(換句話說,沒有兩個輸入會產生相同的輸出)
      4. 不可逆——給定哈希函數的輸出,無法獲得原始輸入

      這些規則為比特幣挖礦保護網絡提供了基礎。

      特別是比特幣協議的創建者中本聰選擇使用SHA-256 哈希函數作為比特幣挖礦的基礎。這是一個特定的密碼散列函數,已在數學上證明具有上述屬性。它總是輸出一個256 位的數字(最基本的計算單位),通常以 64 個字符的十六進制數字系統表示,以方便人類閱讀。

      SHA-256 函數的輸出通常稱為其輸入的哈希值。

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      哈希函數的輸入導致完全唯一的輸出

      這是一個 SHA-256 函數輸入和輸出的示例(您可以在這里自己嘗試一下):

      Input to SHA-256:
      <Bitcoin Transaction>
      Output to SHA-256:
      77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf

      有趣的是,在比特幣協議中使用散列的大多數地方,都使用了雙重散列。這意味著原始 SHA-256 函數的輸出隨后會直接放回 SHA-256 函數以獲得另一個輸出。這是該過程的樣子:

      Input to SHA-256(first round):
      <Bitcoin Transaction>
      Output (first round):
      77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf
      
      Input to SHA-256 (second round):
      77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf
      Output (second round and final result):
      3c6c55b0e4b607b672b50f04e028a6951aed6dc97b91e103fb0f348c3f1dfa00

      雙重哈希用于防止生日攻擊。生日攻擊是一種攻擊者能夠通過使用完全不同的輸入(稱為沖突)產生與另一個輸入相同的哈希的場景。這打破了唯一性的第三個屬性。沒有它,兩個完全不同的比特幣區塊可能會由完全相同的哈希表示,從而允許攻擊者潛在地切換區塊。

      使用 SHA-256 函數,這種攻擊發生的概率無限小。如果不是幾乎不可能,SHA-256 將被視為已損壞。

      然而,其他散列函數在過去已經被“破壞”了。為了防止 SHA-256 將來發生這種情況(并有效地破壞比特幣的安全模型),最好對hash 進行哈希處理。這將發生沖突的可能性減半,使協議更加安全。

      在非常高的水平上,比特幣挖礦是一個系統,其中所有比特幣交易都發送給比特幣礦工。礦工選擇價值 1 兆字節的交易,將它們捆綁為 SHA-256 函數的輸入,并嘗試找到網絡接受的特定輸出。第一個找到此輸出并將區塊發布到網絡的礦工會以交易費用和新比特幣的創建形式獲得獎勵。讓我們更進一步,深入了解比特幣區塊鏈本身,看看礦工究竟做了什么來確保網絡安全。

      比特幣挖礦:技術介紹

      引入挖礦是為了解決雙花問題。如果我有 1 個比特幣并將其發送給 Bob,然后嘗試將相同的比特幣發送給 Alice,網絡會確保只接受一筆交易。它通過稱為采礦的眾所周知的過程來做到這一點。

      在深入研究技術細節之前,重要的是要了解為什么需要挖礦來保護網絡。由于現在存在法定貨幣,我們持有的貨幣是由美聯儲創建和驗證的。由于比特幣在去中心化和共識的嚴格假設下運作,因此不存在任何中央機構來驗證該貨幣的發行并為其加蓋時間戳以及對該貨幣發生的任何交易的驗證。

      Satoshi Nakamoto 提出了當時唯一已知的解決方案,以在面向共識的系統中解決此驗證問題。這個方案在比特幣白皮書中被稱為工作量證明,它優雅地證明了交易是由那些愿意花費足夠的物理計算能量和時間來進行驗證的人驗證的,同時引入了誘導市場競爭的激勵措施。這種競爭使去中心化的特性能夠在生態系統中有機地出現和繁榮。

      塊內的外觀

      一個比特幣區塊主要由兩個部分組成:

      1.交易,以默克爾樹的形式

      采礦計算機收集足夠的交易來填充一個塊并將它們捆綁到一個默克爾樹中。

      merkle 樹是一個相對簡單的概念:交易作為葉子位于樹的底部,并使用 SHA-256 函數進行哈希處理。使用 SHA-256 函數再次對兩個葉子事務的組合進行哈希處理,以形成葉子的父節點。這個父節點與散列交易的其他父節點一起不斷向上哈希,直到創建一個。這個根的哈希實際上是它下面的交易的唯一表示。

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      默克爾樹的根是樹中每個交易的哈希值的組合?;叵胍幌?,對于散列函數的任何輸入,輸出都是完全唯一的。因此,一旦網絡上的大多數節點接收到一個挖掘的塊,默克爾樹哈希的根就充當該給定塊中所有交易的不可更改的摘要。

      如果惡意行為者嘗試更改塊中交易的內容,則其哈希值將被更改。哈希的這種變化將向上傳播到交易的默克爾樹,直到根的哈希改變。然后,任何節點都可以通過將更改塊的默克爾樹的根與有效塊的默克爾樹的根進行比較來快速捕捉到這種惡意行為。

      2.區塊頭

      區塊頭是區塊本身內容的摘要。它包含以下六個組件

      • 比特幣客戶端運行的軟件版本
      • 區塊的時間戳
      • 其包含交易的默克爾樹的根
      • 它之前的塊的哈希
      • 一個隨機數
      • 目標_

      請記住,交易默克爾樹的根充當區塊中每筆交易的有效摘要,而無需查看每筆交易。前一個塊的散列允許網絡按時間順序正確放置塊。這就是術語區塊鏈的來源——每個區塊都鏈接到前一個區塊。隨機數和目標是挖礦的關鍵。它們是解決礦工需要解決的 SHA-256 難題的基礎。

      請注意,塊頭中的所有這些數據都使用一種稱為little-endian的符號壓縮成 80 個字節,這使得節點之間的塊頭傳輸變得非常高效。出于解釋的目的,我們將忽略這種壓縮并假設數據是其原始形式。

      解釋采礦問題

      存儲在塊頭中的目標只是一個存儲在位中的數值。在傳統的以 10 為底的表示法中,這個目標的范圍在 0 到 222?(一個67 位以上?的數字)范圍內的某個地方,具體取決于有多少礦工同時競爭解決這個問題。

      回想一下,SHA-256 的輸出只是一個數字。礦工的目標是獲取當前區塊的頭部,向其添加一個稱為nonce的隨機數,并計算其哈希值。哈希的這個數值必須小于目標值。這里的所有都是它的。但說起來容易做起來難。

      回想一下 SHA-256 的第一個屬性:哈希函數的輸入總是會產生相同的輸出。因此,如果礦工拿到塊頭,對其進行哈希處理,并意識到哈希值不小于目標值,他們將不得不以某種方式更改輸入,以便嘗試找到低于目標值的哈希值。

      這就是nonce的用武之地。

      礦工在塊頭中添加一個數字(從 0 開始),稱為nonce,并對該值進行哈希處理。如果哈希值不小于目標值,礦工將隨機數加 1,再次將其添加到塊頭,并對更改后的值進行哈希處理。這個過程不斷重復,直到找到小于目標值的哈希值。

      采礦示例

      這是組成第一個塊頭的粗略近似值:

      • 創世區塊中交易的默克爾根:
      Merkle Root:
      4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
      • 第一個已知的比特幣版本:0.1.0
      • 區塊的時間戳:2009–01–03 18:15:05
      • 目標(這也是最高的目標):
      Target:
      0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
      • 沒有前一個區塊哈?!@是第一個區塊,所以這是一個獨特的案例

      將其組件添加在一起后的最終塊頭:

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      讓我們使用這個大標題并計算雙哈希:

      SHA-256 of header:
      7d80bd12dfdccbdde2c41c9f406edfc05afb3320f5affc4f510b05a3394e1c91
      
      SHA-256 of the previous result (final result):
      c5aa3150f61b752c8fb39525f911981e2f9982c8b9bc907c73914585ad2ef12b

      當轉換為以 10 為底時,目標和輸出哈希都是非常大的數字(請記住,長度超過 67 位)。下面的 Python 函數并沒有嘗試在此處演示兩者的比較,而是處理比較:

      def isBlockHashLessThanTarget(blockHash, target):
          return int(blockHash, 16) < int(target, 16)

      如果哈希值小于目標,則返回 True,否則返回 false。

      這是我們的目標和塊哈希的結果:

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      現在我們將原始塊的十六進制值加 1。這是以下結果:

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      注意由于添加了隨機數,最后一個數字現在是 1

      然后,我們運行相同的散列算法并對這些更改的數據進行比較。如果它不低于目標,請繼續重復。一旦找到成功的哈希,用于查找此解決方案的最新隨機數將保存在塊中。創世區塊上列出的隨機數是 2,083,236,893。

      這意味著中本聰在找到一個可以接受的哈希之前迭代了這個過程超過 20 億次。我已經為這個創世紀區塊挖掘過程編寫了一個小的 Python 實現,可以在我的GitHub 上找到。

      subhan-nadeem/bitcoin-mining-python
      bitcoin-mining-python - 比特幣挖掘算法的 Python 實現
      github.com

      看看你需要多長時間才能成功挖掘創世區塊!

      警告:extraNonce

      塊頭中的 nonce 值存儲為 32 位數字。這意味著任何人能夠達到的最高隨機數是232(大約 40 億)。經過 40 億次迭代,nonce 耗盡,如果沒有找到解決方案,礦工再次陷入困境。

      對此的解決方案是在coinbase(區塊的交易內容,存儲為 merkle 樹)中添加一個稱為extraNonce 的字段。這個 extraNonce 的大小僅受區塊本身大小的限制,因此只要區塊大小在協議限制范圍內,它就可以像礦工希望的那樣大。

      如果隨機數的所有 40 億個可能值都用完,則將額外的隨機數添加并遞增到coinbase。計算新的默克爾根和隨后的新塊頭,并再次迭代隨機數。重復此過程,直到找到足夠的散列。

      最好在nonce用完之前避免添加extraNonce,因為對 extraNonce 的任何更改都會更改 merkle 樹。這需要額外的計算才能向上傳播更改,直到計算出 merkle 樹的新根。

      礦工獎勵

      以最快的速度成功發布區塊的礦工將獲得憑空創造的全新比特幣獎勵。該獎勵目前為 12.5 BTC。這些比特幣是如何產生的?

      每個礦工只需在他們的區塊中添加一個新的輸出交易,在開始開采該區塊之前將 12.5 個比特幣歸屬于自己。網絡協議將在接收到新驗證的塊時接受此特殊交易為有效。這種特殊事務稱為生成事務。礦工有責任在挖掘之前將此交易添加到區塊中。至少有一個案例是礦工在挖一個區塊之前忘記將獎勵添加到交易中,有效地銷毀了 12.5 BTC!

      驗證工作量證明

      假設我們的礦工發現了一個小于目標的哈希值。該礦工所要做的就是將具有原始六個組件的挖掘塊發布到任何連接的節點。接收區塊的這個節點將首先驗證交易集,確保所有交易都是有效的(例如,所有交易都經過適當的簽名,并且硬幣不會被重復使用和/或無中生有)。

      然后,它將簡單地對塊頭進行雙重哈希?,并確保該值低于塊包含的目標值。一旦該塊被認為有效,新節點將繼續在網絡上傳播該塊,直到每個節點都有一個最新的分類帳。

      如您所見,任何給定節點都可以輕松驗證新發布的塊。然而,向網絡發布一個有效的區塊需要大量的計算能力(因此,電力和時間)。這種不對稱性使網絡得到保護,同時允許希望在網絡上進行經濟活動的個人以相對無縫的方式進行。

      出塊時間和調整目標

      當第一批礦工開始挖礦時,他們每個人都監控出塊時間。每個比特幣區塊都有 10 分鐘的固定區塊時間。這意味著,鑒于網絡上當前的計算能力(網絡哈希率)水平,節點總是希望平均每 10 分鐘產生一次新驗證的塊。我們可以合理地期望在 10 分鐘內生成塊,因為在給定網絡哈希率的情況下,找到塊的概率是已知的。

      例如,讓我們以比特幣中存在的最簡單的目標:創世塊。任何單個散列小于最簡單目標的概率是 232 中的 1。這是超過四十億分之一。因此,我們可以合理地期望有人運行 232 次挖掘問題迭代以找到合適的哈希值。網絡上的節點預計每 10 分鐘將在網絡上的所有礦工中運行 40 億次這樣的迭代。

      如果在大樣本量的塊中,塊開始出現的速度超過 10 分鐘,這非常清楚地表明網絡上的節點正在以比 10 分鐘快得多的速度迭代 40 億個哈希。這種情況促使每個節點根據網絡功率的增加(或減少)按比例調整目標,以確保每 10 分鐘繼續出塊。

      實際上,網絡上的節點監控2016個區塊的區塊時間,精確到兩周。每兩周,將總出塊時間與預期出塊時間(即 20160 分鐘)進行比較。

      要獲得新的目標,只需將現有目標乘以過去兩周的總實際出塊時間的比率即可得到預期出塊時間。這將根據網絡上進入或退出計算能力的數量按比例調整目標。

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天

      計算新目標的公式,每個比特幣節點每 20160 分鐘(兩周)運行一次

      出塊時間和輕松計算找到有效塊的概率的能力使節點可以輕松監控和確定網絡上的總算力并調整網絡。無論向網絡添加多少計算能力或增加速度有多快,平均出塊時間將始終保持在 10 分鐘。目前網絡上的總哈希率為每秒 28.27 exahash。即每秒在網絡上的所有計算機上運行28.27 x 101?哈希。

      為什么挖礦有效:加密單向哈希,比特幣挖礦:技術介紹-南華中天