原文標題:《一文詳解跨鏈的技術點及難點:從完美跨鏈談起》
原文來源:機械鐘
原文采訪與撰文:李畫
受訪者:劉毅,Cdot 創始人

關於跨鏈需要知道的第一件事情是,我們永遠沒有辦法把一條鏈上的資產真正的轉移到另一條鏈上,以比特幣爲例,2100 萬枚比特幣,全部都會且只會呆在某個確定的比特幣地址中,而不會去其他任何地方。
以比特幣和以太坊之間的跨鏈爲例,它需要你把比特幣轉入某個地址,鎖定這部分比特幣,然後在以太坊上發行比特幣替代品,並轉入你在以太坊上的地址;贖回的時候,需要你調用智能合約銷燬比特幣替代品,然後在比特幣網絡上把鎖定的比特幣釋放給你。
不難發現,這其中唯一的難點就在於消息的互通。
也就是說,當你在比特幣網絡把比特幣鎖定後,只要以太坊能知道這件事,就可以在以太坊上鑄幣給你;當你在以太坊把替代品銷燬後,只要比特幣網絡能知道這件事,就可以在比特幣網絡上釋放幣給你。
那麼消息的互通難在哪裏?我採訪了 Cdot 的創始人劉毅,劉毅認爲多鏈是一種更具生命力的系統,因此他和他的團隊致力於鏈與鏈之間的聯通。Cdot 已經爲以太坊和 Flow 建立了跨鏈橋,也正在進行 Cosmos 與 Polkadot、Cosmos 與以太坊的跨鏈研發。
問:先問一個「大」問題,你是如何看待跨鏈的重要性的?
劉毅:公鏈技術發展面臨的主要問題是如何突破性能和成本瓶頸,同時不過度犧牲鏈上應用的可組合性。目前看有三個解決方案:分片、Layer 2、多鏈(跨鏈)。Polkadot、Cosmos、Ava,還有包括 Cdot 在內的衆多團隊,做得就是多鏈這個方向。
也就是說,如果可以用 Substrate /Cosmos SDK 爲每個加密協議開發出專用的鏈,又可以通過跨鏈,讓這個加密協議可以跟其他加密協議互操作,那麼公鏈的性能和成本問題就可以得到解決。
問:迴歸今天的技術主題,跨鏈時兩條鏈消息的互通難在哪裏?
劉毅:可以從 Vitalik 在 2016 年寫的一篇叫《Chain Interoperability》的文章談起,他把跨鏈技術分成了三類,哈希時間鎖、見證人、中繼,我覺得基本上可以沿用。
那它倆的區別是什麼?當我在目標鏈上收到一個消息後,如果是見證人跨鏈,我驗證的是這條消息來自於見證人,如果我相信見證人,我就相信這個消息,就執行該執行的操作。
如果是中繼跨鏈,我驗證的不是這條消息來自於哪個中繼,我驗證的是這條消息是不是來自於源鏈,如果是,就執行該執行的操作。
也就是說,見證人可以看做是需要被信任的中繼,中繼可以看做是無需被信任的見證人。這就是兩者的核心區別,中繼顯然比見證人更符合 trustless 的原則。
中繼是無法做惡的,如果一箇中繼提交的信息不是來自於源鏈,目標鏈驗證之後會把它識別出來。但是見證人是可以做惡的,它可以造出一個消息發給目標鏈,目標鏈驗證它是來自於自己相信的見證人後,就會執行這個操作。
這樣看來,似乎大家都應該用中繼去做跨鏈產品,但爲什麼還存在見證人方式?因爲中繼跨鏈的要求比較高。
它的要求到底是什麼?假設咱們是兩條鏈,你上面發生了一個事件,由一箇中繼發給了我,我要驗證這個信息來自於你這條鏈,對吧?
怎麼驗證呢?我的鏈上需要有你的鏈的輕客戶端。可以粗略地理解爲類似於比特幣 SPV 的機制,但發生在鏈上,而不是在手機錢包裏,即你的所有區塊頭我這兒都要有。
這個時候,當一條消息過來,中繼不但要把消息給我,還要把消息的證明給我,這個證明是一個 Merkle Proof,它告訴我這個事件或這筆交易是發生在你這條鏈上的哪個區塊(高度)。
我拿到 Merkle Proof 後,因爲有你所有的區塊頭,就可以把對應高度的區塊頭拿出來,用 Merkle Proof 驗證這個交易或者這個事件是否存在。如果存在性得到證明,我就確定了這個消息確實是源自於你這條鏈的。
然後,當我這條鏈生成一個事件或者發生一筆交易後,中繼也發給你,你也有我全部的區塊頭,也可以驗證這個消息是否來自於我。這是一個完美的跨鏈,對吧?
可爲什麼大家不去實現完美的中繼跨鏈呢?因爲有些鏈是沒有辦法實現別的鏈的輕客戶端的。比如比特幣,它上面實現不了任何一個鏈的輕客戶端。
以太坊上能不能實現別的鏈的輕客戶端呢?要看實現的難度。以太坊需要用智能合約實現輕客戶端,但智能合約是有 gas 限制的,所以輕客戶端驗證的計算量是要能夠容納到 Gas Limit 以內的。
問:可不可以這麼認爲,如果一個鏈不具備實現另外一個鏈的輕客戶端的條件,它就永遠無法以中繼的方式與另一個鏈跨鏈?
劉毅:它就只能用見證人的方式跨鏈,但可以混合,一個方向上用見證人,另外一個方向上用中繼。
比如我開發一條鏈,比特幣肯定實現不了我的輕客戶端,但我可以實現比特幣的輕客戶端,那麼比特幣到我這個方向能夠用中繼,我到比特幣這個方向就只能用見證人。

