一場靠出力才能中獎的彩票
想像世界各地有成千上萬的陌生人,誰也不是主管,卻都想寫下一本共享帳本的下一頁。如果他們同時動筆,結果只會是一片混亂——互相打架的頁面,誰也不服誰。工作量證明用一個極其簡單的想法解決了這件事:別投票,去幹活。想贏得添加下一個區塊的權利,你得先贏一場彩票——而買彩票的唯一方式,就是實打實地燒掉算力。誰付出了這份力氣、又恰好先碰上運氣,誰就贏;其餘所有人都能在一瞬間核對這個結果。
跑這場比賽的人叫礦工,比賽本身就是挖礦。叫它「挖礦」是個比喻:就像挖金子一樣,你付出力氣卻沒有回報的保證,而每隔一陣子才會挖到一次。我們來看看他們究竟在挖什麼。
謎題:雜湊要落在目標之下
這道謎題用到密碼學雜湊——一種把任意資料變成定長亂碼數字的函數。它有兩點特別適合做彩票。第一,你無法預測輸出:把輸入改動一個字元,結果就會跳到一個完全不同、看起來隨機的數字。第二,你無法倒著算它:沒有捷徑能找出一個輸入,讓它正好給出你想要的數字。唯一的辦法就是猜、算雜湊、核對、再來一遍。
要建構一個區塊,礦工先把待處理的交易收集起來,再配上一個概括該區塊的小小區塊頭。區塊頭裡有一個欄位礦工可以隨意改動:隨機數(nonce,意為「只用一次的數」)。礦工要做的,就是找到一個隨機數,使得對整個區塊頭求雜湊得到的數字足夠小——具體來說,要小於一個叫做目標值的門檻。把獲勝條件寫成一道簡潔的不等式,就是:
hash( block_header_with_nonce ) < target nonce = 0 -> hash = 9c4f...e1 (too big, no) nonce = 1 -> hash = 71a0...3d (too big, no) nonce = 2 -> hash = a8b2...ff (too big, no) ... nonce = 49281-> hash = 0000a3...7 (below target -> WIN!)
難找,卻一秒可驗
讓整套系統得以運轉的魔法就在這裡。找到一個中獎隨機數極其困難——沒有巧妙的方法,只能盲目試錯,所以一個礦工可能要算上萬億次雜湊,才碰到一個落在目標值之下的。可一旦找到了,任何人只用一次雜湊就能驗證:拿過區塊頭和那個幸運隨機數,求一次雜湊,自己看看結果是不是低於目標值。產出代價高昂、驗證輕而易舉——這種不對稱,正是工作量證明的核心。
這就是為什麼誰也不必信任誰。一個中獎的區塊自帶它的證明:那個隨機數本身,就是「有人真的燒掉了算力」的證據。你信這個礦工,不是因為他和善或有官方身分——而是因為你能自己重算一次雜湊,數學對得上。
難度讓節奏保持穩定
如果目標值固定不變,那麼隨著礦工增多或換上更快的機器,這場比賽會越跑越快——區塊來得太快,又不可預測。於是網路會按既定節奏調整目標值,這套機制叫做挖礦難度。規則是自我校正的:如果最近的區塊來得太快,網路就調低目標值(提高難度),要求更多前導零;如果區塊來得太慢,就調高目標值(降低難度)。
最長的鏈獲勝
有時兩個礦工幾乎同時中獎,網路就會短暫地分成兩條互相競爭的鏈。沒有裁判來定奪。取而代之的,是一條機械而著名的規則:誠實的礦工總是在累積工作量最多的那條鏈上繼續建構——實際操作中,就是最長的有效鏈。下一個區塊落在哪條分支上,哪條就勝出,較短的分支乾脆被放棄。它裡面的交易會退回等待池,留待以後再被收錄。
這就是為什麼那麼多力氣換來的是安全。要改寫一個舊區塊,攻擊者得重做它的工作量,還要跑贏真鏈上每一個誠實礦工——一場接一場地重新中獎,速度還得超過世界上其餘所有人加起來。一個區塊被埋得越深,這件事就越是貴到不可能,這正是為什麼一個舊區塊會被當作已成定局。
這一切的猜測都靠電力運轉,那份能耗是真實存在的——它就是讓這條鏈「攻擊起來很貴」的字面意義上的代價。把工作量證明講清楚之後,下一篇會看另一台偉大的共識引擎,它用鎖定的權益取代了被燒掉的電力。