Cosmos被譽爲「區塊鏈的互聯網」,旨在解決區塊鏈可互操做性和可擴展性問題。其區塊鏈間通信協議能夠實現區塊鏈的互聯,支持不一樣區塊鏈之間的資產轉移。隨着區塊鏈協同操做的需求愈加強烈, Cosmos做爲跨鏈技術的佼佼者,值得咱們關注和學習。算法
摘要
本文給出了Cosmos IBC(互聯鏈通訊)協議的技術規範,這個協議在2016年6月Cosmos白皮書中有過首次描述[1]。其它一些技術也能夠在一個原子操做中涵蓋兩個鏈,好比「哈希時間鎖定合同」[2],不過不少(此類技術)都僅限於保證兩個交易同時成功或失敗。IBC則建立了完整的雙向「側鏈」,真正地容許跨鏈傳遞價值,並充分利用Tendermint的即時最終性來實現代幣的快速傳遞。數據庫
IBC使用消息傳遞範式,並容許參與鏈保持獨立。每一個鏈都維護一個局部的部分順序,而消息則用於跟蹤全部跨鏈的因果關係。一旦兩個鏈之間註冊了信任關係,就能夠安全地將數據包從一個鏈發送到另外一個鏈上,表明從一個鏈上的一個帳戶轉移代幣到另外一個鏈上的帳戶。該協議也可擴展到代幣轉移以外(的其它功能) – 儘管爲其餘應用類型設計安全的通訊邏輯還待深刻研究。該協議對鏈之間傳輸數據包時的阻塞時間或網絡延遲不作假設,所以在異構環境中具備很強的魯棒性。安全
本文闡述了Cosmos IBC協議的要求和結構,目標是提供足夠的細節來充分理解和分析協議的安全性。微信
如下是《Cosmos互聯鏈通訊技術規範》譯文的前半部分。網絡
一 、簡介架構
Cosmos IBC是圍繞Cosmos網絡和Tendermint共識引擎而設計的,從根本上依賴於Tendermint的即時最終性屬性(意味着永遠不會建立分叉)。Cosmos網絡將由Cosmos樞紐和多個獨立的分區組成,這些分區都經過IBC與樞紐進行通訊。Cosmos樞紐還能夠經過在它們之間中繼IBC消息來橋接不一樣的分區。框架
咱們從一個簡單情形的具體例子入手,它可用於爲後續的抽象解釋提供一個形式框架。在此以後,將解釋這個例子中使用的消息傳遞語義。接下來就是安全證實和數據包傳輸所依賴的技術基礎。異步
在此以後,將討論更高級的消息類型,例如超時和路由(以使更大的網絡在至關長時間內能高效運做),還要對協議處理全部可能狀況的能力予以充分考慮。分佈式
除了爲IBC協議提供理論理解和參考文檔以外,本文還旨在爲協議的安全基礎提出使人信服的論據。本文是對正在進行的Cosmos項目的一個報告,隨着來自實踐的數據不斷更新理論,咱們也將持續調整它的內容。微服務
2、 示例場景
爲了使討論不那麼抽象,這裏用例子說明一個具體情形是如何工做的。Alice想從她在Cosmos分區X上的帳戶發送30個wink幣(示例代幣名稱)給Cosmos樞紐上的Bob。假設分區X已經跟樞紐創建了一個IBC鏈接,Alice將在分區X上建立一個交易來發起傳輸。分區X會將那些代幣凍結在某個託管帳戶,而後建立一個IBC數據包請求樞紐在Bob的帳戶中建立相應數量的代幣。本質上,分區X上的驗證節點集合會保證銷燬這些代幣以換取在樞紐上重鑄它們。
一個獨立的中繼進程(任何人均可運行的客戶端軟件)能夠從分區X提取那個IBC數據包的證實並將其發佈到樞紐。樞紐將驗證區塊頭,Merkle證實和順序號來確保這是一個從分區X來的有效的IBC數據包。這下咱們面臨兩個選擇:要麼分區X在樞紐上有足夠信用來鑄這30個wink幣從而數據包被接受,要麼信用不夠而數據包被拒絕。若是數據包被接受,樞紐就在Bob的帳戶中鑄30個新鮮的wink幣,並將數據包連同成功記錄存在它的傳入隊列中;若是數據包被拒絕,則不會建立代幣,且隊列中會存入一個失敗記錄。
我說的「信用」指的是什麼?咱們不但願每一個鏈接到樞紐的鏈都能在樞紐上隨意建立任意數量的任意代幣,不然全部經濟保證很快就變得毫無心義。樞紐必須使用它本身的邏輯來驗證它是否足夠信任分區X並接受那30個wink幣。若是分區X是wink幣的本源(X的原生代幣),那麼在發送wink幣到樞紐這件事上,它將獲得樞紐的極大信任。若是樞紐以前已經向分區X發送過500個wink幣,那麼它必須記住這個信息並容許分區X將(不超過)那500個wink幣發送回樞紐,從而實現代幣的自由流動。這個邏輯能夠爲代幣傳輸提供安全性,其它應用則須要在不徹底信任網絡中全部分區的狀況下,運用它們本身的邏輯來維護全局約束條件。
在樞紐成功或不成功地執行了那個交易以後,咱們但願將交易的收據(連同證實)傳回到分區X以完成這個循環。此收據只是另外一種類型的IBC數據包,其執行方式與發送同樣。惟一區別是,在發起分區處理收據毫不能產生錯誤。(根據收據內容)若是交易是成功的,則分區X將銷燬託管的30個wink幣,代幣在分區間轉移成功;若是交易因任何緣由被拒絕,那麼託管代幣就會釋放回Alice的帳戶 – 就像什麼都沒有發生過同樣。
這意味着,在收到響應(成功或失敗)以前,誰也不能碰分區X上的託管代幣。除非咱們有證據證實該數據包被接收鏈拒絕,已經發出的代幣不會被釋放。沒有代幣會被無故建立或銷燬,也不可能執行雙花,代幣不會莫名消失在跨鏈操做中。發送方只須要等待兩個數據包的轉發和執行(不少狀況下是十來秒鐘)。對處理硬分叉分區(如ETH/ETC或BTC/BCH)的考慮會在下面的高級章節討論。
3、 消息傳遞語義
在試圖擴展區塊鏈時,必須找到一種不違反任何安全保證的可行方法,來增長並行寫的數量。防止雙花須要爲任何給定帳戶提供嚴格的串行訪問(讀和寫),可是咱們須要一些安全的方法來容許多個交易同時執行,而又不給惡意利用競態條件提供可能性。
經過IBC協議,咱們尋求避免一個問題,那就是容許多個獨立節點將交易應用到相同的狀態空間。若是你不想丟失任何數據(好比:強最終一致性),這個問題即使不考慮拜占庭角色也是困難的,在面對惡意行動人尋求利用任何不一致爲自身牟利的狀況下,則變得極其困難。安全地將不一樣的部分排序協調成一致的全局排序的最嚴謹方法是CRDTs(無衝突數據複製類型),它保證一組固定交易的全部可選的部分排序都將收斂到相同結果。CRDTs確實頗有趣,但因爲其固有特性,不容許在區塊鏈用例中強制執行約束條件(例如,帳戶餘額永遠不能爲負數)。
這個問題的另外一個解決方案是使用分片,每一個分片都只能訪問狀態空間的一部分。這能夠增長吞吐量,但也會使任何涉及多個分片的交易極難正確執行。觸及多個分片並須要一致視圖的查詢能夠經過使用快照來執行,可是在高度分佈的環境中這可能很困難。若是您想在兩個分片上安全地、原子地查詢和修改數據,就須要相似鎖和三階段提交的機制,這在許多數據庫中都使用過。可是,若是您想要保證順序並在通訊層引入同步和定時假設,這就是一個阻塞操做,這使得它不適合分佈式(多)區塊鏈的場景。
咱們經過定義「分區」而走了一條不一樣的路。每一個分區都是一個獨立的區塊鏈,有本身的應用邏輯,本身的交易和數據存儲。分區應該沿使用界線分開,所以絕大多數交易隻影響一個分區,但咱們能夠保證任何跨鏈交易擁有安全和非阻塞的語義。每一個分區都是一個完整的獨立系統,它們使用消息傳遞進行通訊。它們可以保證本地分區中的交易正確排序和執行,同時容許其它分區裏的交易並行執行。惟一須要全局排序的東西是系統之間發送的消息。
分佈式系統中的消息傳遞是一個已經被深刻研究的領域,也是許多其它系統的搭建基礎。咱們可以對異步消息進行建模,且對信道不作時序假設。這樣的結果是,咱們容許每一個分區以本身的速度行動,不被任何其它分區阻塞,卻可以以當時網絡容許的最快速度通訊。
使用消息傳遞做爲原語的另外一個好處是,接收方可以對傳入的消息應用本身的安全檢查。僅僅由於一個咱們瞭解的分區發送了一條消息給某個特定賬戶添加50個以太幣,並不意味着咱們必須增長餘額。咱們能夠在接收消息時添加咱們本身的業務邏輯,以決定咱們是否想拒絕該消息,以及咱們想如何處理它(若是咱們接受它)。在一個共享狀態的場景中,很難甚至不可能作到這一點。消息傳遞容許每一個分區確保其安全性和自治性,同時容許不一樣的系統做爲一個總體協同工做。這能夠看做是微服務體系架構的一個類比,可是跨越了組織邊界。
爲了在一個可證實的異步消息傳遞原語上構建有用的算法,咱們須要定義一些更高階的結構在全部系統間共享,從而容許咱們和一些更容易的保證打交道。
3.1 可靠消息隊列
咱們在這裏引入的第一個原語是可靠的消息隊列(如下簡稱隊列),這是異步消息傳遞的典型構造,它使咱們可以確保因果排序並避免阻塞。
這個隊列在每一個區塊鏈的Merkle數據存儲中以多個鍵值對的形式永續保存。每一個隊列有一個獨特的前綴,鍵是經過把一個表明其順序號的8字節大端模式整數追加在這個前綴後面生成的。注意這個編碼方式爲咱們提供了一個與鍵的順序號相一致的鍵的字典序,這讓咱們能快速找到最新的數據包,也能證實在某個給定順序位的數據包內容(或沒有數據包) -- 假設像在咱們的IAVL+ Merkle樹[3]裏那樣訪問範圍證實。
新增的任何一個數據包的順序號只能比當前最高數據包的順序號大1。爲了使證實更容易,咱們會將順序號也存在數據包自己(鍵值對的值)裏面。一旦一個數據包被寫入,它就是不可變的(除了在清理期間刪除,這在後面會解釋)。這使得接收分區能夠接受位於源分區高度H的數據包Z的證實,而接收分區處理交易時儘可放心數據包在源分區裏仍然以相同狀態存在(異步性的要求)。區塊鏈應用邏輯必須爲全部隊列保證這些約束條件,以確保消息層的正常運行。
假設咱們的IBC隊列的前綴是0xCAFE,咱們能夠看到多個數據包是如何存在Merkle樹中的,而它們的順序號又是如何追加(生成鍵)的,這樣咱們就能夠輕鬆地爲某個給定數據包的存在(或不存在)提供一個Merkle證實。下面圖示了構建順序號爲2的數據包的Merkle證實的路徑,用橙色高亮顯示。
本節的其他部分將定義可經過此隊列發送的基本消息類型。
3.2 註冊鏈(需經許可)
在兩個鏈之間創建起鏈接以前,咱們須要先讓它們彼此註冊。這一點尤其重要,由於全部輕客戶端證實都須要一個對驗證消息頭相當重要的信任種子,當有未經共識算法批准的惡意分支存在時,它能讓咱們確認那條真的鏈。
爲了在A和B之間造成鏈接,咱們必須在B上註冊A,也要在A上註冊B。這些過程是對稱的,因此在這裏咱們只描述如何在A上註冊B。在註冊時,A爲B添加一個可信的消息頭和驗證節點集合,保存在它的安全數據存儲中。這用於驗證來自B的全部將來的消息頭,以及驗證節點集合的變動。A還要建立兩個具備不一樣名稱(前綴)的隊列。
ibc:<B的鏈標識>:out – 存放全部以B爲目的地的傳出數據包
ibc:<B的鏈標識>:in – 存放全部來自B的傳入數據包連同它們的執行結果
注意,註冊鏈應該是一個須要得到許可的操做,且執行時要有人工驗證。這將產生一個信任聲明,即這個消息頭和驗證節點集合表明了對應鏈的正確狀態,它們不屬於試圖鏡像這條鏈的某些影子鏈。不像PoW的最長鏈勝出算法,對權益證實而言信任必須在某個時點被明確授予。
並且,註冊過程還必須定義好咱們用來驗證Merkle證實的算法(這些證實存在於隊列中的IBC數據包裏)。缺省設置是來自咱們的IAVL樹的Merkle證實格式,可是其餘Merkle化的數據存儲,好比Patricia Trie,也能夠獲得支持。這個算法必須在註冊時設置一次,而且必須被參與鏈所支持。隊列的整個生命週期都會基於可信的消息頭,一致地使用該算法驗證每一個數據包或收據。
3.3 驗證節點變動
任何生產鏈的驗證節點集合都會隨着時間推移而發展變化。當咱們註冊一個新鏈時,會針對一個特定的驗證節點集合作一個信任聲明 (更具體而言,咱們的信任綁定的是這樣一個條件:消息頭擁有超過必定閾值數量的與給定公鑰集相匹配的數字簽名)。當咱們信任的這組公鑰變化時,咱們須要一個消息來把這個變動通知給其它鏈。因爲驗證節點變動對共識算法相當重要,因此咱們用一個標準格式把它存儲在Tendermint的區塊頭內。
咱們定義一個特殊的更新數據包,它包含一個Tendermint區塊頭和新的驗證節點集合,咱們能夠將它發送給接收鏈。接收鏈能夠覈實驗證節點集合變動的有效性,並使用它來驗證全部將來的數據包。
3.4 發送數據包
發送一個IBC數據包涉及區塊鏈應用邏輯調用IBC模塊,告訴它須要發送的數據包以及目標鏈的標識。若是目標鏈已經註冊好,IBC模塊只需計算下一個順序號並將其添加到傳出隊列out queue。順序號與特定鏈接相關並由發送鏈生成,它們必須是單調遞增和連續的。
數據包被寫入Merkle化的數據存儲,這樣它就嵌入了和區塊頭相關聯的證實當中。這些表明了數據包的鍵值對證實接下來就會被傳送給其它鏈。
區塊鏈應用程序必須對誰能夠寫一個隊列的鍵空間作出限制,不是隨便哪一個智能合約均可以在那裏寫交易數據,只有當區塊鏈邏輯斷定數據包有效,且與數據包類型相關的全局約束條件獲得知足(好比:上面例子中的託管代幣被凍結),纔會生成(並寫入)數據包。
3.5 中繼數據包
爲了讓數據包到達目標鏈,咱們依靠一個或多箇中繼進程把鏈A上的傳出證實out proof發佈到鏈B的傳入隊列in queue中。因爲這裏只須要輕客戶端證實,中繼進程不須要是驗證節點,甚至都不須要是全節點。實際上,若是每一個發起建立IBC數據包的用戶也負責將它中繼到接收鏈,那就太理想了。惟一的限制是,中繼進程必須可以在目標鏈上支付適當的費用。
爲了系統自舉,鏈開發人員能夠提供一個有足夠資金的特殊帳號給中繼進程,爲全部數據包支付費用,直到用戶在兩個鏈上都有代幣。不過,使用IBC的人應該本身負責支付這些費用。注意,更新消息頭是一種代價高昂的交易(大約100個數字簽名校驗),而爲一個已知消息頭髮布證實則要便宜得多(大約20個哈希計算)。所以,爲了優化,許多數據包能夠捆綁在一塊兒在同一區塊高度發送,即便它們是在不一樣的區塊高度建立的,這樣能夠經過增長一點延遲來節省計算成本。
系統必須容許多箇中繼進程安全地並行運行,拒絕掉任何重複的消息發佈。但更理想的是能在起初就防止他們嘗試重複發佈,由於這會浪費帶寬和鏈上的計算時間。
3.6 收據
當一個IBC數據包發佈到另外一個鏈上並被認爲是有效的(即,數據包的證實跟源鏈的已知消息頭相匹配),則無論執行是否成功,咱們都必須將它存儲在傳入隊列in queue裏,這樣就有證據代表它已經被處理過。相關交易應該發送到合適的智能合約加以驗證和執行,而後返回標準的ABCI結果(成功或錯誤);收到的數據包連同處理結果被寫進傳入隊列。
另外一箇中繼進程能夠得到這個數據包已經在鏈B上處理過的證實,把它做爲收據發佈到鏈A。此收據將由鏈A處理,觸發進一步的應用邏輯,以及對隊列的清理(參見高級部分)。將請求從A中繼到B的那個進程能夠將響應從B中繼回A,但也可使用一個不一樣的進程來作這件事。
做者:Ethan Frey, frey@tendermint.com
譯者:奚海峯 Haifeng Xi
校對:曹恆 Harriet Cao
本文首發於萬雲Wancloud微信號,未經受權不容許轉載。
。