1. 程式人生 > 程式設計 >Libra教程之:Libra protocol的邏輯資料模型

Libra教程之:Libra protocol的邏輯資料模型

Libra protocol簡介

Libra區塊鏈本質上是一個加密資料庫,這個資料庫是通過Libra protocol來維護的。所以Libra protocol是Libra區塊鏈的核心。

Libra protocol的核心是賬戶,resources和module.

資料庫主要儲存可程式設計的resources賬本,比如:Libra coin。這些resources是由定義的module來約定的,這些module也儲存在資料庫中。

resources屬於賬戶,並通過公鑰加密來認證。

帳戶可以代表系統的直接終端使用者,也可以代表實體,例如 代表使用者的保管錢包。

帳戶所有者通過sign transactions來使用帳戶內的資源。

下面是一個client和validators使用libra protocol進行互動的例子:

graph LR
	A[client]-->|1.client request|B[leader]
	B-->|2.proposes transactions|C[other validators]
	B-->|3.execute the transactions|B
	C-->|3.execute the transactions|C
	C-->|4.vote|B
	B-->|5.responses|A
複製程式碼

具體分析一下每個步驟:

  1. 驗證器維護資料庫並處理客戶提交的交易,以將其包括在資料庫中。
  2. 驗證者使用分散式共識協議來保證交易的提交。驗證者不是不斷輪動的。當驗證人擔任領導者時,它會提出交易,包括直接由客戶提交給的他的交易以及通過其他驗證者間接提交給其他驗證者的交易。3. 所有驗證程式執行交易並形成包含經過身份驗證的資料結構:新的賬本的歷史記錄。
  3. 作為共識協議的一部分,驗證者對該資料結構的驗證者進行投票。
  4. 作為在版本i上提交事務Ti的一部分,共識協議在版本i的資料庫完整狀態上輸出一個簽名-包括其整個歷史記錄來作為對來自客戶端的查詢的驗證響應。

客戶端可以向驗證器發出查詢,以從資料庫讀取資料。 由於資料庫已通過身份驗證,所以可以確保客戶查詢響應的準確性。

此外,客戶端可以選擇通過同步驗證者的交易記錄來建立整個資料庫的副本。

在建立副本時,客戶端可以驗證驗證者是否正確執行交易,從而提高了系統的可靠性。 其他客戶端可以從持有副本的客戶端讀取資料,方式與從驗證程式讀取客戶端的方式相同。 為了簡單起見,本文其餘部分假設客戶端直接查詢驗證器而不是副本。

邏輯資料模型

Libra區塊鏈的所有資料都儲存在一個單一的帶版本的資料庫中。資料庫的版本號是由一個無符號的64-bit的整數來表示。這個整數是系統目前執行的交易個數。

假如在某個版本i,資料庫包含元組(Ti,Oi,Si),其中Ti表示交易,Oi表示交易的輸出,Si表示版本的賬本狀態。

假如版本執行了一個Apply函式,那麼這元組的意思就是:在賬本狀態Si-1執行了一個Ti交易,產生了一個輸出Oi,和一個新的賬本狀態Si。

簡單說就是如下的公式: Apply(Si−1,Ti)->⟨Oi,Si⟩.

Libra協議使用Move語言來實現這個Apply功能,我們會在後面的文章中介紹。本章我們主要講解版本資料庫的交易和查詢功能。

賬本狀態

賬本狀態是Libra區塊鏈的基礎,他包括每個使用者在不同版本的狀態。 每個驗證者都可以獲取最新的分類賬本狀態。

賬本結構為鍵值儲存,可將帳戶地址鍵對映到帳戶值。 賬戶 在分佈賬本狀態下,是已釋出的Move資源和模組的集合。 其中Move資源儲存資料值,模組儲存程式碼。

在賬本初始化的過程中,我們會建立一部分內建的賬戶。

賬戶地址

