fabric一些概念

 

賬本

受衆:架構師、應用程序開發者和智能合約開發者、管理員

賬本是 Hyperledger Fabric 中的一個重要概念,它存儲了有關業務對象的重要事實信息,其中既包括對象屬性的當前值,也包括產生這些當前值的交易的歷史。

在這個主題中,我們將談到:

什麼是賬本?

賬本記錄着業務的當前狀態,它就像一個交易日記。歐洲和中國最早的賬本可以追溯到近 1000 年前,蘇美爾人在 4000 年前就已經有石制賬本了,不過我們還是從離我們最近的例子開始講吧!

你可能已經習慣查看你的銀行賬戶了。對你來說,最重要的是賬戶餘額,它是你當時就能花的錢。如果你想看看你的餘額是如何產生的,可以瀏覽一下相關的交易收入和支出。這是現實生活中的一個賬本的示例——一個狀態(您的銀行餘額)和一組促成該狀態的有序交易(收入和支出)。Hyperledger Fabric 也致力於這兩個方面,它旨在呈現一組賬本狀態的當前值,同時記錄下促成了以上賬本狀態的交易的歷史。

賬本、事實和狀態

賬本儲存的其實並不是業務對象本身,而是與業務對象相關的事實信息。當我們說“我們在賬本中存儲一個業務對象”時,其實是說我們正在記錄與一個業務對象當前狀態有關的事實,以及與促成這一當前狀態的交易歷史相關的事實。在一個日益數字化的世界裏,我們感覺自己正在看的是一個物體本身,而不是關於這個物體的一些事實。對於數字對象來說,它可能位於一個外部數據庫,但通過我們儲存在賬本中有關該對象的事實就能夠識別出該數字對象的所在位置以及其他與之相關的關鍵信息。

雖然與業務對象當前狀態相關的事實可能會發生改變,但是與之相關的事實歷史是不可變的,我們可以在事實歷史上增加新的事實,但無法更改歷史中已經存在的事實。我們將看到,如果把區塊鏈看作是與業務對象有關的事實歷史,且該歷史是不可更改的,那麼我們就能夠很輕鬆、高效地理解區塊鏈。

現在我們來深入探討一下 Hyperledger Fabric 的賬本結構!

賬本

Hyperledger Fabric 中的賬本由“世界狀態“和”區塊鏈“這兩部分組成,它們彼此不同但卻相互關聯。二者都代表了與業務對象有關的一些事實。

首先,世界狀態是一個數據庫,它存儲了一組賬本狀態的當前值。通過世界狀態,程序可以直接訪問一個賬本狀態的當前值,不需要遍歷整個交易日誌來計算當前值。默認情況下,賬本狀態是以鍵值對的方式來表示的,稍後我們將看到 Hyperledger Fabric 如何提供這一方面的靈活性。因爲我們可以創建、更新和刪除狀態,所以世界狀態能夠頻繁更改。

其次,區塊鏈是交易日誌,它記錄了促成當前世界狀態的所有改變。交易被收集在附加到區塊鏈的區塊中,能幫助我們理解所有促成當前世界狀態的改變的歷史。區塊鏈數據結構與世界狀態相差甚遠,因爲一旦把數據寫入區塊鏈,就無法修改,它是不可篡改的

 

賬本 L 由區塊鏈 B 和世界狀態 W組成,其中世界狀態 W 由區塊鏈 B 決定。我們也可以說世界狀態 W 是源自區塊鏈 B。

爲幫助理解,可以這樣認爲: Hyperledger Fabric 網絡中存在一個邏輯賬本。實際上,Fabric 網絡維護着一個賬本的多個副本,這些副本通過名爲共識的過程來與其他副本保持一致。分佈式賬本技術(DLT)這個術語經常與這種賬本聯繫在一起,這種賬本在邏輯上是單個的,但是在整個網絡中卻分佈着許多彼此一致的副本。

現在讓我們更細緻地研究一下世界狀態和區塊鏈數據結構。

世界狀態

世界狀態將業務對象屬性的當前值保存爲唯一的賬本狀態。這很有用,因爲程序通常需要對象的當前值,如果遍歷整個區塊鏈來計算對象的當前值會很麻煩——從世界狀態中可以直接獲取當前值。

 

一個賬本世界狀態包含兩個狀態。第一個狀態是: key=CAR1 和 value=Audi。第二個狀態中有一個更復雜的值:key=CAR2 和 value={model:BMW, color=red, owner=Jane} 。兩個狀態的版本都是0。

