最後我們要談一下比特幣協議的一些內在限制,以及優化的難度。在比特幣2009年剛問世的時候,它的協議有許多內在的硬性限制,那是因為在那時沒有人會想到它會發展成一個重要的國際貨幣。比如每個區塊的平均時間、塊的大小、每個區塊的簽名數目、切分性、比特幣總量、區塊獎勵結構等。
比特幣的總體數量與記賬獎勵很可能永遠都不會改變,因為那樣經濟影響太大。礦工與投資人都在比特幣現有的框架內投入巨資,如果這個框架改變了,會對他們產生巨大衝擊。所以,社區基本達成共識,不管這些特性好或不好,都不應該改變。
但其他一些方面的改善可以讓所有人受益——因為一些初始設計事後來看確實不太合理。其中最主要的是比特幣系統的交易處理能力。每秒鐘比特幣網絡到底可以處理多少交易?這個硬傷來自對區塊大小的硬性規定,每個區塊大小限定在1MB,每個交易大約是250字節,所以每塊最多容納4 000個交易。平均每隔10分鐘,有一個礦工獲得記賬權利,所以每秒鐘只能處理7個交易,這就是比特幣網絡的交易處理能力!似乎改掉這些限制只是需要改掉源代碼的某些常數這麼簡單,實際上卻並不容易,後面我們會簡單分析一下原因。
比特幣的交易處理能力到底屬於什麼水平?和前主流的一些信用卡公司相比,比特幣這個處理能力實在太低了。我們可以做一下比較:維薩(Visa)平均每秒處理2 000筆交易,峰值每秒處理10 000筆交易。貝寶(PayPal)的交易處理能力比維薩弱,但峰值時每秒也能處理100筆交易。比特幣無法處理這種量級的交易。
另一個限制是比特幣用的密碼算法。現在只有幾個哈希函數算法和一個簽名算法可以使用。比特幣使用的簽名算法是ESDSA——一種secp256k1的橢圓曲線數字簽名算法(見第1章),大家擔心在比特幣的一生(大家都希望是很長的一生)中,這個算法可能會被攻破。哈希函數也有同樣的問題,比特幣使用的SHA-1也有弱點,進10年來,對SHA-1的分析也逐步取得了一些進展(儘管並不致命)。為了改變這些問題,我們不得不加強比特幣的腳本語言來支持新的密碼算法。
修訂協議
那我們到底怎樣才能修訂比特幣協議並引入一些新特性呢?你也許認為這很簡單,只要發佈一個新版本,然後更新所有的節點。但事實上非常複雜,實際中,我們根本無法假定所有的節點都會更新版本。網絡裡的某些節點會無法獲取新版本,或無法及時獲取新版本。絕大多數節點更新了協議、部分節點沒有更新的後果是否嚴重,取決於協議更新的內容。按照產生的結果,協議修訂可以分為兩種類型:一種會造成硬分叉,另一種會造成軟分叉。
硬分叉
通過修訂協議引入新的特性,可能會使前一版本的協議失效。即運行新版協議的節點認定為有效的區塊,會被運行舊版協議的節點認定為無效。而由於我們不能確保每個節點都會更新協議,我們只能假定大部分節點已經升級(新節點),但還有部分節點沒有升級(老節點),很快,最長的那個區塊鏈分支裡包含的某些區塊會被老節點認定為無效區塊,因此,老節點會認為其他的分支(在這個分支中,所有新節點認為有效的區塊都會被排除在外)才是最長、有效的區塊鏈分支,並一直擴展這個分支,直到它們更新了版本。
這種改變稱為硬分叉,它使得原先的鏈分裂了。網絡上的所有節點會根據其所運行的協議版本去擴展兩條不同的區塊鏈,當然,這兩個分叉再也不會合併。那些老節點只要不更新版本,就被永遠地排除在了另一條鏈之外,這是比特幣社區所不能接受的。
軟分叉
另一種修訂是加入新的特性,讓現有的核驗規則更加嚴格。那樣老的節點依然會接收所有的區塊,而新的節點會拒絕一些。這樣的改變叫作「軟分叉」。這可以避免硬分叉所造成的永久分裂。
我們如果引入可以產生軟分叉的新版協議,會有什麼後果呢?運行新版協議的節點會使用一些更嚴格的規則,現在,假定絕大部分節點都更新了新版協議並執行新的規則(這是產生軟分叉的關鍵,因為老節點不會執行新規則,新節點的數量要足夠多才能夠競爭最長的鏈)。這種情況下,老節點可能會挖到一些無效的區塊——因為這些區塊中包含一些在新規則下無法核驗通過的交易,然後,老節點會知道它們核驗有效的區塊不被別的節點接受(即使它們並不知道原因),這使得老節點的礦工會去更新協議。而且,如果新節點用它們的區塊擴展了老節點的分支,那麼,老節點也會轉而擴展這個分支,原因是新節點核驗通過的區塊,老節點也必定能核驗通過。這樣就沒有硬分叉了,只是會有很多臨時的小型分叉而已。
本章3.2節提到的「支付給腳本的哈希值」就是軟分叉的一個經典例子。第一版比特幣協議裡並沒有P2SH。P2SH之所以造成軟分叉,是因為對老節點而言,一個有效的P2SH交易也可以核驗通過——它只驗證這個哈希值跟前一筆交易輸出哈希值是不是一樣而已,它並不知道還要進一步檢驗腳本是否合法。我們依賴新版節點去進行這項核驗:腳本本身真的可以獲取到前一個交易輸出的幣。
那我們到底可以通過軟分叉為比特幣協議添加哪些特性呢?P2SH是成功的,也許添加新的密碼算法也可以通過軟分叉實現。我們也可以通過軟分叉在元數據的幣基參數中添加更多的信息實現,目前,幣基參數可以是任何數值,但未來我們也許可以限定幣基參數的格式。已經有人提出,可以在幣基參數里放入一個梅克爾樹根,其中包含所有未被消費的比特幣的信息。這種做法只會造成軟分叉,因為老節點核驗通過的區塊,在新節點上可能無法核驗通過。但隨著區塊鏈的延長,很快老版本就會轉而去擴展最長的區塊鏈分支。
其他的一些改變可能就會產生硬分叉了,比如在比特幣裡添加新的功能操作代碼、改變區塊大小和交易規模,甚至其他一些修復性的改動。本章3.2節提到過MULTISIG指令存在一個缺陷,它會推送給堆棧一個莫名其妙的值,要修復這個缺陷,也會產生硬分叉。這就是為什麼儘管這個缺陷很煩人,但也一直沒有修復,因為和硬分叉相比,保留一個缺陷還是可以忍受的。有些修訂非常有意義,但目前比特幣環境不太可能接受硬分叉。但許多優秀想法都在其他的競爭幣中得到了測試而且成功運行,因為那些競爭幣系統是從頭開始建立的,硬分叉不會產生嚴重的後果。我們會在第10章進行更多的討論。
比特幣區塊大小的難題
因為比特幣變得越來越受歡迎,到2016年年初,已經開始經常發生區塊被交易寫滿的情況,尤其是當區塊在超過10分鐘後還沒有被礦工挖出來時(因為挖礦的隨機性,確實有些區塊在10分鐘後還沒有被挖到),這使得有些交易不得不排隊等待被寫進區塊鏈。但要改變區塊大小,就需要硬分叉。
究竟是否要改變,以及如何改變區塊大小,在比特幣社區裡有熱烈的討論。這些討論幾年前就開始了,但一直進展緩慢,無法達成共識,近來討論日趨激烈。我們在後面第7章會討論比特幣的社區、政治與管理。
隨著區塊大小問題得到共識解決方案,本章的一些細節有可能就會過時。提高比特幣交易處理能力的一些技術細節很有意思,我們鼓勵讀者可以通過網絡閱讀更多的資料。
到了這裡,你一定對比特幣的技術機制有了一定程度的瞭解,也知道比特幣節點是如何工作的。但是我們自身並不是一個比特幣節點,你不會在大腦裡運行比特幣節點程序。那我們到底如何和網絡進行交互,從而使比特幣可以成為一種貨幣呢?如何讓一個節點通知你交易信息呢?如何使用現金來交換比特幣呢?又如何儲存比特幣呢?對於如何創造一種可被人們使用的貨幣(而不僅僅是一個軟件)來說,這些問題至關重要,我們將會在下一章回答這些問題。
延伸閱讀
在這一章中我們討論了很多技術細節,你也許很難一次消化。作為本章的補充讀物,你可以上網查閱一些我們討論過的資料。網上有許多網站能讓你看到區塊和交易到底是什麼樣子的。比如有一個「區塊鏈瀏覽器」,網址是:blockchain.info。
還有一本比特幣開發手冊也很好地講述了一些技術細節(尤其是其中的第五、第六和第七章):
Antonopoulos,Andreas M. Mastering Bitcoin:Unlocking Digital Cryptocurrencies . Newton,MA:O\'Reilly Media,2014.