今天的互聯網,已經發展了四十多年,從一個小型的科研項目,成長為數字觸角伸向世界的龐然大物。盡管核心的底層互聯網協議自20世紀90年代以來基本保持一致,互聯網的應用層和服務架構卻發生了極大的變化,以支持互聯網應用的爆發式增長。
建設互聯網應用的基本模型是上世紀90年代流行起來的客戶端/服務器模型。該模型短期利好,但長期帶來很多負面后果。Web應用順勢而起,但是導致Web服務愈加依賴于遠程服務器。云計算是基礎的客戶端/服務器模型的一個演進。今天,在云端存儲著私有的用戶數據,運行著應用業務邏輯和計算,管理著訪問權限,等等。
最近的十年里,我們開始看到云計算帶來的負面后果,人們由此開始質疑基于客戶端/服務器開發軟件的完整模型。大規模的數據泄露, 用戶隱私的喪失,數據缺乏可移植性,以及根植于客戶端/服務器模型核心設計帶來的科技巨頭間廣泛的互不信任。鑒于計算在人類社會中的重要性與日俱增,我們不能讓過時的計算模型來定義我們現在的生活方式。
云計算的下一步演進將利用更強勁的客戶端設備、邊緣計算和全球連接以減少對這些中心化平臺的依賴。趨勢已經朝著去中心化計算演進,我們相信這是計算機工業自大型機轉向桌面電腦以來最重大的技術變遷。去中心化計算可以改變軟件如何構造和使用。其提供給開發者一系列新的工具,改變了用戶和軟件之間的關系:軟件的存在是保護用戶,軟件的優化是為用戶利益至上。
Blockstack是一個開源軟件產品,在開源社區中設計、開發、成長為一個去中心化計算網絡,為傳統的云計算提供一個全棧的替代。Blockstack正在重新構想傳統互聯網的應用層,為去中心化應用提供一個全新網絡;構建于Blockstack之上的應用將使用戶擁有和直接控制他們自己的數據。Blockstack使用現存的互聯網傳輸層協議以及底層的通信協議,但是移除了應用層里的中心點。我們遵循端到端的設計原則,以保持網絡核心簡單,而將復雜性推送到客戶端。為了應用的可擴展性,我們將全局狀態變化最小化,提供一個可靠的去中心化存儲系統,其相比云存儲性能相當。而且,我們的全棧方法為所有開發者構建去中心化應用必須的棧組件提供了默認的選項。Blockstack是模塊化的,開發者可以輕易定制和集成其他替代技術。
設計目標
Blockstack的設計優化源于下列屬性:
1. 易使用。去中心化應用應該像現在的互聯網應用一樣容易被終端用戶所使用。此外,開發去中心化應用應該像在今天的云上開發一樣容易。
2. 可擴展。去中心化應用應該可以支持互聯網級別的用戶量,也就是數億到十億的用戶量。為了達到這點,網絡(包括區塊鏈)必須可以隨用戶數和運行的應用數量進行擴展。
3. 用戶控制。采用去中心化計算的應用應該默認由用戶控制。用戶應該可以提供自己的計算和存儲資源,而不是依賴于應用運營的服務器。
帶著這些設計目標,Blockstack做出了自己的設計選擇,將其與其他的“重”區塊鏈和“世界計算機”設計哲學的去中心化計算方案區別開來。
最小化區塊鏈層的邏輯和狀態:為了取得可擴展性,Blockstack在我們的“輕”區塊鏈層最小化了應用的邏輯和數據。使用區塊鏈操作記錄應用邏輯和存儲,本質上要比“鏈下”方法要慢。需要在全網范圍和設備間同步和驗證狀態,顯示出這種操作在吞吐量上極大的局限性。限制因素在于底層的全局連通帶寬和典型網絡節點上可用的內存/存儲,也就是物理限制(而不是任何協議的限制)。
本地狀態變化 vs. 全局狀態變化:Blockstack平臺使用全棧方法確保構建在Blockstack上的應用是可擴展的:與應用的交互盡可能改變本地的狀態,而不是全局的狀態。正因為此,我們的存儲系統和認證協議是我們平臺的基礎組件——其使得應用不發起一個區塊鏈交易,就可以和用戶的私人數據存儲交互,并且完成用戶認證。Stacks區塊鏈僅用于在去中心化的環境中,以一種一致的方式協調全局狀態的變換(例如:注冊一個全局唯一的用戶名)。
可靠的云存儲 vs. 對等存儲:在Blockstack上構建的應用,其數據存儲和用戶是一體的(使用用戶自己的私人數據鎖柜),不需要在服務器端保存任何用戶訪問憑證。這種方式不僅將用戶數據交由用戶自己控制,而且為開發人員降低了復雜度:開發人員無需運行服務器和數據庫,從而代替用戶支付云服務的賬單。此外,我們避免了點對點存儲固有的可靠性和性能問題,在一個去中心化的廣域文件系統中改變了現有云存儲提供商的位置——區塊鏈層只存儲指向用戶數據鎖柜的指針。
適用開發者的全棧SDK:Blockstack提供全棧方法,為開發去中心化應用所需的所有層提供了默認的選項。開發者SDK將區塊鏈的復雜性和其他開發技術抽離;應用開發者能夠使用Blockstack SDKs輕松構建他們的應用。技術棧的不同層次是模塊化的,可以根據需要使用其他技術。
與同期的去中心化計算方法除了這些不同外,我們的智能合約語言也做了獨特的設計決策來優化智能合約的安全和可預測性。
新應用模型
Blockstack為開發者構建應用提供了一個新的模型,確保應用是去中心化的,而且默認是由用戶控制的:
1. 無不透明數據庫:在客戶端/服務器模型中,數據庫是所有應用的核心組成部分,因為服務端需要存儲和查詢大量的用戶數據。在去中心化計算中,開發者無需擔心數據庫的維護和安全問題,因為他們從一開始就不做數據托管。開發者更多聚焦在應用邏輯上,用戶下載應用后,接入他們的私人數據鎖柜。如果使用數據庫的話,其功能等同于過去互聯網的“搜索檢索器”——索引公共數據的服務。任何人都可以使用底層(去中心化)的數據創建這些索引。
2. 無服務器:在客戶端/服務器模型中,應用通過增加服務器擴容,因為所有的計算都在服務端執行。在去中心化計算中,應用在客戶端運行,每個用戶將自身的計算和存儲能力帶入網絡(而不是依賴于應用開發者)。開發者只需提供最少的基礎設施托管應用代碼,因為每個用戶自帶所需的存儲和計算資源使用應用。
3. 智能合約:在客戶端/服務器模型中,全局狀態變化由一個中央服務器協調,其是網絡真理的唯一權威。在去中心化計算中,這些狀態的變化是通過執行于一個開放區塊鏈之上的智能合約解決的。
4. 去中心化認證:傳統的互聯網中,用戶認證通過使用某種信任的認證流程進行。如果應用維護了一個用戶數據庫,該應用通過密碼認證用戶,有時加入第二因子。如果應用依賴于某個第三方認證服務,像Google或Facebook,該應用將使用OAuth協議從第三方認證服務獲得驗證結果。顯然,在所有這些方法中用戶自己無法控制認證流程。在去中心化計算中,認證由用戶的客戶端執行,通過加密數字簽名證明對區塊鏈上注冊的某個用戶名的控制權。任何應用都可以獨立驗證證明。
5. 原生代幣:在傳統的互聯網應用中,支付通常采用像信用卡一樣的第三方服務。數字代幣是去中心化計算平臺上的原生資產,如Blockstack和以太坊。用戶對代幣有直接的所有權,可以使用它們直接注冊數字資產和智能合約,也可以支付智能合約的運行費用。這種原生代幣的使用可通過智能合約編程,構建軟件訂閱服務,也可以自動化其他的應用功能。這種可編程的代幣是傳統互聯網應用開發者無法得到的能力。
去中心化計算層次結構
Blockstack去中心化計算網絡邏輯上位于傳統互聯網架構的“應用層”。然而,Blockstack網絡自身由多個系統組成,共同為實現去中心化應用提供必需的組件:
1. Stacks區塊鏈:Stacks區塊鏈是Blockstack網絡的基礎。Stacks區塊鏈使用戶可以注冊和控制數字資產,如通用用戶名,并且可以注冊/執行智能合約。像通用用戶名這樣的數字資產,允許用戶接下來控制他們的存儲以及更多功能——用戶將其私有數據鎖柜的訪問憑證與其通用用戶名進行連接。
2. Gaia:Gaia是一個用戶控制的存儲系統,使應用可以和私人數據鎖柜交互。私人數據鎖柜可以在一個云服務提供商,或者是其他的數據存儲服務商托管。重要的是,用戶控制使用哪一個提供商。Gaia上的數據經過加密,并使用用戶密鑰在客戶端側簽名。用戶的數據鎖柜(data locker)可以通過查詢Stacks區塊鏈上的信息發現。
3. Blockstack認證:Blockstack認證協議是應用的去中心化認證協議。通過該協議用戶可以使用自己擁有的ID進行認證,并且設置使用哪個Gaia服務器保存該用戶的應用數據。
4. Blockstack程序庫和開發包:開發者程序庫(Libraries)和開發包(SDKs)位于平臺堆棧的頂端,應用開發者和用戶以此和Blockstack網絡的不同組件進行交互。例如,Blockstack客戶端軟件允許用戶注冊并管理自己的ID。Blockstack的開發者程序庫使開發人員構建Blockstack應用像構建傳統的Web應用一樣簡單。
Stacks區塊鏈
Stacks區塊鏈是Blockstack網絡的基礎層。Stacks區塊鏈為網絡提供了全局共識和協調層,產生了Blockstack網絡的原生代幣,稱為“Stacks token”。當用戶注冊通用用戶名,軟件許可,存儲鎖柜的指針等數字資產時,需要消耗Stacks代幣作為“燃料”。當注冊/執行智能合約時,Stacks代幣也被用于支付給礦工。
本章我們展示Stacks區塊鏈的高階設計。關于這些設計如何實現和演進的細節,我們建議您閱讀不同組件的SIP(Stacks Improvement Proposals)1。當更多的SIP被Stacks改進程序接受時,我們將更新本篇白皮書。Stacks區塊鏈體現了如下的設計決策:
1.一個可調諧的工作量證明(tunable proof-of-work)機制用于領導人選舉
2.一個燃燒證明(proof-of-burn)挖礦算法來重用現有區塊鏈的算力
3.一個新穎的對等網絡(Atlas),節點連通采用基于圖的隨機游走算法,減少了取得共識需要的數據量
4.一種智能合約語言,Clarity (清),非圖靈完備,解釋型語言
區塊鏈版本:當前生產環境中運行的Stacks區塊鏈是“版本1”,是部署基本功能的一個初始實現。Stacks區塊鏈v1使用比特幣網絡實現其共識算法,支持Stacks代幣操作,比如轉賬。Stacks區塊鏈v1為一些用例實現了智能合約,比如Blockstack Naming System。關于版本1功能和實現的更多細節,請查看Github上的已有實現。本章中的剩余部分將討論Stacks區塊鏈“版本2”的設計。Stacks區塊鏈v2實現了我們新共識算法和智能合約語言的完整功能,將是對版本1的一個主要升級。
1. 領導人選舉
Blockstack的第一代區塊鏈邏輯上在Layer-1(L1)之上操作,每一個交易1:1對應于一個L1的比特幣交易。這樣做的原因是確保重組Blockstack區塊鏈的難度就像重組比特幣區塊鏈的難度一樣大——這是我們從Namecoin,一個更小型區塊鏈網絡上得到的一個安全問題的教訓。
Stacks區塊鏈采用一個可調諧的證明機制(Tunable Proofs)用于領導人選舉過程。可調諧證明機制是一個有附加功能的工作量證明(PoW)系統,可以重用另一個更成熟區塊鏈的算力。采用可調諧證明機制,我們的目標是安全地啟動一條新的區塊鏈,慢慢轉換到使用自身的PoW機制。可調諧證明機制有兩部分:(a)自身的PoW 和(b)另一種加密數字貨幣的燃燒證明。
在初始時,燃燒證明部分的挖礦有更大的權重。通過燃燒證明,礦工燃燒加密數字貨幣表明他們參與挖礦程序的興趣。為了競選領導人,候選人燃燒底層鏈的代幣(這里是比特幣),在領導人的候選(would-be)塊里提交了一個初始的交易集。該次提交同時也表明了該領導人的分叉選擇:當前塊的共識哈希必須包含前一個塊的頭部。當出現有多個競爭的分叉時,那些選擇在失敗分叉上“挖礦”的領導人無法收到區塊獎勵和交易手續費,也不能恢復已燒掉的加密數字貨幣。
Stacks區塊鏈中采用的燃燒證明機制可以達成:
高驗證吞吐量。處理的Stacks交易數量與底層“燃燒鏈”(這里是比特幣)的交易處理速率間解耦。使用燃燒證明選舉允許Stacks交易的“全部區塊”用底層燃燒鏈的每一個新區塊來確認。
低延遲塊采納。通過采用單一領導人選舉,我們的燃燒證明共識算法允許當前領導人在Stacks區塊中立即包含一個來自于交易池(mempool)新交易。這個區塊流模型允許用戶在幾秒鐘內得知一個交易被區塊采納。
開放領導人集合。燃燒證明選舉允許任何人成為領導人。這個機制確保Stacks區塊鏈是一個開放的區塊鏈(相對于依賴固定領導人集合的封閉區塊鏈,或者委托權益證明(DPoS)系統,其行為功能上與封閉的集合類似)。而且,通過執行單一領導人選舉,我們的共識算法確保潛在領導人間無需協調。
無挖礦硬件可參與。作為領導人參與,所需的工作涉及燃燒某種加密數字貨幣,而不是像傳統的工作量證明挖礦方案。因此,參與領導人選舉不需要挖礦硬件。任何能獲得要燃燒的加密數字貨幣的人都能參與挖礦,哪怕只能負擔得起最低限度的數量。
公平礦池。Stacks區塊鏈天然地支持公平的礦池。任何參與到網絡中的人可以燃燒加密數字貨幣支持某個指定領導人的選舉。提交這樣的“用戶投票型燃燒”(user support burns)的用戶將與該領導人分享等量份額的Stacks區塊獎勵。
故障恢復能力。這個設計確保發生燃燒鏈不穩定,或者不適合Stacks區塊鏈挖礦時,Stacks區塊鏈可以使用另一條不同的燃燒鏈。
關于燃燒證明組件的更多細節參見文獻。將來可能發生的情況是,一旦在Stacks區塊鏈上有足夠的自身算力,燃燒證明組件就不再需要了。
2. 可調諧證明
除了燃燒證明之外,Stacks區塊鏈的共識算法中包含了一個內置的工作量證明(PoW)組件。這種組合分擔了在SIP-001中描述的燃燒證明選舉系統所在區塊鏈的安全職責。這種內置的工作量證明和燃燒證明的組合在我們系統里被稱為可調諧證明。允許引入內置的PoW挖礦,而在當前PoW利益較低時,通過燃燒證明確保區塊鏈的穩定。當底層燃燒鏈走向衰落時,可調諧的功能給我們更靈活的遷移。可協調機制的設計的靈活性還擴展到今后新的共識機制。我們可以研究其它PoW和PoS的共識機制, 如果未來有必要采取新的共識機制, 也可以安全合理的引入。
PoW組件在領導人選舉中是這樣工作的,其允許候選人在他們的燃燒交易中可選地包含一個PoW隨機數。產生此隨機數需要的工作量(就是某種函數,其計算結果哈希前置多少個0)對應成候選人的“燃燒數量”。在初始時,內置的PoW將占比5%(相對于已提交的燃燒數量)。內置的PoW組件仍在大量的設計和開發之中。隨著更多的細節具體化,這部分內容(以及一個對應的SIP)將被更新。
3. Atlas對等網絡
Atlas對等網絡是一個內容可尋址的對等網絡,實現了一個Gossip協議,每個節點跟蹤哪些其他節點當前在網絡中,每個節點試圖保存網絡中所有數據的一個完整副本。該網絡的容量受到了Stacks區塊鏈的限制:數據集中的每一條新紀錄,都必須和Stacks區塊鏈上的一個交易相關聯。Atlas對等網絡是作為Stacks區塊鏈的一個子系統工作的。其設計成一個無結構對等網絡(unstructured peer network)以避免節點加入或離開網絡引起的問題。而且,既然每個節點都保留所有數據的一個副本,數據的索引在Stacks區塊鏈上可用,那么新的Atlas節點可以快速同步其需要存儲的數據,因為事先知道應該從其他節點存儲什么數據(通常在點對點網絡中這對節點是未知的)。
Atlas網絡作為Stacks區塊鏈的“擴展存儲”子系統運行。我們的設計方案是盡可能少地依賴于直接與Stacks區塊鏈自身的交互,盡可能少地在其上存儲數據。對于許多在Blockstack上的應用,例如Blockstack Naming System (BNS)的智能合約,其本質上是有一個機制存儲不可改變和帶有時間戳的數據。在BNS里,這被用來將用戶名和路由信息關聯,通過路由信息可以發現用戶個人資料和應用數據。大多數的區塊鏈直接將這種數據存儲在區塊鏈上。然而,我們相反選擇將哈希存儲在區塊鏈上(空間昂貴),并實現了一個單獨的對等網絡來交換對應于這些哈希的數據。
4. Stacks代幣用途
Stacks區塊鏈實現的原生Stacks代幣激活了Blockstack網絡上的幾項基礎操作:
1. 注冊數字資產的燃料。Stacks代幣用來注冊不同種類的數字資產,例如:用戶名,域名,軟件授權,播客,還有一些其他的。
2. 注冊/執行智能合約的燃料。執行智能合約需要燃料以支付驗證合約正確性并執行合約的開銷。Stacks代幣也被用來核銷在Stacks區塊鏈上存儲智能合約的成本。
3. 交易手續費。Stacks代幣被用來支付交易手續費,以此Stacks區塊鏈才能記錄該交易。
4. 錨定的應用鏈。對于在Blockstack上廣受歡迎的應用,我們的區塊鏈有一個可擴展的入口,應用可以在Stacks區塊鏈上初始化自己的區塊鏈。這樣的“應用鏈”燃燒Stacks代幣挖礦。
上面的列表并不是全部——隨著Blockstack網絡的成熟,我們期待網絡參與者會發現和開發出Stacks代幣的其他用處。我們當前正積極研究一個“應用權益”機制,使代幣持有者可以潛在參與我們的“應用挖礦”開發者激勵計劃中。
Clarity (清)智能合約語言
Stacks區塊鏈支持加載和執行智能合約,以對數字資產進行編程控制。“清”這個新智能合約語言優化了安全和可預測性,強調了其不同于先前的智能合約系統的一些關鍵設計目標:
1. 該語言必須允許快速、精確的運行時和空間需求的靜態分析。為了支持這一點,該語言在單一交易的執行中是非圖靈完備的。但就完整的交易歷史來說,該語言是圖靈完備的。
2. 智能合約應該是由我們的虛擬機解釋執行的,而非編譯。開發者編寫的合約代碼必須直接部署到區塊鏈上。
為了實現以上兩個性質,我們創造了一個新的LISP語言變種,特殊設計成智能合約的編寫語言。在SIP-002[24]中有關于Clarity(清)語言設計的更詳細討論。
1. 語言概覽
智能合約語言Clarity(清)與其他的LISP變種(例如:Scheme)相似,但是有如下的不同:
1. 遞歸是非法的,并且沒有lambda函數
2. 循環只能通過map,filter,或fold執行
3. 唯一的原子類型是布爾,整型,定長數組,以及控制主體(principals,是Blockstack智能合約語言中特有的數據類型)
4. 對原子類型的列表提供額外的支持,但該語言中唯一變長的列表只能作為函數輸入出現(也就是說,對類似append或join的列表操作不支持)。我們也支持名稱和類型指定(named-and-typed)的元組。
5. 變量僅能使用let綁定創建,不支持類似set的可變功能
6. 允許使用define語句定義常量和函數來簡化代碼。但這純粹是句法意義上的。如果一個定義不能被還原(inlined),該合約將被視為非法被拒絕。這些定義同時也是私有的,在某個函數中這樣的定義,只能被指定智能合約中定義的其他函數所調用。
7. 通過define-public語句指定的函數是公有函數。傳給這些函數的參數必須指定類型。
智能合約有下面的權力:
1. 從其他的智能合約調用公有函數。這些智能合約以其哈希標識,被調用智能合約必須在調用者智能合約發布時已存在。結合遞歸的非法性,這樣做將防止函數重入,這在現存的智能合約平臺上是一個通用的攻擊途徑。
2. 擁有并控制數字資產。就像公鑰或多重簽名地址一樣,智能合約是一級主體。
每個智能合約有自己的數據空間(data-space)。在此數據空間中的數據被存儲在map里。這些存儲將一個typed-tuple與另一個typed-tuple相關聯(很像一個有類型的鍵值對數據庫)。相對于表(table)數據結構,map只關聯一個指定的key到一個唯一確定的value。
每個智能合約可以從任何其他智能合約的map里取數據。但是,只有一個智能合約可以直接在其自己的map里更新數據。
由于以下兩點原因,我們選擇使用map,而不是其他的數據結構:
1. 由于map結構的簡單性,使得虛擬機內實現更簡單,函數推導更容易。通過檢查一個指定函數的定義,可以清楚的看到哪些map將被修改;甚至在那些map中,哪些key會受到一個給定調用的影響。
2. Map接口確保其操作的返回類型是定長的,這對智能合約運行時、成本和其他屬性的靜態分析是必須的。
2. 圖靈不完備和靜態分析
創造一個非圖靈完備語言是一個重要的設計考慮。在區塊鏈這種惡意的網絡環境中,這一點為編程帶來了許多好處。
1. 圖靈不完備使靜態分析能夠決定執行一個指定交易的成本。這允許網絡預先清楚地知道向一個指定交易收取多少手續費。這也會提升客戶端的體驗,因為對客戶端來說廣播一個交易的成本可知了,所以能容易地傳達給用戶。
2. 圖靈不完備允許靜態分析可以快速決定一些重要屬性,例如單個交易可能調用了哪幾個合約。這提升了用戶體驗,因為客戶端可以警告用戶關于一個給定交易的任何潛在副作用。
3. 改進的、精確的靜態分析將允許程序員充滿信心地分析他們的智能合約,在上線之前發現任何可能的缺陷和錯誤。
基本上我們認為,像對待其他編程形式一樣對待智能合約編程是個錯誤。區塊鏈的性質造就了智能合約非常重要的特性。我們認為犧牲編程的簡易,來換取增進的人和計算機對智能合約行為的全面理解,是一個好的權衡。已有的智能合約使用實踐證實了這點——圖靈完備智能合約的歷史基本上是智能合約bug的歷史。
在智能合約語言“清”中,在廣播智能合約之前運行的靜態分析可以提供如下的信息:
1. 廣播指定交易的成本是其輸入大小的函數
2. 可以修改任意特定表的交易集合
未來的工作可以支持甚至更高級的分析功能,例如自動檢查智能合約代碼上的證據的能力。
3. 解釋型語言 vs. 編譯型語言
在我們智能合約語言Clarity(清)中的另一個關鍵設計決策是,選擇一門解釋型語言,而不是編譯型語言(例如,編譯成WASM)。與同時期的其他方法相比,我們不采用編譯器的設計決策是一個根本的不同。采用這種設計決策的主要原因,是對程序實現的bug歸因的能力。
程序實現的bug是無法更改的事實,即使有最好的編碼規范,也無從避免。智能合約的bug(區塊鏈)是如此,其他代碼也一樣。智能合約的bug處理起來更復雜。不同的區塊鏈社區奉行“代碼即法律”的哲學,提交到區塊鏈上的法則是最終真相的來源(source of ultimate truth)。編寫智能合約的開發者通過源代碼表達他們的意愿,然而是編譯將他們的意愿轉換為實際的法則。這會導致因為編譯器的bug使實際法則偏離開發者意愿的情況。會產生令人不快的情況,人們將爭論是開發者意愿更重要還是法則更重要。在Stacks區塊鏈里,我們移除編譯步驟,直接提交開發者意愿到區塊鏈,避免這種狀況,以使開發者意愿絕不會偏離法則。
讓我們考慮一下在智能合約語言(也就是虛擬機)的實現里出現bug的情況。如果智能合約語言使用解釋器,那么解決bug相對容易實施。世界上的所有合約代碼都在區塊鏈上,只需要對解釋器打一個補丁,然后從創世塊開始重啟區塊鏈(重新應用到所有的交易)。
但是如果智能合約語言是編譯的,該bug是在編譯器內部,而非虛擬機,那補救措施就沒那么明顯了,因而可能會發生更多的爭議。這是因為編譯器里的一個bug可以導致其生成的代碼(最終廣播到區塊鏈上)產生與開發者初衷背離的行為。在加密數字貨幣社區里,在對“代碼即法律”哲學的認同下,這種情況愈加復雜。由開發者編寫的代碼是正確的,但是區塊鏈上產生的交易是錯誤的。收集每個開發者的源代碼并重新編譯是不現實的,尤其在無法驗證源代碼是否已改變的情況下。我們懷疑,在實踐中這種情況下在區塊鏈上發布的代碼多數是最終真相的源。如果是這樣,開發者應該歸因和驗證此代碼,而不是他們的源代碼。我們相信,使用一個高級的解釋型語言對于確保正確的智能合約執行是至關重要的。
Gaia:用戶控制的存儲
Blockstack使用Gaia存儲系統給用戶對其數據的控制權。這是一個用戶控制的存儲系統,使應用可以與私人數據鎖柜(private data lockers)交互。私人數據鎖柜可以托管在一個云服務提供商,或者是其他的數據存儲服務商。重要的是,用戶控制使用哪一個提供商。Gaia上的數據經過加密,并使用用戶控制的密鑰簽名。邏輯上,Gaia像是一個廣域的文件系統,可以被掛載以保存文件。
使用Gaia存儲系統,用戶要指定一個Gaia存儲位置的地址,在此保存數據。只是Gaia存儲位置的“指針”被保存到Stacks區塊鏈上(以及Atlas子系統上)。當用戶使用Blockstack認證協議登錄應用和服務時,將此位置傳遞給應用;有了這個信息,應用知道如何與指定地Gaia數據鎖柜交流,如此應用數據被保存到用戶指定的存儲里。
Gaia的設計哲學是,以一種終端用戶無需信任底層云服務提供商的方式重用現有的云服務提供商和基礎設施。我們看待云存儲服務提供商(像Amazon S3, Google Cloud Storage,甚至一個本地磁盤)只是作為一個通道(dumb drives),在上面存儲加密過的,和/或簽名過的數據。云服務提供商看不到用戶的數據;他們只能看到加密的數據塊。
而且,因為通過Stacks區塊鏈可發現相關聯的公鑰或數據哈希,云服務提供商沒有篡改用戶數據的能力。
向Gaia服務器寫數據涉及到POST數據到服務器的合適位置。這些POST在服務器端被驗證,檢查是否此寫請求附帶了一個簽名的認證token。這個token使用私鑰簽名,控制了是否對特定的bucket有寫權限。為了給用戶的每一個應用提供分離的bucket,用戶將為每一個應用推導出不同的私鑰。每一個私鑰僅賦予Gaia服務器上特定bucket的訪問權限。
在Gaia里,用戶的區塊鏈驗證的路由信息中包含一個URL,指向一個簽名過的JSON對象(由該用戶的owner key簽名)。這個簽名過的JSON對象內包含指向該用戶Gaia數據鎖柜的URL。一旦應用知道用戶的Gaia數據鎖柜的位置,就可以使用普通的HTTP請求向那個位置請求一個文件。為了查詢不同用戶創建的文件,應用可以完全在客戶端順序地執行查詢。這在初始查詢時會有時間延遲的開銷,但是路由信息中的許多數據可以由瀏覽器本地緩存(或者由本地應用),所以后續的查詢就像傳統的互聯網數據訪問一樣快了。
圖1顯示了Gaia的總覽。查詢一個像werner.id一樣的名字,其工作流程如下:
1. 在Stacks區塊鏈上查詢該名字,取得(name,hash)對
2. 在Blockstack的Atlas對等網絡里查詢hash(name),得到該名字的路由信息文件。
3. 從路由信息文件中取得該用戶的Gaia URL,接著查詢此URL,連接至存儲后端。
4. 從指定的Gaia服務處GET/PUT數據(如果需要且讀者有此訪問權限,則進行解密),并驗證相應的簽名或哈希。
上面的步驟1和步驟2可通過對blockstack-core在/v1/names/《name》訪問點上的一個簡單調用即可執行。這些重復的讀寫操作已在我們的開發者程序庫中自動處理了。
性能。我們架構的目標是相對構建于云服務提供商之上的傳統互聯網應用提供可比的性能。通過移除控制和失效的中心點,我們引入了有意義的安全和容錯的好處——在讀寫性能上付出一些小的額外開銷是值得的,只要這些額外開銷對普通用戶不那么重大或顯而易見。我們評估了Gaia的讀寫性能,顯示出其在讀寫底層存儲的文件上是有競爭力的。由于加密的緣故,Gaia為每個文件增加了一個可忽略的固定大小的存儲空間開銷(粗略為文件大小的5%)。加密也會有CPU的額外開銷;但是因為文件尺寸變化非常小,讀寫的網絡性能與直接訪問底層的存儲服務是相似的。
系統擴展性。我們架構的存儲層不是一個可擴展性的瓶頸。同期的云存儲系統是高度可擴展的。Atlas網絡也是擴展性良好,因為其并不索引單獨的用戶文件或文件塊,只索引指向用戶存儲后臺的指針。存儲后臺處理批量的數據讀寫操作,Atlas網絡只在下述情況下參與 (a)用戶改變或更新了他的存儲后臺或者公鑰映射,或(b)新用戶在系統中注冊。當注冊新域名/用戶時,路由文件的哈希必須在區塊鏈上廣播。區塊鏈可能是可擴展性的一個瓶頸(相對于Atlas網絡),但用戶極少寫區塊鏈。另外,鏈下名字注冊的使用可以在一個單一的區塊鏈交易中注冊超過100個用戶,由此可以支持每天數十萬個用戶注冊(可以與傳統云上平臺的每日新用戶數量相比)。提升Gaia到10億用戶量級在實踐中可能會暴露出可擴展性問題,但明顯現在不會發生,解決這些挑戰是正在進行和將來工作的一個研究領域。
認證
使用互聯網應用,用戶賬戶是至關重要的。Blockstack提供給用戶一個通用的用戶名,無需任何密碼,可用于所有的應用。不像基于密碼的認證,用戶使用公鑰密碼學進行認證:一個本地運行的軟件客戶端處理來自特定應用的登錄請求,并對認證請求簽名。
Blockstack Auth是我們的認證協議,其將應用與用戶的Gaia hub以及任何應用相關的私鑰連接在一起。應用使用這些信息將用戶和其數據保存,驗證其他用戶產生的數據是真實的。
1. 單點登錄
Blockstack Auth使用公鑰密碼學進行認證。用戶登錄一個應用以使此應用可以產生和存儲簽名過的數據,其他用戶可以讀取和驗證其數據。這反過來向其他用戶證明了該登錄用戶是合法的。
在Blockstack中,登錄的目的是向應用客戶端提供足夠的信息,來產生和存儲真實的數據。這意味著,認證功能可以以一個認證器(authenticator)應用的形式,獨立運行在用戶的計算機上。因為所有的名字都是在Stacks區塊鏈上注冊的,每個應用和認證器一直有一個最新的視圖 (1)所有存在的名字,和(2)所有名字的公鑰及Gaia hub。這消除了對一個服務端ID提供者的需要。
為了認證用戶數據,應用客戶端只需能夠聯系一個Stacks區塊鏈節點。為此用戶在登錄時向應用提供其首選Stacks節點的網絡地址。
用 戶 通 過 點 擊 “ 登 錄 ” 按 鈕 來 登 錄 一 個 Blockstack 應 用 。 此 應 用 ( 調 用blockstack.js SDK)將用戶重定向到Blockstack認證器應用,請求登錄。用戶將看到可選擇的用于登錄的Blockstack ID,同時還有一個應用所需的權限列表。選擇一個ID,認證器則將用戶導回到應用,并向應用傳遞三個信息:
1. 用戶的用戶名(或者是公鑰的哈希,如果還沒用戶名的話)
2. 應用特定的私鑰,用來加密和簽名用戶的數據。這是使用用戶主私鑰、登錄使用的ID和應用的HTTP Origin所生成的確定性密鑰。
3. 用戶Gaia hub的URL,以及用來查詢其他用戶和數據的首選Stacks區塊鏈節點。
有了這些,用戶展現了其用戶名,通知應用哪里可以找到和存儲其數據。在那里,應用可以持久化地讀寫應用特定的數據,訪問其他用戶的應用特定數據——所有這些不需要提供其自身的存儲或ID解決方案。
登出操作簡單地清除應用的本地狀態,因此導致Web瀏覽器和客戶端忘記應用特定的私鑰。
Blockstack程序庫和開發包
Blockstack PBC是一個公益公司(Public Benefit Corp),和開源貢獻者一起開發了Blockstack的核心協議和開發者程序庫。開發者程序庫使開發人員在Blockstack網絡上構建應用更簡單,而Blockstack客戶端使用戶可以和Blockstack網絡的不同組件以及不同應用進行交互。
1. 開發者程序庫
Blockstack設計成讓開發人員開發去中心化應用盡可能地簡單。與Stacks區塊鏈或去中心化存儲的交互復雜性大多向應用開發者隱藏了,他們可以只關注應用的邏輯。Blockstack開源代碼庫包含了一些不同平臺的開發者程序庫:一個Javascript Web SDK (blockstack.js),iOS和Android的移動SDK。所有這些程序庫都是在MIT許可協議下可用,訪問此鏈接可獲取 https://github.com/blockstack。
這些程序庫提供所有必須的API接口,以及實現我們認證協議的代碼,直接與Gaia服務器交互,生成Stacks交易。使用這些程序庫允許開發者創建尊重用戶安全和隱私的去中心化應用,就像開發傳統的應用一樣容易。
Radiks 對于希望穿透復雜的社交圖譜分享數據的應用來說,對數據建立索引通常是有用的和最有效的。Radiks系統是一個服務器和客戶端的程序庫,用來構建并與這樣的索引交互。Radiks程序庫使開發人員可以在應用內創建跨用戶的結構化數據集,可以通過字段的值查詢。這要求一個服務器端的組件處理索引和查詢,可關鍵這不是用戶信任的計算環境的一部分。其只能看到數據的密文和一些必要的元數據,后者用于構建索引以及通過索引應答查詢。
2. 用戶軟件
雖然應用開發者將使用開發包和程序庫與Blockstack網絡進行交互,但用戶還需要軟件來執行諸如注冊用戶、指定其Gaia服務器以及應用用戶認證等功能。Blockstack生態系統目前提供兩個可使用戶與網絡進行交互的開源項目:
1. Blockstack瀏覽器。這是目前推薦的認證器應用的一個開源實現,而且其允許用戶瀏覽可用的Blockstack應用、注冊用戶名以及認證應用用戶。Blockstack瀏覽器可以在桌面上進行本地安裝,也可以采用web部署。
2. Blockstack CLI。這是一個命令行實用程序,允許高級用戶和開發者與Blockstack協議交互。除了提供認證功能,其允許用戶創建原始交易,以及通過Gaia進行高級數據管理任務。
應用和服務
截至2019年初,Blockstack上已經搭建了100多個應用。開發者正在搭建各種不同類型的應用,在app.co上可找到持續增多的Blockstack應用的完整清單。由于Blockstack是模塊化的,不同的應用可獨立地使用不同的組件。以下是我們對一些示例用例做出的簡要概述。
目前,Blockstack上的辦公效率應用使用Blockstack認證和Gaia存儲,用戶可以創建、編輯以及共享文件。為幫助用戶發現彼此的文件,這些應用使用Blockstack個人資料檢索器。該檢索器是去中心化的——因為個人資料集是全球可見的,是可以被發現的,任何人都可以部署及運行個人資料檢索器。
Blockstack生態系統還包含許多社交應用。通常情況下,這些社交應用使用 Blockstack認證,同時部署一個Radiks服務器,以使用戶高效地發現并獲取其他用戶的資料。在至少一個用例中,應用使用一個專用的中繼通道在眾多用戶間路由加密的信息。Blockstack上的發布和存儲應用不僅使用Gaia存儲用戶資料,而且還將其通過傳統的HTTP URL與非Blockstack用戶分享。
開發者獎勵。Stacks區塊鏈擴大了挖礦的概念,應用開發者可以通過在網絡上發布高質量的應用 “挖”Stacks代幣。這一機制被稱作應用挖礦,其被設計成一種激勵機制,以期在網絡上獲得高質量應用。應用挖礦計劃目前由擁有多名獨立審閱人的Blockstack PBC運營。開發者可以將其應用每月提交一次以審閱,并基于其應用在應用排名機制中的表現獲得獎勵。應用由一組獨立審閱人審閱,每名審閱人對于什么樣的應用才是好應用有自己的評定標準。應用得到的總分決定了其排名情況。
結論
Blockstack是一個去中心化計算網絡,向開發者提供了用于搭建去中心化應用的全棧。迄今為止,我們的網絡上已經搭建了100多個去中心化應用。Blockstack無需開發者運行服務器和數據庫:取而代之的是用應用將數據寫到用戶控制的私人數據鎖柜里。這一去中心化存儲系統與傳統云存儲在性能上相當,只因加密/解密引入一點開銷。我們的認證協議無需采用基于密碼的登錄方式,那種方式不如加密認證安全。用戶可以使用單一賬戶訪問所有服務和應用,不必持續不斷的為新服務創建新賬戶。我們的開發者程序庫使得在該平臺上開發去中心化應用與搭建傳統互聯網應用一樣簡單。
在本文中,我們呈現了Blockstack的最新設計。自2016年和2017年產品的早期實現以來,Blockstack的核心設計一直在演進,吸取了從產品部署中得到的經驗教訓以及去中心化應用開發者的反饋。與早期(2017年)的白皮書相比,主要變化包括(a)對Stacks 區塊鏈的說明,其使用新穎的可調諧證明機制來安全地啟動一條新的區塊鏈,和(b)對新智能合約語言Clarity(清)的說明,關注智能合約的安全和可預測性。我們已經以開源的方式發布了Blockstack 。
評論
查看更多