賬號地址是一個256-bit的值。使用者可以在本地建立公私鑰對,然後將公鑰的加密hash值作為賬戶的地址。這裡要注意的是,這個賬號地址只有發生交易的時候才會被建立(比如有Libra幣被髮送到這個地址的時候)。

賬戶建立之後,使用者就可以使用私鑰簽名來使用這個賬號來傳送交易。使用者可以在不更換賬號地址的情況下,來更換或者輪循私鑰。

如果你願意,一個使用者可以建立無限多個賬戶。

Resource

之前講到了狀態資料庫是一個key-value形式的結構。key就是account的地址,value可以是resource也可以是module。

每一個resource都有一個由module宣告的型別。resource的型別包含型別的名字和定義該型別的module的名字和地址。

假如我們有兩個賬戶:Ox12和Ox34. 在Ox12中定義了一個module:Currency,在這個module中定義了一個type T。那麼這個型別的名字就叫:Ox12.Currency.T。

這個型別的名字是唯一的,即使你在其他的賬戶中使用這個型別。比如我在Ox34中使用了這個型別,那麼可以從Ox34中這樣獲得該resource: 0x34/resources/0x12.Currency.T.

這樣設計的目的是讓所有的資源型別都有一個統一的名字。

Module

Module主要是使用Move位元組碼來宣告資源和procedures。和資源一樣,Module也是通過賬戶地址來定位的,比如上面的Currency Module的標誌就是:Ox12.Currency。

在當前的Libra版本中,Module是不可更改的。一旦該Module在賬戶中宣告之後,就不可以刪除和更改,除非進行硬分叉。這個限制可能在未來的版本中發生改變。

交易

客戶端通過提交Transaction來更新Libra區塊鏈。通常來說Transaction包含一個交易指令碼和交易指令碼所需要的引數。

驗證者使用當前賬本狀態和交易指令碼的輸入產生一個固定的輸出結果。賬本的狀態只有當交易被共識提交之後,才會生效。

交易輸出

執行一個交易Ti會產生一個新的賬本狀態Si,執行結果程式碼(執行是否成功),使用的gas,和event列表。

事件

事件列表是通過執行事務產生的一系列副作用。Move程式碼 在事件structure中出發時間。 每個事件都與唯一鍵相關聯, 通過這個唯一鍵,可以確定發出事件的結構以及有效payload(有關事件的詳細資訊)。

一旦在共識協議中達成交易,交易產生的事件會被新增到賬本歷史中,並在相應的事件中提供成功執行的證明。 例如,一個 付款交易會產生一個事件,使接收者可以確認已付款收到並確認付款金額。

看起來好像Event是多餘的,因為除了查詢交易產生的事件以外,客戶端還可以通過查詢blockchain是否包含該交易來確定。

但是這很容易出錯,因為包含Ti並不意味著成功執行(例如, gas用完後可能會被打斷)。 在交易可能失敗的系統中, event中的證據,不僅表明特定交易已執行,而且已成功完成 完成了預期的效果。

交易只能生成events,他們並不能讀取event,這樣的設計是為了讓交易關注與最新的state資訊,而不是歷史的event資訊。

賬本歷史

賬本歷史按順序儲存著提交和執行的交易及其相關聯的事件。賬本歷史主要是用來儲存記錄,讓大家知道最新的賬本狀態是怎麼計算出來的。

和其他的區塊鏈不一樣的是,Libra賬本歷史並沒有交易塊的概念,在邏輯資料模型中,交易是順序執行的,並不需要區分到底這個交易在哪個塊裡面。

雖然驗證者不需要賬本歷史來產生新的賬本狀態,但是客戶端可以使用這個賬本歷史來驗證和查詢相應的交易資訊。

驗證者通過查詢歷史賬本來告訴客戶端之前的賬本狀態,交易和相應的輸出。

客戶可以通過在在歷史賬本狀態上重新執行特定的交易,通過驗證輸出的結果和執行後的賬本狀態來驗證該交易是否被正確的執行。

更多教程請參考 flydean的部落格