對比特幣的繼承與創新!深刻理解公鏈 CKB 的 Cell 模型

爲了理解底層公鏈 CKB 的 Cell 模型,咱們前置了幾篇概念性文章,講述了咱們應該 以狀態爲中心設計區塊鏈系統的,以及這麼作帶來的好處。而且在上一篇文章中,詳細分析了 比特幣 UTXO 模型和以太坊的 Account 模型,以及進行了對比分析。終於,咱們要來了解集大成者 Cell 模型了。(前排提示:一遍看不懂不要緊,多看幾遍就懂了)

祕猿科技區塊鏈小課堂第 18 期android


在設計 CKB 的時候,咱們想要解決三個方面的問題:編程

  • 狀態爆炸引發的公地悲劇及去中心化的喪失;
  • 計算和驗證耦合在了一塊兒使得不管是計算仍是驗證都失去了靈活性,難以擴展;
  • 交易與價值存儲這兩個目標的內在矛盾,Layer 2 和跨鏈的出現將放大這種矛盾,並對 Layer 1 的經濟產生很是負面的影響。

對這些問題沒有答案,Layer 1 就沒法長久運行,區塊鏈給咱們的種種承諾天然也是無從談起。這三個問題根植於區塊鏈架構和協議設計的最深處,很難經過打補丁的方式來解決,咱們必須從最基本的數據結構開始,從新審視問題的根源,尋找更合適的地基。segmentfault

幸運的是,這個更合適的地基簡單得使人感到幸福,並且一直就擺在咱們眼前。(本文會包含一些很是簡單的代碼,應該不會影響非技術讀者閱讀……)安全

從 Bitcoin 中咱們學到了什麼

Bitcoin 把整個帳本分割保存在了一個個 UTXO 裏面,UTXO 是未花費交易輸出(Unspent Transaction Output)的簡寫,其實是交易中包含的輸出(CTxOut)。CTxOut 的結構很是簡單,只有兩個字段:cookie

class CTxOut
{
public:
    CAmount nValue;
    CScript scriptPubKey;
...
}

每個 CTxOut 表明了一個面值不一樣的硬幣(Yay bit-「Coin」),其中 nValue表明這個硬幣的面值是多少,scriptPubKey 是一段表示這個硬幣全部者是誰的腳本(一般包含了全部者的公鑰),只有能提供正確參數使這個腳本運行成功的人才能把這個硬幣「轉讓」給另一我的。網絡

爲何要給「轉讓」打引號?由於在轉讓的時候,並非簡單地把硬幣中的 scriptPubKey 修改或是替換掉,而是會銷燬和創造新的硬幣(畢竟在數字的世界中銷燬和創造虛擬硬幣的成本很低)。每個 Bitcoin 交易,都會銷燬一批硬幣,同時又創造一批硬幣,新創造的硬幣會有新的面值和新的全部者,可是被銷燬的總面值老是大於等於新創造的總面值,以保證沒有人能夠隨意增發。交易表示的是帳本狀態的變化。數據結構

圖片描述

這樣一個模型的特色是:架構

  • 硬幣(資產)是第一性的;
  • 全部者是硬幣的屬性,每一枚硬幣有且僅有一個全部者;
  • 硬幣不斷的被銷燬和建立。

是否是很簡單?若是你以爲本身已經理解了 Bitcoin 和 UTXO ,恭喜你,你也已經理解了CKB 和 Cell!分佈式

Cell

Layer 1 的關注點在狀態,以 Layer 1 爲設計目標的 CKB 設計的關注點很天然就是狀態。Ethereum 將交易歷史和狀態歷史分爲兩個維度,區塊和交易表達的是觸發狀態遷移的事件而不是狀態自己,而 Bitcoin 協議中的交易和狀態融合成了一個維度,交易即狀態,狀態即交易,正是一個以狀態爲核心的架構。工具

同時,CKB 想要驗證和長久保存的狀態,不只僅是簡單的數字(nValue),而是任何人認爲有價值的、通過共識的數據。顯然 Bitcoin 的交易輸出結構知足不了這個需求,可是它已經給了咱們足夠的啓發:只須要將 nValue 通常化,把它從一個存放整數的空間變成一個能夠存聽任意數據的空間,咱們就獲得了一個更加通常化的「CTxOut」,或者叫 Cell:

pub struct CellOutput {
    pub capacity: Capacity,
    pub data: Vec<u8>,
    pub lock: Script,
    pub type_: Option<Script>,
}

