區塊鏈鍵值
1. 組成區塊鏈基礎運算功能的組織架構內容
隨著互聯網的都不發展,消費者對區塊鏈技術和數字虛擬貨幣的認知程度也在不斷的提高。今天,我們就一起來了解一下區塊鏈技術的基礎運算方法都有哪些結構構成的。下面java課程http://www.kmbdqn.cn/就一起來了解一下具體情況吧。
構成計算技術的基本元素是存儲、處理和通信。大型主機、PC、移動設備和雲服務都以各自的方式展現這些元素。各個元素之內還有專門的構件塊來分配資源。
本文聚焦於區塊鏈的大框架:介紹區塊鏈中各個計算元素的模塊以及各個模塊的一些實現案例,偏向概論而非詳解。
區塊鏈的組成模塊
以下是去中心化技術中各個計算元素的構件塊:
存儲:代幣存儲、資料庫、文件系統/blob
處理:有狀態的業務邏輯、無狀態的業務邏輯、高性能計算
通信:數據、價值和狀態的連接網路
存儲
作為基本計算元素,存儲部分包含了以下構件塊。
代幣存儲。代幣是價值的存儲媒介(例如資產、證券等),價值可以是比特幣、航空里程或是數字作品的版權。代幣存儲系統的主要作用是發放和傳輸代幣(有多種變體),同時防止多重支付之類的事件發生。
比特幣和Zcash是兩大「純凈」的、只關注代幣本身的系統。以太坊則開始將代幣用於各種服務,以實現其充當全球計算中心的理想。這些例子中代幣被用作運營整個網路架構的內部激勵。
還有些代幣不是網路用來推動自身運行的內部工具,而是用做更高級別網路的激勵,但它們的代幣實際上是存儲在底層架構中的。一個例子是像Golem這樣的ERC20代幣,運行在以太坊網路層上。另一個例子是Envoke的IP授權代幣,運行在IPDB網路層上。
資料庫。資料庫專門用來存儲結構化的元數據,例如數據表(關系型資料庫)、文檔存儲(例如JSON)、鍵值存儲、時間序列或圖資料庫。資料庫可以使用SQL這樣的查詢快速檢索數據。
傳統的分布式(但中心化)資料庫如MongoDB和Cassandra通常會存儲數百TB甚至PB級的數據,性能可達到每秒百萬次寫入。
SQL這樣的查詢語言是很強大的,因為它將實現與規范區分開來,這樣就不會綁定在某個具體的應用上。SQL已經作為標准應用了數十年,所以同一個資料庫系統可以用在很多不同的行業中。
換言之,要在比特幣之外討論一般性,不一定要拿圖靈完備性說事。你只需要一個資料庫就夠了,這樣既簡潔又方便擴展。有些時候圖靈完備也是很有用的,我們將在「去中心化處理」一節具體討論。
BigchainDB是去中心化的資料庫軟體,是專門的文檔存儲系統。它基於MongoDB(或RethinkDB),繼承了後者的查詢和擴展邏輯。但它也具備了區塊鏈的特徵,諸如去中心化控制、防篡改和代幣支持。IPDB是BigchainDB的一個受監管的公開實例。
在區塊鏈領域,也可以說IOTA是一個時間序列資料庫。
文件系統/blob數據存儲。這些系統以目錄和文件的層級結構來存儲大文件(電影、音樂、大數據集)。
IPFS和Tahoe-LAFS是去中心化的文件系統,包含去中心化或中心化的blob存儲。FileCoin、Storj、Sia和Tieron是去中心化的blob存儲系統,古老而出色的BitTorrent也是如此,雖然後者使用的是p2p體系而非代幣。以太坊Swarm、Dat、Swarm-JS基本上都支持上述兩種方式。
數據市場。這種系統將數據所有者(比如企業)與數據使用者(比如AI創業公司)連接在一起。它們位於資料庫與文件系統的上層,但依舊是核心架構,因為數不清的需要數據的應用(例如AI)都依賴這類服務。Ocean就是協議和網路的一個例子,可以基於它創建數據市場。還有一些特定應用的數據市場:EnigmaCatalyst用於加密市場,Datum用於私人數據,DataBrokerDAO則用於物聯網數據流。
處理
接下來討論處理這個基本計算元素。
「智能合約」系統,通常指的是以去中心化形式處理數據的系統[3]。它其實有兩個屬性完全不同的子集:無狀態(組合式)業務邏輯和有狀態(順序式)業務邏輯。無狀態和有狀態在復雜性、可驗證性等方面差異巨大。三種去中心化的處理模塊是高性能計算(HPC)。
無狀態(組合式)業務邏輯。這是一種任意邏輯,不在內部保留狀態。用電子工程術語來說,它可以理解為組合式數字邏輯電路。這一邏輯可以表現為真值表、邏輯示意圖、或者帶條件語句的代碼(if/then、and、or、not等判斷的組合)。因為它們沒有狀態,很容易驗證大型無狀態智能合約,從而創建大型可驗證的安全系統。N個輸入和一個輸出需要O(2^N)個計算來驗證。
跨賬本協議(ILP)包含crypto-conditions(CC)協議,以便清楚地標出組合電路。CC很好理解,因為它通過IETF成為了互聯網標准,而ILP則在各種中心和去中心化的支付網路(例如超過75家銀行使用的瑞波)中廣泛應用。CC有很多獨立實現的版本,包括JavaScript、Python、Java等。BigchainDB、瑞波等系統也用CC,用以支持組合式業務邏輯/智能合約。
2. 區塊鏈核心技術-P2P網路
點對點網路是區塊鏈中核心的技術之一,主要關注的方面是為區塊鏈提供一個穩定的網路結構,用於廣播未被打包的交易(交易池中的交易)以及共識過的區塊,部分共識演算法也需要點對點的網路支撐(如PBFT),另外一個輔助功能,如以太坊的消息網路,也需要點對點網路的支持。
P2P網路分為結構化和非結構化網路兩類。結構化網路採用類似DHT演算法來構建網路結構;非結構化網路是一種扁平的網路,每個節點都有一些鄰居節點的地址。
點對點網路的主要職責有維護網路結構和發送信息這兩個方面。網路結構要關注的是新節點的加入和網路更新這兩個方面,而發送信息包括廣播和單播兩個方面
如何建立並維護點對點的整個網路?節點如何加入、退出?
網路結構的建立有兩個核心的參數,一個是每個節點向外連接的節點數,第二個是最大轉發數。
新節點對於整個網路一無所知,要麼通過一個中心的服務獲取網路中的一些節點去連接,要麼去連接網路中的「種子」節點。
網路更新處理當有新節點加入或者節點退出,甚至原來一些節點網路不好,無法連接,過一段時間又活了,等等這些情況。一般通過節點已有的連接來廣播這些路由表的變化。需要注意的是,因為點對點網路的特殊性,每個節點的路由表是不一樣的(也叫partial view)
廣播一般採用泛洪協議,即收到轉發方式,使的消息在網路中擴散,一般要採用一些限制條件,比如一條消息要設置最大的轉發數,避免網路的過渡負載。
單播需要結構化網路結構支持,一般是DHT,類似於DNS解析的方式,逐跳尋找目標節點地址,之後進行傳輸,並且更新本地路由表。
要想快速檢索信息,有兩種數據結構可以使用,一種是樹類型,如AVL樹、紅黑樹、B樹等;另外一類是hash表。
哈希表的效率比樹更高,但是需要佔用更多的內存。
信息的表示採用鍵值對的方式,即一個鍵對應一個值,我們要查找的是key,值是附著的信息。
哈希表要解決的問題是如何均勻地為每一個key分配一個存儲位置。
這裡面有兩個重點:1.是為key分配一個存儲地點,這個分配演算法是固定的,保證存儲的時候和查找的時候使用同一個演算法,不然存進去之後會找不到;2.是均勻地分配,不能有點地方存放數據多,有點放存放數據少。
一般語言裡面的hashtable、map等結構使用這個技術來實現,哈希函數可以直接使用取模函數,key%n,這種方式,n代表有多少個地方,key是整數,如果key是其他類型,需要先進行一次哈希,將key轉為整數。這種方式可以解決上面的兩個需求,但是當n不夠大的時候(小於要存儲的數據),會產生沖突,一個地方一定會有兩個key要存儲,這時候,需要在這個地方放一個鏈表,將分配到同一地點、不同key,順序擺放。當一個地點放的key太多後,鏈表的查找速度太慢,要轉化為樹類型結構(紅黑樹或者AVL樹)。
上面說過,哈希表效率很高,但是佔用內容,使用多台機器就可以解決這個限制。在分布式環境中,可以將上述的地點理解為計算機(後面成為節點),即如何將一個key映射到一個節點上,每個節點有一個節點ID,即key->node id的映射,這個映射演算法也要固定。
這個演算法還有一個非常重要的要求,即scalebility,當新節點加入和退出時候,需要遷移的key要盡量少。
這個映射演算法有兩種典型結構,一個是環形,一個是樹形;環形的叫一致性哈希演算法,樹形的典型叫kademlia演算法。
選點演算法就是解決key->node id的映射演算法,形象的來說就是為一個key選擇它生命中的她(節點)。
假設我們使用32哈希,那麼總共能容納的key的數據量是2**32,稱之為hash空間,把節點的ID映射成整數,key也映射成整數。把key哈希和節點哈希值接的差值的叫做距離(負數的話要取模,不用絕對值),比如一個key的哈希是100(整數表示),一個節點的哈希是105,則這兩個的距離是105-100=5。當然使用其他距離表示也可以,比如反過來減,但是演算法要固定。我們把key映射(放到)距離他最近的節點上。距離取模的話,看起來就是把節點和key放到一個環上,key歸屬到從順時針角度離它最近的節點上。
kademlia演算法的距離採用的是key哈希與節點哈希異或計算之後的數值來表示(整數),從左往右,擁有越多的「相同前綴」,則距離越近,越在左邊位置不一樣,距離越遠。
樹結構的體現是,將節點和key看成樹的節點,這個演算法支持的位數是160bit,即20個8位元組,樹的高度為160,每個邊表示一位。
選點的演算法和一致性哈希相同,從所有節點中,選擇一個距離key距離最小的節點作為這個key的歸宿。
由於是在分布式環境中,為了保證高可用,我們假設沒有一個中心的路由表,沒有這個可以看到全貌的路由表,帶來了一些挑戰,比如如何發現節點、查找節點?
在P2P網路中,常用的方法是每個節點維護一個部分路由表,即只包含部分節點的路由信息。在泛洪演算法中,這些節點上隨機的;在DHT演算法中,這個路由表是有結構的,維護的節點也是有選擇性的。那麼如何合理的選擇需要維護路由信息的節點呢?
一個樸素的做法是,每一個節點保存比他大的節點的信息,這樣可以組成一個環,但是這樣做的話,有一個大問題和一個小問題。大問題是,每個節點知道的信息太少(只有下一個節點的哈希和地址),當給出一個key時,它不知道網路中還有沒有比它距離這個key距離還短的節點,所以它首先判斷key是否屬於自己和下一個節點,如果是,那麼這個key就屬於下一個節點,如果不是就調用下一個節點同樣的方法,這個復雜度是N(節點數)。一個優化的方法是,每個節點i維護的其他節點有:i+2 1, i+2 2,....i+2**31,通過觀察這個數據,發現由近到遠,節點越來越稀疏。這樣可以把復雜度降低到lgN
每個節點保存的其他節點的信息,包括,從左到右,每一位上與本節點不同的節點,最多選擇k個(演算法的超參數)。比如在節點00110上(為演示起見,選擇5位),在要保存的節點路由信息是:
1****: xxx,....,xxx(k個)
01 : xxx,....,xxx(k個)
000 : xxx,....,xxx(k個)
0010 : xxx,....,xxx(k個)
00111: xxx,....,xxx(k個)
以上為一行稱為k-bucket。形象的來看,也是距離自己越近,節點越密集,越遠,節點越稀疏。這個路由查找、節點查找的演算法也是lgN復雜度。