賬本狀態記錄了一組與特定業務對象有關的事實。我們的示例展示的是 CAR1 和 CAR2 這兩輛車的賬本狀態,二者都各有一個值和一個鍵。應用程序可以調用智能合約,該合約使用簡單的賬本 API 來獲取寫入刪除狀態。注意狀態值可以是簡單值(Audi…),也可以是複合值(type:BMW…)。經常會通過查詢世界狀態來檢索具有某些特定屬性的對象,例如查找所有紅色寶馬。

世界狀態被作爲數據庫來實現。這一點很有意義,因爲數據庫爲有效存儲和狀態檢索提供了充分的算子。稍後我們將看到,我們可以將 Hyperledger Fabric 配置爲使用不同的世界狀態數據庫來滿足以下需求:不同類型的狀態值,應用程序所需的訪問模式,例如,當遇到複雜查詢的情況時。

應用程序提交那些會更改世界狀態的交易,這些交易最終被提交到賬本區塊鏈上。應用程序無法看到 Hyperledger Fabric SDK(軟件開發工具包) 設定的共識機制的細節內容,它們能做的只是調用智能合約以及在交易被收進區塊鏈時收到通知(所有被提交的交易,無論有效與否,都會被收進區塊鏈)。Hyperledger Fabric 的關鍵設計在於,只有那些受到相關背書組織簽名的交易纔會更新世界狀態。如果一個交易沒有得到足夠背書節點的簽名,那麼它不會更新世界狀態。您可以閱讀更多關於應用程序如何使用智能合約以及如何開發應用程序的信息。

您還會注意到,每個狀態都有一個版本號,在上面的圖表中,狀態 CAR1 和 CAR2 都處於它們的初始版本 0。版本號是供 Hyperledger Fabric 內部使用的,並且每次狀態更改時版本號會發生遞增。每當更新狀態時,都會檢查該狀態的版本,以確保當前狀態與背書時的版本相匹配。這就確保了世界狀態是按照預期進行更新的,沒有發生併發更新。

最後,首次創建賬本時,世界狀態是空的。因爲區塊鏈上記錄了所有代表有效世界狀態更新的交易,所以任何時候都可以從區塊鏈中重新生成世界狀態。這樣一來就變得非常方便,例如,創建節點時會自動生成世界狀態。此外,如果某個節點發生異常,重啓該節點時能夠在接受交易之前重新生成世界狀態。

區塊鏈

現在讓我們把注意力從世界狀態轉移到區塊鏈上。世界狀態存儲了與業務對象當前狀態相關的事實信息,而區塊鏈是一種歷史記錄,它記錄了這些業務對象是如何到達各自當前狀態的相關事實。區塊鏈記錄了每個賬本狀態之前的所有版本以及狀態是如何被更改的。

區塊鏈的結構是一羣相互鏈接的區塊的序列化日誌,其中每個區塊都包含一系列交易,各項交易代表了一個對世界狀態進行的查詢或更新操作。我們在其他地方討論了排序交易的確切機制;其中重要的是區塊排序以及區塊內的交易排序,這一機制是在 Hyperledger Fabric 的排序服務組件首次創建區塊時被建立起來的。

每個區塊的頭部都包含區塊交易的一個哈希,以及前一個區塊頭的哈希。這樣一來,賬本上的所有交易都被按序排列,並以密碼方式連接在一起。這種哈希和鏈接使賬本數據變得非常安全。即使某個保存賬本的節點被篡改了,該節點也無法讓其他節點相信自己擁有“正確的”區塊鏈,這是因爲賬本被分佈在一個由獨立節點組成的網絡中。

區塊鏈總是被作爲一個文件來實現,而與之相反的是,世界狀態被作爲一個數據庫來實現。這是一個明智的設計,因爲區塊鏈數據結構高度偏向於非常小的一組簡單操作。第一項操作被放在區塊鏈的末尾,就目前來說,查詢操縱相對少見。

讓我們更細緻地看看區塊鏈的結構。

 

區塊鏈 B 包含了 B0、B1、B2、B3這四個區塊。B0 是該區塊鏈的第一個區塊,也叫創世區塊。

在上面的圖中我們可以看到,區塊 B2 有一個區塊數據 D2,該數據包含了 B2 的所有交易:T5、T6、T7。