在 Cell 裏面,nValue 變成了 capacity 和 data 兩個字段,這兩個字段共同表示一塊存儲空間,capacity 是一個整數,表示這塊空間有多大(以字節數爲單位),data 則是保存狀態的地方,能夠寫入任意的一段字節;scriptPubKey 變成了 lock,只是換了一個名字而已,表達的是這塊共識空間的全部者是誰 - 只有能提供參數(例如簽名)使得 lock 腳本成功執行的人,才能「更新」這個 Cell 中的狀態。整個 CellOutput 佔用的字節數必須小於等於 capacity。

CKB 中存在着許許多多的 Cells,全部這些 Cell 的集合造成了 CKB 當前的完整狀態,在 CKB 的當前狀態中存儲的是任意的共同知識,再也不僅僅是某一種數字貨幣。

圖片描述

交易依然表示狀態的變化 / 遷移。狀態的變化,或者說 Cell 內容的「更新」實際上也是經過銷燬和建立來完成的(並非真的去修改原有 Cell 中的內容)。每一筆交易實際上都會銷燬一批 Cells,同時建立一批新的 Cells;新創造的 Cells 會有新的全部者,也會存放新的數據,可是被銷燬的 capacity 總和老是大於等於新建立的 capacity 總和,由此保證沒有人能夠隨便增發 capacity。由於 capacity 能夠轉讓,沒法增發,擁有 capacity 等於擁有相應數量的共識狀態空間,capacity 是 CKB 網絡中的原生資產。Cell 的銷燬只是把它標記爲「已銷燬」,相似 Bitcoin 的 UTXO 從未花費變爲已花費,並非從區塊鏈上刪掉。每個 Cell 只能被銷燬一次,就像每個 UTXO 只能被花費一次。

這樣一個模型的特色是:

  • 狀態是第一性的;
  • 全部者是狀態的屬性,每一份狀態只有一個全部者;
  • 狀態不斷的被銷燬和建立。

因此說,Cell 是 UTXO 的通常化(generalized)版本

Verify

僅僅有一塊能夠保存任意狀態的空間還不夠。Bitcoin 之因此有價值,是由於網絡中的全節點會對每一筆交易進行驗證 ,使得全部用戶都相信(而且知作別人也相信)Bitcoin 協議中寫下的規則(例如 2100 萬的上限)會獲得保證。

共同知識之因此能成爲共同知識,是由於每一個人都知道其餘人承認這些知識 ,區塊鏈之因此能讓知識變成共同知識,是由於每一個人都知道其餘人都能獨立驗證這些知識並由此產生承認。任何共識的過程都包含了一系列的驗證以及相互之間的反覆確認,這個過程正是網絡中共同知識造成的過程。(須要注意的是,驗證知識是相對事先肯定的驗證規則來講的,經過驗證的知識不表明命題爲真。)

咱們如何驗證 Cell 中保存的數據呢?這時候就須要 Cell 中的另外一個字段 type 發揮做用了。type 與 lock 同樣,也是一段腳本, type 定義了 data 字段中保存的數據在狀態遷移過程當中必需要遵照的規則,是對狀態的約束。CKB 網絡在共識的過程當中,會在 CKB-VM 中執行 type 腳本,驗證新生成的 Cell 中保存的狀態符合 type 中預先定義好的規則。知足同一種 type 約束的全部 Cell,保存的是同一種類型的數據。

舉個例子,假設咱們想定義一個叫作 SatoshiCoin 的代幣(UDT,UserDefinedToken),它的狀態遷移必須知足的約束是什麼?只有兩條:

用戶必須證實本身是輸入代幣的全部者;
每一次轉帳的時候,輸入的代幣數量必須大於等於輸出的代幣數量。

第一條約束能夠經過 lock 腳原本表達,若是有興趣能夠查看這裏的示例代碼[1],與 Bitcoin 的 scriptPubKey 原理相同;第二條約束,在 Bitcoin 中是在底層硬編碼實現的,在 CKB 中則是經過 type 腳原本實現。每一個 Cell 表明的 SatoshiCoin 數量是一種狀態,咱們首先定義其狀態結構,即每一個 type 等於 SatoshiCoin 的 Cell 在 data 保存的狀態爲一個長度爲 8 的字節串,表明的是序列化事後的數量:

{
    "amount": "Bytes[8]" // serialized integer
}

type 腳本在執行中,須要讀入交易中全部同類型的 Cells(根據 type 字段能夠判斷),而後檢查同一類型下的輸入 Cells 中保存的 amount 之和大於等於輸出 Cells 中保存的 amount 之和 。因而經過 lock 和 type 兩個腳本,咱們就實現了一個最簡單的代幣。

lock 和 type 腳本不只能夠讀取自身 Cell 中保存的狀態,也可以引用和讀取其它 Cell 中保存的狀態,因此 CKB 的編程模型是一個有狀態的編程模型。值得指出的是,Ethereum 的編程模型之因此強大,更可能是由於它有狀態,而不是由於它的有限圖靈完備。咱們能夠把 type 腳本保存在一個獨立的 Cell 裏面,而後在每個 SatoshiCoin Cell 的 type 字段引用它,這樣作的好處是相同的 type 腳本只須要一份空間保存,像這樣保存數字資產定義的 Cell 咱們把它叫作 ADC(Asset Definition Cell)。

SatoshiCoin 的另外一個特色是,具體的資產與全部者之間的記錄,分散保存在多個獨立的 Cell 裏面,這些 Cell 能夠是開發者提供給用戶的,也能夠是用戶本身擁有的,甚至是租來的。只有在共識空間全部權明確的狀況下,全部者才能真正擁有共識空間裏面保存的資產(任何數據都是資產)。在 CKB 上,由於用戶能夠真正擁有共識空間,因此用戶能夠真正擁有數字資產(當你能真正擁有土地的時候,才能真正擁有土地上的房子)。

Cell 是抽象的狀態驗證模型,Cell 提供的存儲(data)沒有任何內部結構,Cell 支持任意的狀態驗證規則(type)和全部權驗證規則(lock),咱們能夠在 Cell 模型上模擬 UTXO 模型(就像上面的 SatoshiCoin),也能夠在 Cell 模型上構建 Account 模型。lock 腳本在驗證交易輸入的時候執行,確保用戶對輸入有全部權,有權銷燬輸入的 Cells;type 腳本在驗證交易輸出的時候執行,確保用戶生成的新狀態符合類型約束,正確生成了新的 Cells。因爲狀態模型迥異,以及計算和驗證分離,CKB 的編程模型與 Ethereum 的編程模型有很是大的不一樣,什麼是 CKB 編程模型上的最佳實踐還須要大量的探索。

圖片描述

通用驗證網絡(General Verification Network)

Bitcoin 是一個驗證網絡(Verification Network)。在轉帳時,用戶告訴錢包/本地客戶端轉帳的數量和收款人,錢包根據用戶提供的信息進行計算,在本地找出用戶擁有的數量合適的硬幣(UTXO),同時產生一批新的硬幣,這些硬幣有些歸收款人全部,有些是找零。以後錢包將這些花費掉的硬幣和新生成的硬幣打包到一個交易裏面,將交易廣播,網絡對交易驗證後將交易打包到區塊裏面,交易完成。

在這個過程當中,網絡中的節點並不關心老的狀態(被銷燬的硬幣)是怎樣被搜索出來的,也不關心新的狀態(新硬幣)是怎樣生成出來的,只關心這些硬幣的面值總和在交易先後沒有改變。在轉帳過程當中,計算在用戶端完成,所以用戶在交易發送時就能肯定計算結果(新狀態)是什麼。

Ethereum 是一個通用計算網絡(General Computation Network)。在使用 DApp 的時候,用戶告訴錢包/本地客戶端想要進行的操做,錢包將用戶的操做請求原樣打包到交易裏面,並將交易廣播。網絡節點收到交易以後,根據區塊鏈的當前狀態和交易包含的操做請求進行計算,生成新的狀態。在這個過程當中,計算在遠端完成,交易結果(新狀態)只有在交易被打包到區塊以後才能肯定,用戶在交易發送的時候並不能徹底肯定計算結果。

圖片描述

(圖中,上面是 Ethereum 的流程,交易中包含的是用戶請求或者說事件/Event;下面是 Bitcoin/CKB 的流程,交易中包含的是鏈下生成的狀態/State。)

CKB 是一個通用驗證網絡(General Verification Network)。在使用 DApp 的時候,用戶告訴錢包/本地客戶端想要進行的操做,錢包根據當前狀態和用戶的操做請求進行計算,生成新的狀態。在這個過程當中,計算在用戶端完成,計算結果(新狀態)在交易發出的時候就已經肯定了。

換句話說,Bitcoin 和 CKB 都是先計算再共識,而 Ethereum 是先共識再計算。有趣的是,在許可鏈架構裏面也有一樣派別之分:Fabric 是先計算再共識,而 CITA(實際上不只僅是許可鏈)是先共識再計算。(思考題:哪種架構更適合許可鏈?)

計算與驗證的分離同時也使得 Layer 2 與 Layer 1 天然分開了。Layer 1 關心的是新的狀態是什麼,並不關心新的狀態是如何獲得的。不管是 State channel,Plasma 仍是其餘 Layer 2 方案,其實質都是在鏈外進行計算,在特定時候將最終狀態提交到 Layer 1上進行驗證。

圖片描述

爲何 CKB 的 Cell 模型更好?

如今咱們獲得了一個很是不一樣的基礎數據結構,在這個結構之上咱們設計了獨特的經濟模型,這個結果然的更好嗎?回顧一開始的三個問題也許能給咱們一些啓示。

capacity 是原生資產,受到預先肯定的發行規則約束,其總量有限;
capacity 同時又是狀態的度量,有多少 capacity ,CKB 上就能放多少數據,CKB 狀態空間的最大值與 capacity 總量大小相等,CKB 上保存的狀態不會超過 capacity 總量。

這兩點決定了 CKB 不會有狀態爆炸的問題。在 capacity 發行規則適當的狀況下,網絡應該能夠長久的保持去中心化的狀態。每個 Cell 都是獨立狀態,有明確的全部者,本來屬於公共資源的狀態空間被私有化,寶貴的共識空間能夠被更有效的使用。

CKB 是一個通用驗證網絡,計算和驗證獲得了分離,各自的靈活性和擴展性都獲得了提升。更多的計算被推到了用戶端執行,計算髮生在離場景和數據更近的地方,數據處理的方式更靈活,工具更多樣。這也意味着,在 CKB 架構中,錢包是一個能作的事情更多,能力更大的入口。在驗證端,因爲計算結果已經徹底肯定,交易的依賴分析變得很是輕鬆,交易的並行處理也就更加容易。

在基於 Cell 創建的經濟模型中,存儲的使用成本與佔用空間大小和佔用時間成正比,礦工能夠經過提供共識空間得到相應的收益。CKB 提供的 Utility 是安全的共識空間,價值來自於其安全性和可用性(accessability),並非來自於交易處理能力(TPS),與 Layer 2 負責交易的特色相輔相成,在分層網絡和跨鏈網絡中具備更好的價值捕獲能力。

最後,CKB 不是……

IPFS

CKB 是一種存儲這一點可能會令人感到迷惑:「這不就是 IPFS/Filecoin/(任何分佈式存儲)嗎?」

CKB 不是分佈式存儲,關鍵的區別在於分佈式存儲只有存儲,沒有驗證,也就不會對其存儲的數據造成共識。分佈式存儲的容量能夠隨着存儲技術的增加而等比例的增加,而 CKB 的容量則收到造成全球共識效率的限制。

CKB 也不須要擔憂容量不夠。在 Layer 2 以及分層技術成熟的階段,極端狀況下,Layer 1 上可能只須要放一個 merkle root 就足夠了。在 Layer 1 上進行驗證所須要的狀態,也能夠經過交易提交給節點,節點經過 merkle proof 驗證狀態是有效的,在此基礎之上再驗證狀態遷移是有效的,這個方向已經有一些研究。

Qtum

Qtum 是嘗試在 UTXO 模型上引入更強大的智能合約的先行者之一,具體作法是保持 Bitcoin 原有的 UTXO 模型不變,在其上引入帳戶抽象層(Account Abstraction Layer),支持 EVM 或是 x86 虛擬機。

在 Qtum 中,Bitcoin 的驗證是第一層,EVM 的計算是第二層(注意這是一個區塊連協議內部的分層,不是 Layer 1 和 Layer 2)。Qtum 對 UTXO 中 scriptPubKey 的處理邏輯進行修改,以實如今交易打包後,將 Bitcoin Transaction 中攜帶的請求傳遞給 EVM 進行執行的效果。

Qtum 將 Bitcoin 和 Ethereum 的執行模型橋接到了一塊兒,網絡節點先驗證交易輸入部分(同 Bitcoin),再調用合約進行計算(同 Ethereum),狀態分散在 UTXO 模型和 EVM 本身的狀態存儲兩個地方,總體架構比較複雜。

CKB 所作的是繼承 Bitcoin 的架構思路,對 UTXO 模型進行通常化(Generalization)處理獲得 Cell 模型,總體架構保持了一致性以及 Bitcoin 的簡潔。CKB 上的全部狀態都在 Cell 裏面,計算在鏈下完成(相似 Bitcoin),網絡節點只作驗證。

相關文章
相關標籤/搜索