全長2760 字,預計閱讀10 分鐘作者:DaviRain 撰文:MiX
章魚網絡DaviRain 受邀參加RUST.CC 中國大會,分享主題為《通過Substrate - IBC 實現Substrate 資產跨鏈》的Workshop。主要討論了IBC 跨鏈通信協議,以及Substrate-IBC 在Substrate 上實現的IBC 協議,最後通過實戰,在Substrate 的模版上配置Substrate-IBC 完成一筆ICS20 的跨鏈轉賬演示。
https://github.com/octopus-network/substrate-ibc
主要內容分為四個部分:
- 什麼是IBC 協議以及IBC 生態的現狀
- Substrate-IBC 架構的介紹
- 在Barnacle 模版配置Substrate-IBC Pallet
- 演示IBC 協議的同質化代幣跨鏈轉賬功能
以下為分享實錄:
我們先看看Substrate-IBC 的來源。
Substrate-IBC 是由Interchain 基金會資助,由章魚網絡提案並開發的一個Substrate Pallet 模塊,是連接Polkadot 和Kusama 與Cosmos 的重要一步,使兩個生態系統之間的資產和數據的安全交換成為可能。 Substrate-IBC 模塊,使開發者能夠創建帶有IBC 功能的Substrate 區塊鏈。這個模塊的目標是讓建立在Substrate 上的區塊鏈可以通過IBC 協議以無信任方式與其他支持IBC 的區塊鏈進行交互。為最終的區塊鏈互聯網章魚網絡貢獻出自己的一份力量。
背景講完了,下面讓我看看IBC 協議具體到底是什麼,以及IBC 生態的現狀。
IBC 是Inter-Blockchain Communication(跨鏈通信)的縮寫。 IBC 協議是一個端到端的、面向連接的、有狀態的協議,用於可靠有序和認證的分佈式賬本上的模塊之間的通信。
IBC 協議採用分層設計,主要分為2層:IBC/TAO 和IBC/APP。
1、IBC/TAO:TAO 是指Transport,Authorization,Organization,該協議處理分佈式賬本數據之間的傳輸,認證、排序。
2、IBC/APP:基於TAO 構建的上層應用層,定義了從傳輸層發送過來的數據的處理方式,如同質化代幣轉移和非同質化代幣轉移。
實現IBC 協議的大多數工作集中在TAO 層,一旦TAO 層實現,則很容易在TAO 層之上實現不同的APP 層。
這裡有幾點需要注意的是,鏈之間的通信依賴Relayer 通信,Relayer 相當於IBC 協議的物理層,Relayer 會掃描運行IBC 協議的區塊鏈,並負責向其他區塊鏈報告最新的狀態。多個Relayer 可以為多個Channel 傳輸數據,Relayer 使用每個鏈上的Light Client 來交易發送過來的消息。
下面我們詳細的來看下IBC 的TAO 層,IBC 的TAO 層很清晰的分成了3個模塊:Channel、Connection 還有Light Client。
這也是IBC 生態內的人都叫IBC 協議為區塊鏈的TCP/IP 協議的原因。
當初的TCP/IP 協議之所以能作為標準互聯網協議存在長達近50年之久,是由於它足夠簡潔和靈活。迄今為止,個人電腦,服務器,智能手機均採用這一協議。這一協議甚至也被用在小型物聯網設備上並且經受住了多輪互聯網技術更新和迭代的考驗。
和TCP/IP 協議類似,IBC 的特殊性在於它可以將應用層(Application Layer)從傳輸層和網絡層(TAO, Transport, Authorization, Organization)中剝離出來。
這意味著IBC 定義了數據是如何跨鏈被發送和接受,並且沒有明確具體的數據以及這些數據是如何組織結構的。這使得IBC 從其他一些需要在應用層實現大量標準化的互聯互通解決方案中脫穎而出。
IBC/TAO 層的主要作用,在兩個鏈之間以Reliable,Rodered and Authenticated 方式傳遞數據包。
- Reliable 是指原鏈僅發送一個Packet,目標鏈僅接受一次,二者無需信任任何第三方。
- Ordered:是指目標鏈接受Packet 的順序與原鏈發送Packet 的順序一致。
- Authenticated:每個Channel 分配給特定的模塊,只有分配導Channel 的模塊可以通過這個Channel 發送Packet,任何其他模塊無法使用該Channel 發送Packet。
講完了IBC/TAO的大概分層模塊,讓我們具體的看下各個模塊的具體的實現,我們先看下Light client這個模塊。
這個模塊是整個IBC 協議的核心。
從名字我就可以知道這是輕客戶端,輕客戶端的歷史可以很早就在比特幣中提出了,也稱為輕節點,相當於全節點來說,當時主要用於比特幣的簡化支付驗證(SPV)。這樣的輕客戶端往往不與鏈進行直接交互,而依賴全節點作為中介,從全節點請求某種信息,例如發送交易、驗證賬戶餘額和請求區塊頭。
IBC 協議的核心就是一種無第三方信任的密碼學驗證的輕客戶端驗證邏輯。 IBC 中用於驗證遠程狀態機的狀態更新的算法稱為“合法性判定”。將合法性判定與一個可信的狀態組合在一起,就可以實現遠程狀態機基於本地狀態機的“輕客戶端”功能。除了驗證狀態的更新,每個輕客戶端也有能力通過“不良行為判定”來檢測不良行為。不良行為判斷用來懲戒作惡行為。通過維護輕客戶端的狀態,來驗證連接和通道的狀態。
輕客戶端是IBC/TAO 的基礎,輕客戶端有一個為一個Client ID 作為標識,Light Client 會追踪其他區塊鏈的共識狀態,並且會基於共識狀態驗證對方區塊鏈發送過來數據的合法性。 Relayer 只負責消息的傳遞,消息的合法性是依賴於輕客戶端做驗證,所以IBC的安全性並不依賴於第三方服務比如Relayer。這是為什麼IBC 協議稱為無需信任的原因。這是密碼學證明提供的安全性來實現的。
然後我們看下Connection。 Connection 是建立在Light Client 之上的一個模塊。是連接兩個分佈式賬本的通道。一個Light Client 可以接受任意數量的Connection。 Connection 通過四次握手完成,所有操作都是由Relayer 發起交易來觸發,下面就是從一個鏈到另一個鏈之間連接建立的過程:
- connOpenInit:在AppChian0 鏈上會創建並存儲INIT 狀態。之後Relayer 會中繼產生的ConnectionOpenInit 事件,事件中有密碼學相關的證明。
- connOpenTry:之後AppChain1 鏈若驗證AppChian0 鏈上該Connection 狀態為INIT,則在AppChian1 鏈上創建並存儲TRYOPEN 狀態。再由Relayer 中繼產生的ConnectionOpenTry 事件。
- connOpenAck:然後AppChian0 鏈若驗證AppChian1 鏈上該Connection 狀態為TRYOPEN ,則將AppChian0 鏈上該Connection 的狀態由INIT 更新為OPEN。 **再由Relayer 中繼產生的ConnectionOpenAck事件。
- connOpenConfirm:然後AppChian1 鏈若驗證AppChian0 鏈上該Connection 狀態已由INIT 更新為OPEN,則將AppChian1 鏈上該Connection 狀態由TRYOPEN 更新為OPEN。
至此整個Connection 創建完成。連接說完了下面在看一些Channel。
Connection 和Light Client 構成了IBC 中傳輸層的主要組件。但是,IBC 中的應用程序之間的通信是通過Channel 進行的,Channel 在應用程序模塊與另一條鏈上的相應應用程序模塊之間進行路由。這些應用程序由端口標識符命名,例如ICS-20 Token 傳輸的Transfer。 Channel 通過四次握手完成,所有操作都是由Relayer 發起交易來觸發。
下面就是從一個鏈到另一個鏈之間連接建立的過程。
可以看到Channel 的創建和Connection 是類似的,有一點不同的是,所有上層的應用的邏輯實現都是在這些ChannelOpenInit,chanOpenTry 等等發生事件之後回調接口實現的,當這些事件發生的時候也會觸發應用層的邏輯。
chanOpenInit:在AppChain0 鏈上會創建並存儲INIT狀態。之後Relayer 會中繼產生的chanOpenInit 事件,事件中有密碼學相關的證明,
chanOpenTry:之後AppChain1 鏈若驗證AppChain0 鏈上該Channel 為INIT 狀態,則在AppChain1 鏈上創建並存儲TRYOPEN 狀態。再由Relayer 中繼產生的ChanOpenTry 事件。
chanOpenAck:然後AppChain0 鏈若驗證AppChain1 鏈上該Channel 為TRYOPEN 狀態,則將AppChain0 鏈上該Channel 的狀態由INIT 更新為OPEN。再由Relayer 中繼產生的chanOpenAck 事件。
chanOpenConfirm:然後AppChain1 鏈若驗證AppChain0 鏈上該Channel 狀態已由INIT 更新為OPEN ,則將AppChain1 鏈上該Channel 狀態由TRYOPEN 更新為OPEN。
至此整個Channel 創建完成。
這裡有關IBC/TAO 模塊的部分講完了,讓我們繼續看下IBC/APP 模塊。
IBC/APP 模塊這裡,我們主要講ICS20 模塊也就是同質化代幣轉移模塊,這也是這次Workshop 最終的目標。
使用IBC 的Ics20 模塊可以構建跨鏈轉移Token 的應用,在做跨鏈轉移的時候最重要的是需要確定轉移的Token 是不是當前鏈。
- 如果Token 是當前鏈的Native Token,那麼當前鍊是Token 的源鏈。
- 如果Token 是當前鏈通過Channel 從其他鏈接受的Token,那麼當前鏈不是Token 的源鏈。
區分好了當前Token 的鍊是否是原鏈就可以做Token 轉移了,這是因為Token 從原鏈到目標鍊和Token 從目標鏈到原鏈的邏輯是不同的,可以看到AC0 Token 從Appchain0 到Appchain1,AC0 Token 將在Appchain0 鏈上被託管,在Appchain1上將Mint 出AC0 等額度的Token。 AC0 Token 從Appchain1到Appchain0,AC0 Token 將在Appchain1 上被銷毀,在Appchain0 上釋放出託管的ACO Token 。
ICS20 的核心原理就是這個樣子的,總結來說, Appchain0 鏈上的IBC 模塊會不斷的同步Appchain1 鏈上的區塊頭信息, Appchain1 鏈上的IBC 模塊同理。通過這種方式,雙方能夠實現跟踪對方區塊鏈上的驗證者集合的變化,本質上來說,就是Appchain0 鏈、 Appchain1 鏈相互維護了一個對方的輕節點。當使用IBC 開始一筆跨鏈轉賬之後, Appchain0 鏈上的10個AC0 Token 就會處於鎖定的狀態。一份證明AC0 鏈上已經鎖定10 AC0 Token 的Proof會被路由到Appchain1 鏈上的IBC 模塊。
Appchain1 鏈結合Appchain0 鏈的輕節點信息,對這份Proof 驗證通過之後, Appchain1 鏈上會“鑄造”10份AC0 跨鏈資產,這些跨鏈資產可以進行後續的流通使用。當然這些跨鏈資產也可以通過同樣的跨鏈方式返回到Appchain0 鏈, Appchain0 鏈上的AC0 Token 相應執行解鎖的操作。
最後給出一個IBC 消息通信的總結:
1、IBC 跨鏈通信雙方先建立起客戶端,建立連接通道。
2、從一個用戶發送一筆交易,需要經過ISC20 模塊的在Token 發送的原鏈上託管代幣,然後經過Relayer 的中繼在目標鏈上Mint 出接受到Token 數量。
原理介紹了這麼多,我們來看看IBC 的現狀以及生態。
從這張圖,我們看到從去年的9月份到現在,整個的IBC 的網絡在逐漸的繁榮。測試網於之前相比多一倍還要多。
通過IBC 連接的網絡有Cosmos hub, Osmosis, Crypto.com, Juno network, IRIS, Incective 等等40多個的鏈已經都在主網上線。
這個是現在最近的一些網絡,啟動IBC 互聯的區塊鏈。
然而這僅僅是Cosmos SDK 開發的鏈,對於使用Substrate 開發框架來說,我們沒有看到,這也是我們開發Substrate-IBC 的一部分原因,當然對比到別的跨鏈協議IBC 協議可以說是最簡明且安全的協議了。這裡說的安全是是對於第三方是無須信任的。 Relayer 僅僅只是中繼數據包。通過集成Substrate-IBC 就可以使得使用Substrate 框架開發的單鏈具有了和帶有IBC 協議實現的區塊鏈(不僅僅是Cosmos SDK實現)之間跨鏈通信的功能成為了可能。
這裡我們看下Substrate-IBC 這個項目的框架。
分成兩部分,一個是鏈的部分另一個是Replayer 的部分。 Substrate 鏈的部分包括Substrate-IBC Pallet 的開發,IBC-RS 中的ICS10 Beefy 輕客戶端/ICS20 Fungible Token Transfer 的開發,Substrate-IBC Pallet和IBC-RS 的集成; Replayer 的部分包括Relayer 對Substrate 的支持,Octopusxt 的開發。
我們已經在Interchain 的Grant 之前兩個里程碑實現了IBC/CORE 核心標準(ICS02-Client, ICS03-Connection, ICS04-Channel&Packet, ICS05-Port, ICS26-Router)。在此基礎上,建立了IBC 中最重要的應用ICS20 Fungible Token Transfer。更多的IBC 應用未來將在Substrate-IBC 模塊中實現。 Substrate-IBC 模塊是Substrate 的一個模塊化組件,它提供了IBC 相關的能力,包括創建客戶端、連接、通道等。 Substrate 應用程序開發人員可以導入這個模塊,只需很小的配置,就可以實現IBC 通信。
之後我們看下Substate-IBC 和IBC-RS 之間的調用關係。
由於IBC 的鏈上數據只能由IBC Pallet讀寫,而不是IBC-RS , 所以IBC-RS 最終要調用Substate-IBC 模塊實現連上數據的讀寫。這里以Update Client 這個請求為例。
1、Relayer 通過調用Substate-IBC 的Deliver 方法,提交了Update Client 這個請求。
2、這個請求被傳遞給了IBC-RS 的ICS-26 Router 路由模塊。
3、路由模塊把請求傳給了ICS20 Client 中的Update Client 的處理邏輯,處理的過程中會調用Substrate-IBC Pallet 中的Clientreader, 讀取相應的Client 的狀態。
IBC 的原理和Substrate-IBC 的項目的結構講解完了,我們看下在Substrate 的一個模版中需要配置Substrate-IBC Pallet 信息。主要包括Runtime 的的配置,Node 中的配置兩個部分。
Substrate-IBC 同其他Substrate Pallet 一樣也是一個運行時邏輯處理模塊,在使用一個Pallet 模塊時需要在Runtime 中配置實例和配置的Pallet 模塊。
這裡我們就在Runtime 中配置Substate-IBC 需要用到的關聯類型的配置還有Substrate-IBC 的在Runtime 中的實例化配置。
Node 中配置的信息是由我們設定這個鏈代幣名稱的配置,跨鏈資產的配置
配置完了,我們看下最終通過Substrate-IBC 實現跨鏈轉賬的步驟。主要有8個步驟:
1、啟動兩條Substrate 鏈Appchain0, Appchain1
2、為已啟動兩條鏈Appchain0, Appchain1 創建通道
3、啟動Relayer 中繼IBC消息
4、在Appchain0, Appchain1 上分別創建跨鏈資產
5、分別在Polkadot.js 上導入兩個賬戶
6、向Appchain0 鏈的David 賬戶轉入原生Token ,以便讓David 賬戶隨後有餘額進行跨鏈轉帳
7、從Appchain0 鏈的David 向Appchain1 鏈的Davidrain 跨鏈轉帳
8、從Appchain1鏈的Davidrain 向Appchain0 鏈的David 跨鏈轉帳
這裡我們使用的是章魚網絡的提供的Substate-Node-Template 定制化的Substarte 模版創建兩條鏈,這個定制化的模版使得應用鏈開發團隊很容易地加入章魚網絡生態。
之後我們需要在兩個鏈之間建立起通道。這個創建Channel命令會自動檢測下層的Client,Connection是否已經創建。
這裡直接通過創建Channel 逐步先創建出Client,Connection,Channel。
因為下層的Client, Connection 都還沒有創建,所以Hermes 會先創建Client,創建Client 不需要握手,我們從日誌可以看出Client 比較快的創建好了。
現在創建Connection, 創建Connection 需要握手,握手過程中有四個事務:connectionOpenInit,connectionOpenTry,connectionOpenAck,connectionOpenConfirm. 這四個事務日誌中會順序展示。
Connection創建完成後,開始創建Channel。創建Channel 也需要握手,握手過程中有四個事務:channelOpenInit,channelOpenTry, channelOpenAck, channelOpenConfirm. 這四個事務日誌中會順序展示。
最終整個通道就會創建完成。
通道創建完成之後,在啟動Relayer 中繼服務。
在Appchain0, Appchain1 鏈上分別創建跨鏈資產。
通過管理員(sudo)賬戶調用OctopusAssets 中的Frocecreate 創建資產,這裡的跨鏈資產都是1號資產,我們在前面配置的Substarte-IBC 的時候給到的跨鏈資產的資產Id 都是1。
向Appchain0 鏈的David 賬戶轉入一定量的Token。
通過Balance 模塊的transfer 函數我們從Alice賬戶轉移500000000000000000000000 Naive Token 給David 賬戶。
從Appchain0 鏈的David 向Appchain1 的Davirain 跨鏈轉賬。
在這裡,我們可以看到在通道通過中繼器和IBC-RS 被啟動後,兩個底層鏈之間使用IBC 來傳輸可Token 的流程邏輯。
一個用戶通過Hermes 命令tx raw ft-transfer 向AppcChain0提交一個交易。
Appchain0 中的IBC 模塊發出一個SendPacket 事件。中繼器檢測到Appchain0 發送出來的SendPacket 事件,然後向Appchain1 提交一個RecvPacket 事務。
Appchain1 處理來自Relayer 的RecvPacket 交易請求,並發出一個[WriteAcknowledgement] 事件。中繼器檢測到Appchain1 發出的事件WriteAcknowledgement,然後向Appchain0 提交一個確認AcknowledgePacket。
Appchain0 中的IBC 模塊處理來自Relayer 的AcknowledgePacket,然後發出一個事件Acknowledge Event。
從Appchain1 鏈的Davirian 向Appchain0 鏈的David 跨鏈轉賬。
我們來看IBC/APP 同質化代幣跨鏈轉賬示意圖。
一個用戶通過Hermes 命令tx raw ft-transfer 向AppcChain1 提交一個交易。
Appchain1 中的IBC 模塊發出一個SendPacket 事件。中繼器檢測到Appchain1 發送出來的SendPacket 事件,然後向Appchain0 提交一個RecvPacket 事務。
Appchain0 處理來自Relayer 的RecvPacket 交易請求,並發出一個[WriteAcknowledgement]事件。中繼器檢測到Appchain0 發出的事件WriteAcknowledgement,然後向Appchain1 提交一個確認AcknowledgePacket。
Appchain1 中的IBC 模塊處理來自Relayer 的AcknowledgePacket,然後發出一個事件Acknowledge Event。
那麼,關於IBC 協議的介紹和啟動一條帶有IBC 模塊的Appchain 就講解完了。
最後這裡給出一些關於IBC 的資源還有一些聯繫方式:
Substrate-IBC:https://github.com/octopus-network/substrate-ibc
IBC-RC:https://github.com/informalsystems/ibc-rs
IBC Spec:https://github.com/cosmos/ibc
IBC Spec-zh:https://github.com/octopus-network/ibc/tree/zh-cn-2022/translation/zh-CN
IBC Paper:https://github.com/cosmos/ibc/raw/old/papers/2020-05/build/paper.pdf