問:以太坊的情況如何?比如要實現以太坊與 Cosmos 的中繼跨鏈。
劉毅:以太坊是一個複雜的問題,它有條件實現一些輕客戶端,但就像上邊說的,最主要的限制是 Gas Limit。
比如一個 Tendermint(Cosmos 採用的共識協議)的鏈,中繼跨鏈需要驗證它的區塊頭,它的區塊頭是所有驗證者的簽名,這些簽名用的是 BLS 簽名算法,驗證區塊頭就要驗證這些 BLS 簽名,但是,以太坊上沒有預編譯 BLS 簽名。
智能合約可以直接調用預編譯加密算法,比如調 ECRecover 方法,用它驗證 ECDSA 簽名只需要 3000 gas,還是比較低的;但驗證沒有預編譯的 BLS 簽名,就得把整個的簽名驗證算法 Solidity 實現,不是底層支持的,這個太貴了。
驗證一個 BLS 簽名,最優好像是二十幾萬 gas,如果 Tendermint 上有 100 個驗證人,那每個區塊可能就有 100 個簽名,驗證 100 個 BLS 簽名,gas 肯定會超,不可能做到。
不過今年 Vitalik 寫的路線圖上,以太坊 1.x 會增加 BLS 簽名預編譯合約,相當於在客戶端底層實現 BLS 驗證,那麼一個函數調用就可以驗證簽名。
假設和 ECDSA 一樣,也是 3000 gas,那驗證 100 個 BLS 簽名是三十萬 gas,這就有可能在智能合約裏實現。
有了 BLS 預編譯後,理論上就可以在以太坊上實現 Tendermint 的輕客戶端,那麼以太坊和 Cosmos 就可以實現雙向的中繼跨越。所以說和 Cosmos 中繼跨鏈的話,比特幣肯定不行,以太坊是現在不行,未來可能行。
問:即便都是採用 Cosmos 的 IBC 標準開發的鏈,也不是天然就能跨鏈?
劉毅:對,兩條鏈即使都實現了 IBC,要中繼跨鏈的話還要實現對方鏈的輕客戶端。
問:輕客戶端用於跨鏈消息的驗證,但跨鏈消息本身是怎樣在兩條鏈間傳遞的?
劉毅:跨鏈橋很形象,它有兩個橋墩和一個橋樑。兩個橋墩就是兩套智能合約(有些鏈可能叫模塊),一個運行在 A 鏈,一個運行在 B 鏈;中間是橋樑,橋樑是鏈下進程,負責監控兩邊這兩套智能合約的事件。
問:比如我在以太坊上把一隻加密貓鎖進了智能合約,鏈下進程監聽到這個事件很容易,但它怎麼告訴 Flow 上的智能合約我鎖了一隻貓?
劉毅:鏈下進程就是給 Flow 發一筆交易,說以太坊這邊鎖了一隻貓,你那邊要鑄造出一隻貓。它是一個程序,通過 RPC(遠程過程調用)接口,一邊連以太坊的節點,另一邊連 Flow 的節點。
問:能完整描述一個具體的跨鏈過程嗎?
劉毅:假設現在有一個 ERC20 的代幣,比如說是 UNI,它發行在以太坊上,我們想把它跨到 PlatON 上面去。
那麼以太坊這邊要有一個智能合約,比如叫 Vault 合約,它是跨鏈橋的一個橋墩;跨鏈的用戶要做兩筆交易,第一筆交易是調用 UNI 合約的 Approve 方法,允許 Vault 合約轉走多少用戶的 UNI。
第二筆交易是發給 Vault 合約的 Lock 方法,把要鎖定的幣種(本例是 UNI)和數量(比如 500 個)作爲參數傳進去,然後還要提供一個 PlatON 的地址,說我鎖 500 個是爲了在這個地址上鑄造出 500 個 UNI 的替代品。
這個時候,Vault 合約就會去調用 UNI 合約做 UNI 的轉移,因爲 Vault 合約已經被 Approve 了,就可以把 UNI 從用戶地址轉到Vault 合約的地址上,也就是把 UNI 鎖住。
鎖完之後,Vault 合約就會發一個事件,比如叫 AssetLock 事件;鏈下進程是通過 RPC 接口連在以太坊節點上的,它會訂閱 Vault 合約的 AssetLock 事件,這個事件只要一出現在日誌裏,鏈下進程就得到這個事件了。
這個事件裏包含相關參數,比如鎖定的是哪個幣,鎖了多少,另一條鏈上的受益人是誰;鏈下進程會等待比如說 100 個塊的確認,不可逆轉;然後,鏈下進程也有一個連接 PlatON 的 RPC 接口,它會提交一筆交易到 PlatON,假設這筆交易叫 Mint。
PlatON 上也會有一個合約,比如叫 Control 合約,它是跨鏈橋的另一個橋墩;Control 合約事先會創建一個類似 ERC20 的合約,比如叫 EUNI,Control 合約是這個合約的 owner,也就是說它有權力控制 EUNI 合約的代幣供應。
Control 合約收到 Mint 請求後,驗證這個請求確實來自於見證人,就會調用 EUNI 合約的 Mint 方法,告訴它給某個地址鑄造 500 個 EUNI 代幣;EUNI 鑄造出來後,就會放在用戶之前提供的地址上,用戶就可以用了。
這個時候,假設用戶把 EUNI 轉給了另外一個用戶,新用戶想要以太坊上的 UNI,那他要做的操作是先 Approve,然後調用 Control 合約的 Redeem 方法,燒掉比如說 100 個 EUNI,並釋放一個事件叫 AssetBurn。
鏈下進程監控到 Control 合約的 AssetBurn 事件,就會給以太坊 Vault 合約發一個交易請求,調用 Release 接口,以太坊驗證這個交易是來自於見證人後,就會把 UNI 從 Vault 合約的地址上轉移到指定的用戶地址上,用戶就得到了原始的 UNI。這就是一個完整的跨鏈過程。
問:可以拋開「鏈下進程」這個角色實現跨鏈嗎?比如一條鏈直接去監聽另一條鏈,然後完成相關的跨鏈操作?
劉毅:這是做不到的,因爲鏈都不能主動發起操作,鏈的邏輯都是被動的。
唯一的例外是 Substrate(Polkadot 開發框架),它上邊有 off-chain worker 這個機制,可以用一個鏈下工作機發起請求。其他的,比如以太坊智能合約,是不能自己主動發起幹什麼事的,它只有被調用。
問:可不可以這麼理解,不管是中繼跨鏈還是見證人跨鏈,都需要鏈下進程來傳遞消息,所不同的是,中繼跨鏈通過輕客戶端驗證消息,見證人跨鏈信任見證人提供的消息?
劉毅:這樣理解基本上沒有問題。中繼跨鏈依賴鏈下進程的可用性,但不依賴它的忠誠。
問:似乎通過鏈下進程傳遞消息不難,難的是驗證消息或者信任消息?
劉毅:對,因爲兩條鏈都有 RPC 接口,而且都有 SDK(軟件開發工具包),是能夠訪問的,所以不難。
而且特定目的的跨鏈,不需要定義一個可擴展的協議,只要自己夠用就好:定義是什麼事件,抽取什麼參數,提交什麼參數給誰,就行了。
問:驗證消息是技術問題,要麼能驗證要麼不能驗證,但信任消息的話,似乎就有不同的模型,反映在見證人跨鏈上就是它可以有不同的實現方式,需要信任的消息可以來自中心化的見證人,也可以來自去中心化的見證人?
劉毅:其實就是一個安全性問題。而安全是一個沒有極限的東西,也沒有絕對,安全通常是一個漸進的過程。
比如一開始,沒什麼資產時,可以用單見證人,連 KMS(密鑰管理服務)都不用;有了資產後就要用 KMS;資產多了,需要多個見證人,爲了省 gas,就要做鏈下簽名聚合;資產更多了,就要用到 MPC(安全多方計算)。
然後再多資產,就要對參與 MPC 的多方進行隨機分組調度,例如 RenVM。這樣就跟做一條公鏈的難度和實踐都差不多,但它也就實現了去中心化的見證人。
問:可以更具體地描述一下嗎?
劉毅:比如一邊是以太坊,一邊是 Flow,我們可以開發一個見證人的節點,把兩邊連起來。
但這一個見證人的安全性和可用性是比較低的,如果黑客攻破了見證人的服務器,拿到見證人的私鑰,就能夠把所有鎖在以太坊上面的 ETH 或者 ERC20 偷走。
還有一個風險就是可用性,如果見證人服務器宕機了,那在一條鏈上鎖定資產後,另一條鏈上是鑄造不出來的,因爲消息傳不過去。
如果承載的跨鏈資產不多,一個見證人是可以接受的,也有一些方法解決單見證人的安全問題和宕機問題。但如果想進一步提高,怎麼做?可以包含 3 個見證人。
假設一邊是比特幣,一邊是以太坊,比特幣網絡上有一個 2/3 的多籤錢包,用戶發交易把比特幣鎖進去,3 個見證人看到後,就給以太坊發消息,以太坊確認消息來自於見證人後,就在以太坊上鑄造代幣。
兌回的時候,用戶在以太坊發交易要求贖回比特幣,3 個見證人看到後,就去比特幣網絡發多籤:一個見證人發一筆交易,說要釋放,另一個見證人也發一筆交易,說要釋放,2/3 錢包看到夠兩個簽名了,就釋放比特幣給用戶。
2/3 比一個見證人要好一點,但 3 個私鑰持有人中只要有 2 人串通,就能把比特幣全部拿走,所以其去中心化程度是不夠的。
那麼更好的方案是 MPC/TSS(安全多方計算/門限簽名)支持下的見證人鏈。剛纔說見證人需要被信任,但如果把見證人做成一條鏈,它是不是也可以實現 trustless?
信任集合擴大了,除了要信任源鏈、目標鏈,中間還有一個見證人,但這個見證人不是中心化的,它是一條鏈,有自己的經濟安全性,只要相信見證人鏈的驗證者(validator)集合整體不會作惡,那整個過程還是 trustless 的。
見證人鏈可以把衆多的見證人節點隨機分組,每個組都會比如說有一個比特幣地址,一段時間之後再把這些節點重新分組,這樣的話,節點如果想串通起來偷走比特幣是不太容易的。
這其中門限簽名的作用是,比如一個分組裏有 21 個節點,每個節點拿一片私鑰,如果設置爲 15/21,那這 21 個節點裏需要有 15 個節點簽名,然後形成一個 ECDSA 的簽名,再通過一筆交易把錢包解鎖。
顯然這種方式的安全性更高,也更可靠(可以容忍 6 個節點不在線,或者故意不參與簽名),而且更經濟,因爲解鎖比特幣只需要發一次交易。
在聚合門限簽名的過程中,需要用到 MPC,因爲不能把節點的私鑰放到一起去簽名,需要大家分別做計算。所以是門限簽名加 MPC 的一個機制,這樣能夠形成一個見證人鏈。
問:MPC/TSS 通常被用於比特幣與以太坊之間的跨鏈,可不可以把它方便地移植到另外兩條鏈之間做跨鏈?
劉毅:可以,但不一定很容易。它的門限簽名和 MPC 是針對 ECDSA 簽名的,這套機制在 ECDSA 的鏈之間做資產跨鏈是容易的。如果它的門限簽名和 MPC 支持其他簽名算法,這套機制則是可以擴展到其他鏈的。