最重要的是,B2 有一個區塊頭 H2,H2 包含了 D2 中所有交易的加密哈希以及前一個區塊中 H1 的一個哈希。這樣一來,所有區塊彼此緊密相連,不可篡改,術語區塊鏈很好地描述了這一點!

最後,如圖所示,區塊鏈中的第一個區塊被稱爲創始區塊。雖然它並不包含任何用戶交易,但卻是賬本的起始點。相反的,創世區塊包含了一個配置交易,該交易含有網絡配置(未顯示)的初始狀態。我們將會在討論區塊鏈網絡和通道 時更詳細地探討初始區塊。

區塊

讓我們仔細看看區塊的結構。它由三個部分組成

  • 區塊頭

    這個部分包含三個字段,這些字段是在創建一個區塊時候被寫入的。

    • 區塊編號:編號從0(初始區塊)開始,每在區塊鏈上增加一個新區塊,編號的數字都會加1。
    • 當前區塊的哈希值:當前區塊中包含的所有交易的哈希值。
    • 前一個區塊頭的哈希值:區塊鏈中前一個區塊頭的哈希值。

    這些字段是通過在內部對區塊數據進行加密哈希而生成的。它們確保了每一個區塊和與之相鄰的其他區塊緊密相連,從而組成一個不可更改的賬本。

  •  

    區塊頭詳情:區塊 B2 的區塊頭 H2 包含了區塊編號 2,當前區塊數據 D2 的哈希值 CH2,以及前一個區塊頭 H1的哈希值 PH1。

  • 區塊數據

    這部分包含了一個有序的交易列表。區塊數據是在排序服務創建區塊時被寫入的。這些交易的結構很複雜但也很直接,我們會在後邊進行講解。

  • 區塊元數據

    這個部分包含了區塊被寫入的時間,還有區塊寫入者的證書、公鑰以及簽名。隨後,區塊的提交者也會爲每一筆交易添加一個有效或無效的標記,但由於這一信息與區塊同時產生,所以它不會被包含在哈希中。

交易

正如我們所看到的,交易記錄了世界狀態發生的更新。讓我們來詳細瞭解一下這種把交易包含在區塊中的區塊數據結構。

 

交易詳情:交易 T4 位於區塊 B1 的區塊數據 D1 中,T4包括的內容如下:交易頭 H4,一個交易簽名 S4,一個交易提案 P4,一個交易響應 R4 和一系列背書 E4。

在上面的例子中,我們可以看到以下字段:

  • (Header)交易頭

    這部分用 H4 表示,它記錄了關於交易的一些重要元數據,比如,相關鏈碼的名字以及版本。

  • (Signature)交易簽名

    這部分用 S4 表示,它包含了一個由客戶端應用程序創建的加密簽名。該字段是用來檢查交易細節是否未經篡改,因爲交易簽名的生成需要用到應用程序的私鑰。

  • (Proposal)交易提案

    這部分用 P4 表示,它負責對應用程序供給智能合約的輸入參數進行編碼,隨後該智能合約生成提案賬本更新。在智能合約運行時,這個提案提供了一套輸入參數,這些參數同當前的世界狀態一起決定了新的賬本世界狀態。

  • (Response)交易響應

    這部分用 R4 表示,它是以讀寫集 (RW-set)的形式記錄下世界狀態之前和之後的值。交易響應是智能合約的輸出,如果交易驗證成功,那麼該交易會被應用到賬本上,從而更新世界狀態。

  • (Endorsements)交易背書

    就像 E4 顯示的那樣,它指的是一組簽名交易響應,這些簽名都來自背書策略規定的相關組織,並且這些組織的數量必須滿足背書策略的要求。你會注意到,雖然交易中包含了多個背書,但它卻只有一個交易響應。這是因爲每個背書都對組織特定的交易響應進行了有效編碼,那些不完全滿足背書的交易響應肯定會遭到拒絕、被視爲無效,而且它們也不會更新世界狀態,所以沒必要放進交易中。

    在交易中只包含一個交易響應,但是會有多個背書。這是因爲每個背書包含了它的組織特定的交易響應,這意味着不需要包含任何沒有有效的背書的交易響應,因爲它會被作爲無效的交易被拒絕,並且不會更新世界狀態。

以上總結了交易的一些主要字段,其實還有其他字段,但是上述幾種是您需要了解的基本字段,便於您對賬本數據結構有一個很好的瞭解。

世界狀態數據庫選項

世界狀態是以數據庫的形式實現的,旨在提供簡單有效的賬本狀態存儲和檢索。正如我們所看到的,賬本狀態可包含簡單值或複合值,爲了適應這一點,世界狀態數據庫可以多種形式實現,從而對這些值進行有效實現。目前,世界狀態數據庫的選項包括 LevelDB 和 CouchDB 。

LevelDB 是世界狀態數據庫的默認選項,當賬本狀態是簡單的鍵值對時,使用 LevelDB 非常合適。LevelDB 數據庫與 peer 節點位於相同位置,它被嵌入與 peer 節點相同的操作系統進程中。

當賬本狀態結構爲 JSON 文檔時,以 CouchDB 來實現世界狀態非常合適,這是因爲業務交易涉及的數據類型通常十分豐富,而 CouchDB 可支持對這些數據類型進行各種形式的查詢和更新。在實現方面,CouchDB 是在單獨的操作系統進程中運行的,但是節點和 CouchDB 實例之間仍然存在1:1的關係。智能合約無法看到上述任何內容。有關 CouchDB 的更多信息,請參見 CouchDB 作爲狀態數據庫

在 LevelDB 和 CouchDB 中,我們看到了 Hyperledger Fabric 的一個重要方面——它是可插拔的。世界狀態數據庫可以是關係數據存儲、圖形存儲或時態數據庫。這極大提升了可被有效訪問的賬本狀態類型的靈活性,使得 Hyperledger Fabric 能夠處理多種不同類型的問題。

示例賬本:fabcar

關於賬本的討論即將結束,讓我們來看一個示例賬本。如果您已經運行了 fabcar 示例應用程序,那麼您就已經創建了這個賬本。

fabcar 示例應用程序創建了 10 輛車,每輛車都有獨一無二的身份;它們有不同的顏色,製造商,型號和擁有者。以下是前四輛車創建後的賬本。

 

賬本 L包含了一個世界狀態 W 和一個區塊鏈 B。其中 W 包含了四個狀態,各狀態的鍵分別是:CAR0,CAR1,CAR2 和 CAR3 。而 B 包含了兩個區塊 0和 1。區塊1包含了四筆交易:T1,T2,T3,T4。

我們可以看到世界狀態包含了對應於 CAR0、CAR1、CAR2 和 CAR3 的狀態。CAR0 中包含的值表明了這是一輛藍色的豐田普銳斯(Toyota Prius),目前車主是 Tomoko,其他車輛的的狀態和值也與此類似。此外,我們還可以看到所有車輛狀態的版本號都是0,這是它們的初始版本號,也就是說這些車輛狀態自創建以來一直沒有被更新過。

我們還可以看到區塊鏈包含兩個區塊。其中區塊0是創世區塊,但它並不包含任何與汽車相關的交易。而區塊1包含交易 T1、T2、T3、T4,這些交易與生成世界狀態中 CAR0 到 CAR3 這四輛車初始狀態的交易相符。同時區塊1與區塊0是相連的。

我們沒有介紹區塊或交易中的其他字段,特別是(區塊/交易)頭和哈希,如果你對這部分內容感興趣的話,可以閱讀文件中的其他部分。讀完後你會對整個區塊和交易有更加透徹的認識,但現在,你對 Hyperledger Fabric 賬本的概念已經足夠了解了。恭喜!

命名空間

上文中我們討論賬本時,似乎它只包括一個世界狀態和一條區塊鏈,但這顯然過於簡單化了。實際上,每個鏈碼都有自己的世界狀態,並且與所有其他鏈碼的世界狀態分離。世界狀態位於一個命名空間中,因此只有位於同一鏈碼中的智能合約才能訪問一個給定的名稱空間。

區塊鏈沒有命名空間。它包含來自許多不同智能合約命名空間的交易。您可以在此主題中閱讀更多關於鏈碼命名空間的信息。

現在讓我們看看命名空間的概念是如何被應用到 Hyperledger Fabric 通道中的。

通道

在 Hyperledger Fabric 中,每個通道都有一個完全獨立的賬本。這意味着完全獨立的區塊鏈和完全獨立的世界狀態,包括名稱空間。應用程序和智能合約可以在通道之間通信,以便在通道間訪問賬本信息。

在本主題中,您可以閱讀更多關於賬本如何與通道一起工作的信息。

更多信息

要深入瞭解交易流程、併發控制和世界狀態數據庫,請查閱交易流程讀寫集語義和 CouchDB 作爲狀態數據庫主題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章