天天看點

Hyperledger Fabric Ledger——賬本總賬

Ledger

Ledger(賬本)即所有的state transitions(狀态切換),是有序且不可篡改的。state transitions(狀态切換)是由參與方送出的chaincode(智能合約)調用(“transactions/事務”)的結果。每個事務都将産生一組資産鍵值對,這些鍵值對作為建立、更新或删除而送出給Ledger(賬本)。

Ledger(賬本)由blockchain(區塊鍊)(“chain”)組成,區塊則用來存儲有序且不可篡改的記錄,以及儲存目前狀态的state database(狀态資料庫)。在每一個channel中都會存在一個Ledger(賬本)。每一個peer都會維護它作為其中成員的每一個channel中的本地拷貝的Ledger(賬本)。

chain是一個事務日志,是一個由hash連結的連結各個區塊的結構,其中每個區塊都包含了N個事務的序列。區塊header包含了該區塊的事務的hash,以及上一個區塊頭的hash。這樣,所有在賬本上的交易都是按順序排列的,并以密碼方式連結在一起。換句話說,在不破壞hash連結的情況下篡改賬本資料是不可能的。最近的區塊的hash代表了以前的每個事務,進而確定所有的peers都處于一緻和可信的狀态。

chain存儲在peer檔案系統(本地或附加存儲)上,有效地支援blockchain工作負載的應用程式的特性。

該賬本的目前狀态資料表示chain事務日志中包含的所有鍵的最新值。由于目前狀态表示channel所知道的所有最新鍵值,是以有時也稱為“World State(世界狀态)”。

在chaincode調用對目前狀态資料執行操作的事務時,為了使這些chaincode互動非常有效,所有鍵的最新值都存儲在一個狀态資料庫中。狀态資料庫隻是一個索引視圖到chain的事務日志中,是以可以在任何時候從chain中重新生成它。在事務被接受之前,狀态資料庫将自動恢複(或在需要時生成)。

狀态資料庫選項包括LevelDB和CouchDB。LevelDB是嵌入在peer程序中的預設狀态資料庫,并将chaincode資料存儲為鍵/值對。CouchDB是一個可選的外部狀态資料庫,當你所寫的chaincode資料被模組化為JSON時,它提供了額外的查詢支援,允許對JSON内容進行豐富的查詢。

在高層業務邏輯處理上,transaction flow(事務處理流程)是由應用程式用戶端發送的事務協定,該協定最終發送到指定的背書節點。背書節點會驗證用戶端的簽名,并執行一個chaincode函數來模拟事務。最終傳回給用戶端的是chaincode結果,即一組在chaincode(讀集)中讀取的鍵/值版本,以及在chaincode(寫集)中寫入的鍵/值集合,即傳回該peer執行chaincode後模拟出來的讀寫集結果,同時還會附帶一個背書簽名。

用戶端将背書組合成一個事務payload,并将其廣播至一個ordering service(排序服務節點),ordering service(排序服務節點)為目前channel上的所有peers提供排序服務并生成區塊。

實際上,用戶端在将事務廣播到排序服務之前,先将本次請求送出到peer,由peer來驗證事務。

首先,peer将檢查背書政策,以確定指定的peer的正确配置設定已經簽署了結果,并且他們将根據事務payload對簽名進行身份驗證。

其次,peer将對事務讀取集進行版本控制,以確定資料完整性,并防止諸如重複開銷之類的問題。Hyperledger Fabric具有并發控制,即事務允許并行執行(通過背書)來增加吞吐量,并且在送出(所有peer)的情況下,每個事務都經過驗證,以確定沒有其他事務修改它已經讀取的資料。換句話說,它確定了在執行(準許)時間之後讀取的資料沒有發生變化,是以執行結果仍然有效,并且可以送出到賬本狀态資料庫。如果讀取的資料被另一個事務更改,則該區塊中的相同僚務被标記為無效,并且不應用于賬本狀态資料庫。用戶端應用程式被警告,并且可以在适當的情況下處理錯誤或重試。

(備注:上述最後一段話的邏輯理論上是正确的,即讀取本地版本然後根據本地版本發送廣播至排序服務,再由排序服務進行事務處理。但事務處理結果通過實際使用sdk開發,該結果并未即時傳回給目前調用用戶端,即用戶端無法實時擷取事務狀态,隻能通過再次查詢來确認最終結果。後續版本sdk可能會修複此問題。)