問:我們對中繼跨鏈和見證人跨鏈有了一定的瞭解,那麼哈希時間鎖是怎樣的一種跨鏈機制?
劉毅:我給哈希時間鎖這種方式起了一個新的名字,叫外部協調。
外部協調是指在跨鏈的全過程中,兩條鏈是互不知道對方的,A 鏈不知道 B 鏈上發生了什麼,B 鏈不知道 A 鏈上發生了什麼(注:在中繼跨鏈和見證人跨鏈中,兩條鏈是互相知道的)。
比如哈希時間鎖,我們是先在 A 上面做一個交易,拿到哈希之後,再把這個哈希提交給 B,這是兩個用戶錢包在做協調的跨鏈,兩條鏈本身是不知道對方鏈的。
爲什麼要把哈希時間鎖擴展成叫外部協調呢?因爲除了哈希時間鎖外,還有大量的非哈希時間鎖的外部協調式跨鏈。
這其中最大的一個應用就是中心化的交易所,我把比特幣存進去,換成以太坊提出來,這就是一個 web 應用做協調的跨鏈。
外部協調的跨鏈在聯盟鏈領域用得也非常多,聯盟鏈廠商,例如 Hyperledger Cactus,就是專門做外部協調的中間件,它能夠跨兩個鏈。用戶把一個交易提交到中間件上,中間件就知道先在 A 鏈上邊做一個操作,再在 B 鏈上做一個操作,A 鏈和 B 鏈相互之間是不知情的。
所以不管是由錢包做協調,還是由應用做協調,還是由中間件做協調,這一類跨鏈的特點就是兩個鏈實際上是互不知情的,是有外部實體在做協調。
爲什麼我們在公鏈或者加密協議領域很少提外部協調?因爲 web 應用或者中間件一定是由中心化實體運行的,不可能做到去中心化。
但錢包做外部實體協調的跨鏈可以認爲是 trustless 的,因爲用戶和錢包是合體的,我們做任何操作都必須信任錢包,也就是說它沒有擴大信任集合。這就是爲什麼把哈希時間鎖當成一種 trustless 的跨鏈。
但哈希時間鎖一個是功能受限,它能做的就是資產的互換,另外它也有業務上的問題。跨鏈的 atomic swap 在 2015 年就實現了,到現在 5 年時間過去了,沒有形成什麼業務。
讓我們以一個小小的總結結束這篇文章吧。似乎可以把現今流行的跨鏈方法分爲三大類:
第一類:中心化的跨鏈(類外部協調)。它是由一箇中心化的第三方在一條鏈上抵押資產,在另一條鏈上發行資產,資產的跨鏈實際上是在該第三方抵押和發行資產時發生,在此過程中,兩條鏈之間並未互通消息。
用戶在進行跨鏈操作時,並不是一個鎖幣、鑄幣的過程,而是更接近於把 A 鏈上的資產兌換爲 B 鏈上的、由第三方發行的另一種資產。
中心化的跨鏈實現起來最爲簡單,但它依賴於一個較強的中心化的信任;此類跨鏈項目包括交易所提供的跨鏈資產等等。
第二類:見證人跨鏈。通過鏈下進程傳遞消息,在一條鏈上鎖定或解鎖資產,在另一條鏈上鑄造或銷燬資產;兩條鏈都需要相信見證人傳遞的消息爲真。
見證人可以是一個或多個見證人節點,也可以是一條見證人節點組成的鏈,後者雖然需要相信見證人,但可以認爲它是去中心化的,因爲它不需要信任某個或某些中心化的第三方。
見證人跨鏈實現起來可以簡單,也可以複雜,取決於見證人的構成;此類跨鏈項目包括 RenVM、tBTC 等等。
第三類:中繼跨鏈。通過鏈下進程傳遞消息,在一條鏈上鎖定或解鎖資產,在另一條鏈上鑄造或銷燬資產;兩條鏈上有對方鏈的輕客戶端,通過輕客戶端驗證鏈下進程傳遞的消息是否爲真。
中繼跨鏈是無需信任的理想跨鏈方式,但由於其實現難度,目前還難以見到;在 Cosmos 的 IBC 跨鏈 1.0 上線之後,可以在兩條 Cosmos 鏈之間實現中繼跨鏈。
Cdot 也正在 ICF 基金會(Cosmos 生態基金)的資助下開發 Substrate IBC,通過它能夠使 Substrate 開發的應用鏈和支持 IBC 的鏈實現中繼跨鏈,Substrate IBC 希望成爲多鏈世界的重要基礎組件。
原文鏈接
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia