加入 PolkaWorld 社羣,共建 Web 3.0!
在區塊鏈世界中,大家都知道升級現有的區塊鏈很煩,比區塊鏈中任何東西都難搞。區塊鏈本質上是一寫即用:沒有辦法真正 “升級” 傳統意義上的區塊鏈,只能建立一個保留舊區塊的新區塊鏈。就好像把你已經死去的狗換成了同一品種的另一隻狗,然後為了安撫孩子們,你開始叫它同一個名字。只是在分叉時,原來的狗並沒有死,而且我猜新的狗植入了原來狗所有的記憶。這只是個不恰當的比喻,不用太認真。無論如何,我覺得你應該明白了。沒有升級,只有分叉。從區塊鏈誕生起,這種模式就一直存在。可能現在還有人的櫃子裡有一臺舊電腦,從 2009 年開始就在執行比特幣挖礦程式,所以傳統意義上,比特幣並沒有升級。假設你能找到那個櫃子和一個適配的老客戶端,你仍然可以連線到 2009 年的比特幣(估計大部分交易來自倒賣盜版《X戰警起源:金剛狼》的人)。
沒有升級,只有分叉。從區塊鏈誕生起,這種模式就一直存在。
升級區塊鏈很難
一般來說,這是分散式系統的問題,但像比特幣這樣的去中心化系統的問題是,沒有一個實體控制網路上的所有計算機。你不能給每一個比特幣礦工打電話,告訴他們必須升級。你可以給一些真正重要的比特幣礦工打電話,但這是一個 bug,不是比特幣網路的一個特性。
現在許多區塊鏈處理這個問題的方法是提前升級客戶端,升級後的客戶端同時支援網路的兩個版本和一個 if 語句,該語句在某個區塊數切換到新的程式碼。以太坊就是使用這個方法在定期更新。現在這個方法還不錯,但它並不能真正解決每次你想改變時都要分叉的問題,它只是給你時間。再說,這是不文明的。當倫敦投票選舉市長時,並不是按照政治路線分成倫敦和倫敦經典,而是選擇讓大多數人高興(或者更準確地說,讓大多數人較少反感)的市長。這種形式化的治理體系是減少區塊鏈生態系統不確定性所需要的。
現在,如果不信任第三方為你提供定期、可信的更新,就不可能擁有像在物聯網裝置中找到的那樣執行時間長的輕客戶端。不過老實說,在現實世界裡的大多數物聯網製造商,都是能不更新就不更新。安全更新物聯網裝置是一個難題,但大多數製造商根本不在乎。如果物聯網製造商在更新其軟體的時候,能達到執行區塊鏈節點所需的靠譜程度,那麼 Mirai 就不會發生。
當然,解決這個問題的另一個辦法是,永遠不要嘗試更新區塊鏈。這在很大程度上就是比特幣的解決方案,雖然可以說比起長期執行的輕客戶和治理,社羣更關注的是讓 10 家賺了點錢的礦工的 ASIC 投資作廢。不過,為了達成這篇文章的標題裡的主張,我們也將讓 “用不更新” 這種方法作廢,因為我覺得大多數人都會同意更新軟體是一件好事,而且通常是一個很好的啟發,讓你去思考一個主題,這與喜歡比特幣的人秉持的信念截然相反。
鏈上升級和其他難題
讓客戶端更新的一種方法是在鏈上部署整個客戶端。你可以使用某種鏈上治理方法來選擇是否接受該客戶端,然後如果接受,那麼世界上所有的客戶端都可以安裝新版本和透過 Linux 分叉,而不是區塊鏈分叉。當然,你不能僅僅在區塊鏈上部署二進位制檔案,首先,這基本上賦予了 government 在任何人的計算機上執行任意程式碼的能力。這不僅僅意味著他們可以在區塊鏈上做任何他們喜歡做的事情,而且他們可以把你的電腦變成殭屍網路節點,他們可以在你的圖片資料夾裡放滿 Danny DeVito 油畫(說真的,這是一個庫存驚人的藝術流派),甚至是挖比特幣(但願不會如此)。即使你完全信任鏈上治理,為每一個作業系統和每一個可用的架構部署二進位制檔案也是一個很大的組織管理問題。
假設我們在虛擬機器中執行整個客戶端。我們用 Java 或 Scala 編寫它,在區塊鏈上部署 Java 位元組碼,或者我們做一些類似於蘋果公司做的事情,用 LLVM 支援的本地語言編譯並部署 LLVM 位碼。好吧,這是更好的,但是不管你使用的 VM 格式是什麼,你都在很大程度上限制了你可以在其中構建客戶端的語言。另外,你還在區塊鏈上部署一個巨大的 blob,而在區塊鏈裡空間是很珍貴的(或者應該是很珍貴的,但實際上儲存租金並沒有得到廣泛的實現)。這忽略了這樣一個事實,即當你構建一個 LLVM 語言時,你會根據作業系統生成不同的位程式碼,蘋果只能逍遙法外,因為他們的作業系統在不同的裝置上,他們部署了相容的 api。
最後,在鏈上部署整個客戶端的任何策略最終都會遇到這樣的問題:處理回滾會將整個事情變成一場滑稽的鬧劇,因為回滾策略是由回滾的內容定義的。面對鏈上更新,定義分叉選擇規則或回滾策略沒有好的答案。
假設我們將定義區塊鏈邏輯的程式碼從其餘程式碼中分離出來,然後將其編譯為 VM 位元組碼。我所說的 “區塊鏈邏輯” 是指定義區塊鏈邏輯的程式碼。以太坊負責賬戶、餘額和智慧合約。ZCash 對交易進行零知識證明。比特幣的基礎計算效率極低。在一般情況下,是程式碼告訴我們如何根據交易更改狀態。我們在網路、實現速度等方面仍然存在競爭,雖然這意味著我們不能用這種方法更新網路程式碼,但是在一個分散式網路中保持多個不同版本的節點比讓這些節點在不斷更新的可變狀態上達成共識要好得多。我們可以使用像 libp2p 這樣的可擴充套件網路協商協議,允許新節點使用新的通訊協議,同時仍然允許舊節點參與。為了避免前面提到的回滾問題,我們必須將邏輯分離到共識級別以下。這意味著我們只能更改將交易對映到狀態更改的程式碼。這確實意味著我們不能改變分叉選擇的規則、回滾策略或共識演算法,但是我們必須在某個地方進行抽象權衡。共識演算法不能改變,因為它可能會使區塊無效,並且我們只能允許改變鏈上影響狀態的東西。
設計我們的介面
為了便於論證,並且因為你可能已經知道我在這裡要引入一些東西,讓我們將這個邏輯稱為區塊鏈的 “runtime”。如果我們從頭開始構建一個新的鏈,我們可以選擇自己的共識演算法等,我們希望使我們的程式碼儘可能通用。因此,我們希望讓 runtime 做出儘可能多的選擇。
假設我們想要同時支援許可的私有鏈和無許可的公有鏈。例如,如果我們選擇像 Tendermint 或 PBFT 這樣的 PoA 共識演算法,那麼我們可以同時擁有這兩種演算法,允許 runtime 選擇許可權。這意味著,如果我們想改變在許可權之間達成共識的方式,那麼我們仍然只能硬分叉,但實際上,這一系統最終還是非常靈活。使用在鏈上選擇許可權的 PoA 系統,我們可以建立許可鏈(意味著只有某些方可以參與網路)和無許可鏈(意味著任何人都可以參與網路)。我們可以對任何一種策略使用任意數量的策略,但例如,我們可以透過對權益不同的質押者進行隨機選擇,來確定許可權池(類似節點的意思),從而建立一個權益證明鏈。這解決了升級策略不確定的問題:升級不能追溯地更改前一個區塊的許可權集,只能更改未來許可權集的選擇方式。
runtime 還應該能夠自己決定何時升級以及如何升級,因為我們可以使用鏈上治理來執行這些升級。由於治理也是在 runtime 中定義的,這意味著你可以對 runtime 進行程式設計,以限制允許治理更改的內容。也許不允許改變治理結構本身,但其他一切都是公平的遊戲。也許它只允許調整一些小事情,但系統的基本規則必須保持不變。也許你可以改變任何事情,但不同的權力層次需要不同級別的票數。這完全取決於 runtime 的開發人員。
這是我們在 Parity Substrate 中採用的方法,Substrate 是我們在 Parity 基礎上構建的區塊鏈開發工具包。共識和網路由 Substrate 處理,鏈的邏輯、許可權選擇和自動升級由 runtime 處理。
是的,正如你現在可能已經收集到的,“runtime” 術語是從 Substrate 複製而來的。這也意味著你將影響共識的程式碼分離出來,你可以使用不同的後端。例如,在 Polkadot 中,我們可以在 “驗證人”、“提名人”、“收集人” 和 “釣魚人” 之間共享 Polkadot 特定的程式碼。即使節點扮演不同的角色,它們都可以就網路的狀態達成一致,並相應地採取行動。就網路而言,它們只在提交給網路的交易種類上有所不同。任何從外部世界獲取資料的東西,無論是一個節點的錯誤行為報告、天氣測量還是一個人向另一個人匯款,都被建模為一個交易,狀態被更新為對此的響應。我們在 Polkadot 中使用的 Substrate 允許我們以一種民主的方式對網路進行更改,不再需要任何客戶端,而且已經過測試:我們使用本文中解釋的確切方法將 Polkadot PoC1 升級到 PoC2。我們希望這種模式能夠在區塊鏈領域開創一個新的實驗時代,但這由你來決定。
歡迎學習 Substrate:
https://substrate.dev/
關注 Substrate 進展:
https://github.com/paritytech/substrate
關注 Polkadot 進展:
https://github.com/paritytech/polkadot
更多內容:
波卡 Polkadot.js 網站操作教程|新手必看
教程 | 如何在 Polkadot CC1 中對映並認領 DOT
Web3 基金會正式啟動 Polkadot 上線!
掃碼關注公眾號,回覆 “1” 加入波卡群
關注 PolkaWorld
發現Web 3.0 時代新機遇
點個 “在看” 再走吧!