作者:0xKooKoo,极客Web3 & Moledao技术顾问, 前Bybit技术负责人

感谢0xmiddle在本文撰写过程中提供的帮助。

Introduction

自区块链行业建立以来,涌现出数不胜数的L1/L2,几乎每条公链都发展出了自己的DeFi生态。某些人只在特定公链上交互,更多人则希望在不同链上寻找交易、挖矿等收益机遇。在这之中,跨链资金转移成为了必不可少的刚需。


除了普通用户,很多项目方也有在不同链间转移资金的需求,在不同链上引导流动性,做到“一钱多用”。


但不同的区块链是孤立的共识系统,资金没有办法从一条链直接跨到另一条链。资金跨链的本质,是跨链桥作为一个公共的交易对手方,在源链上接收用户资金,并在目标链上给用户打钱(发行映射资产,或从目标链储备的流动性池中为用户释放资金)。

到底怎么实现资金跨链才最好?最开始人们还比较信任中心化交易所,曾一度流传一句话:“中心化交易所就是最好的跨链桥。”但「充-换-提」的操作很繁琐,人们希望有一种纯链上方式,更直接的完成资金跨链。

而且,相比于中心化交易所,跨链桥可以完成更通用的跨链消息传递,不仅限于资金传递。例如,你如果使用一个跨链借贷dApp,从A链上提供抵押品,在B链上借出资产,就需要用到跨链消息传递。

如果考察跨链的历史来源,可以追溯到区块链技术发展的早期阶段。当时,不同公链的出现让人们意识到,链之间的互通性问题要被解决,否则会出现很多信息/资金孤岛。随着时间推移,人们提出了不同类型的跨链方法,逐渐形成了今天的通用跨链模式。

下面我们就来讲解一下跨链技术的一些发展。

Methodology

1. 自己寻找对手方
我们来想想,最符合直觉的跨链方法是什么?假如你在A链有100个USDT,你希望把它们转移到B链上。恰好有一个人在B链有100个USDT,他希望把USDT转移到A链去。你们俩一看这不刚好吗,于是一拍即合。
但当你把USDT在A链上转到对方的地址时,他却反悔了,没有在B链上将他的USDT转到你在B链的地址上。
因此,这种P2P交易的模式不是很靠谱,一来对方可能毁约,让你遭受损失,没有任何保障;二来,这个交易对手也不好找,你可能要等很久,才能碰到一个刚好和你要跨出去的金额匹配,但跨链方向相反的用户,甚至可能等到天长地久也等不到这样的对手方。

2. 公证人机制(Notary Schemes)

2.1 单个公证人


于是我们想到,既然对方可能违约,那我能不能找一个可信的第三方进行交易?我在源链上先把钱给他,然后他保证在目标链上把钱转给我。比如说,这个人同时在A链和B链上都有资产,然后他担保说,只要在A链收到我的100个USDT,就一定会从B链转给我100个USDT。


这比第一种P2P的链间资产交换好很多,因为有一个可信的公共对手方了,他手里掌握了一种神奇的东西,叫做「流动性」,你可以随时与它交易。


也就是说,你和他的交易变成了一种“点对池”的交易,而非“点对点”的交易。但你还是觉得不踏实,如果你和他交易100 USDT还好,倘若你要和他交易100万USDT呢?尽管他有比较好的信誉,但还卷款跑路。


说到底,这个公证人其实又是引入了一种中心化,依旧不是我们想要的Trustless 的跨链方式。


2.2 多个公证人(MultiSig)


那如果这个公证人不是一个人,而是一群人呢?我们可以建立一个共管账户,多个签名人共同管理该账户,他们要对一个消息进行签名,签名数达到阈值(一般是2/3),资金才会被转移。


这种情况下,如果其中少数人(不超过1/3)动了歪心思,想在源链上收我的款,又不想在目标链上给我打钱,或者离线了,也没有关系,其他诚实的公证人还是会签名,并把应给我的钱转出去。

这种方案比较靠谱了,弱化了中心化风险,安全性更高一些。比如一共有20个信誉良好的公证人,他们同时动歪心思的概率还是很低的。(这里不包括 Multichain那种20个节点实际上是一个人管理的情况,或是像Axie跨链桥那样被黑客盗取了2/3公证人的签名密钥。)

2.3 多个公证人(MPC)


但多签的账户管理方式,也有很多不方便的地方。


多签使得签名规则更容易暴露。如果是5/7的签名方案,多签钱包的智能合约代码会暴露到底有多少个签名方,黑客可以有的放矢的寻找这些签名方,伺机盗取私钥。


多签需要对不同的公链进行适配。比如有的公链不支持智能合约,你就得用该链特制化的密码学原语实现多签账户,如果这个也不支持,你这个多签钱包就搞不了。


多签的签名人定了就不能改。比如5/7的签名方案,你如果想改成6/8的方案,或者你想更换签名人,就得重新部署多签合约,而且还要把资金转移到新的多签合约中。


首个BTC衍生品tBTC的跨链方案,就是用了多签的方式,因为很蹩脚难用,已经被淘汰了。当前的跨链桥,大多采用了更先进的MPC的方式。

MPC全称Multi-Party-Computation(多方安全计算),是一种私钥分片技术。多签账户是多个私钥管理一个账户,而MPC账户则是一个私钥管理一个账户,该私钥被切分为多个碎片,多个签名人各持有一个私钥碎片,当签名人数达到阈值时才可以合成完整的签名,签名过程不会暴露完整私钥。
MPC账户有以下优势:
比普通多签钱包的保密性更强。当需要签名的时候,由例如5/7个私钥碎片各自去签名,多个子签名融合到一块构成最终的一个合法签名。这样一来,链上看到的是一个单一的、普通的签名,你无法分辨它是否来自MPC账户,更无法知道背后的签名人是谁,也无法知道私钥碎片的数量和具体的签名规则。
可以比多签钱包更好的适配大多数公链。MPC是一种签名技术,与链无关。MPC账户其实就是一个普通账户,不管一条公链是否支持智能合约,都可以通过MPC技术构建共管账户。
MPC更换签名机制更灵活。可以支持更灵活的签名规则调整,比如随时改变私钥碎片数量、签名阈值,也可以随时更换签名人,只需要把私钥进行重新分片(Re-share)即可。
3. 进一步的安全措施

3.1 冷热分离


公证人的托管账户收到了A链上我的100个USDT后,给我在B链的地址转过去100个USDT,这个行为的触发流程该怎么做?


假设说每个公证人成员都有一台机器在监听A链上的transaction,当他们发现我给跨链桥托管账户转了100个USDT,且这笔transaction里面声明了,我希望在链B上名为user2的地址接收这些USDT。


此时公证人集体进行联合签名,将B链上跨链桥账户中的100个USDT转给user2。这个过程肯定要写成代码,自动化运行,否则公证人都得实时在线,收到请求还得立刻操作,太不现实了。


这个自动化程序里会包含几个部分


1、监听程序:负责监听源链上的交易,为了过滤无关交易或无效交易,这一步可能会做一些基本的格式验证;


2、校验程序:这里会包含所支持区块链的轻节点客户端(也可能是全节点),负责验证源链上某笔与跨链桥合约产生交互关系的交易,真的被打包进区块并上链了;


3、签名程序:负责签名发起目标链上向用户的转账交易。

但自动化也带来一个问题,就是这个自动化程序有可能被黑客攻击和操纵。因此为了控制风险,跨链桥会采取冷热分离的措施。自动化程序控制的是热秘钥,转账的金额受到限制,遇到大额转账,则必须让公证人用冷秘钥进行手动签名。冷热分离的规则可以在MPC账户中实现。

3.2 风险隔离


如果真的有bug,不要一次事故全部一锅端吧?因此要做好资金池的隔离,用多个托管账户来管理流动性资金,比如按照不同公链之间做隔离,例如A和B,B和C,C和D全都是独立开来的资金池。


3.3 TEE


公证人所运行的自动化监听和签名程序,可以运行在TEE设备中,这样可以大幅度提高黑客攻击的难度。TEE全称为可信执行环境(Trusted Execute Environment ),是给定设备上运行的与主操作系统隔离的计算环境,就像一块飞地(Encalve)。


这种隔离是通过硬件强制实现的,具有极高的安全性,因此TEE可以运行具有高安全性要求的应用程序,例如加密密钥管理、生物特征认证、安全支付处理等。

3.4 PoA向左,PoS向右


为了让跨链桥更加安全,在公证人的选择方面有两个方向:


一种是尽可能选择信誉良好的大公司、知名机构。对于这些机构而言,作恶的成本极高,可能会损失掉积累多年的商誉。此外,要尽可能让他们在地理分布上足够多元化(避免集中在同一司法辖区)。


比如跨链桥项目Wormhole就选择了这样的模式,它的19个节点背后都是体量庞大、资金雄厚的知名大机构,这就是PoA的方式。


另一种方式则是Permissionless的公证人准入,但要求他们做质押,如果行为不端,他们质押的资金就会被slash。这就是PoS的方式。ZetaChain用的便是这种。

两种方式谁优谁劣,不好直接武断的给结论。取决于跨链桥项目方在各自的方向上做的怎么样。


无论是PoA还是PoS,你可以把跨链桥直接做成一条公链,每个节点跑着相同的程序,所有跨链请求和处理的过程都会被记录到这条链上。这条链本身也可以承载应用,从而成为一个生态枢纽。


3.5 观察者


还有一种增强安全性的方法是,设置一个观察者的角色。该角色负责监控跨链行为,如果发现问题,可以在链上报告并中止交易。由于观察者需要一个窗口期来做出反应,因此跨链转移的到账时间可能被延迟,所以,只有大额交易或敏感跨链操作,用户接受转账延迟的情况下,观察者才会介入。


其他跨链方案
哈希锁定
回到本文所说的第一种方法:P2P的寻找跨链资产交换的对手方。如果我们害怕对手方赖账,那可以设置一套机制,一旦谁反悔了,另一方可以把钱拿回来,完璧归赵。
这就是哈希锁定,它巧妙地利用了哈希锁和时间锁,迫使资金的接收方必须在 deadline之前确定收款,并且产生源链上的收款证明,而打款方凭借这个收款证明,一定可以获取接收人在目标链上的等价资产,否则双方的资金都将原路返还。
但是这种方式只能进行资金的交换,无法完成通用的跨链信息转移。而且哪怕单从资金跨链转移的角度讲,哈希时间锁的用户体验也很不好:
如果币价的波动对交易对手(流动性提供方)不利,他可能理性地选择不成交;
为了完成一笔跨链交换,用户和交易对手都必须操作两次签名。
因此,哈希时间锁作为一种跨链解决方案,基本已被淘汰。早期使用这种方案的跨链桥(例如cBridge、Connext)都已经改弦更张了。
链上轻客户端
这种方式是直接在目标链上部署源链的轻客户端合约。如果你在一条链上部署了合约,那么这条链的所有节点都会运行你部署的合约代码。所以,链上轻客户端的方案,实际上是让目标链直接验证来自源链的交易。
这种方式具有极高的安全性,但也是最昂贵的。昂贵体现在以下几个方面:
目标链的轻客户端合约需要实时接收和验证来自源链的新区块头,这个过程非常耗Gas,即便用ZK来实现简洁证明,验证一个ZK证明的Gas消耗也不会低于40万Gas(EVM为例),而在MPC方案中,链上仅需验证的就是一个签名而已,Gas消耗只有2万出头,差了20倍!一个更安全,但是贵20倍的桥,你会用吗?
开发轻客户端合约的工程量巨大,而且为了让跨链桥兼容更多的异构链,你需要在不同链的完全不同的开发环境中,实现其他各个链的轻客户端合约,对开发人员简直是地狱级挑战。这就导致合约编写出现bug的概率变大,也就是说轻客户端桥的安全性仅仅是理论层面的,在工程实践方面,反而很不安全。
为了降低开发工程量,有一个可行的方案是引入一条中继链,让所有链与这条中继链互相建立轻客户端合约,这的确可以让曾经C(n,2)的工作量减少为 n,但依旧不会太小。原本从源链到目标链直接的跨链传递,也变成了源链→中继链→目标链的二阶传输,这会产生额外的gas消耗和时间消耗。
因此,轻客户端的技术方案,目前来看,无法被用于构建更普适的跨链桥。

End Game


首先,不同的公链有着不同的做法,背后也有不同的资源在支持,只要不服输,生态一定会存在,即使短期内发展不是很好,也说不定哪天做了一个升级就又活过来了。像这种底层infra的事情就是看谁坚持得久,看谁针对市场调整得快。


Bitcoin和Ethereum不能解决所有的应用场景,又或者说在某一个细分赛道,总有人不喜欢第一名,于是新造一个轮子,因此未来一定会是多链的。或者以后底层都不是链了,那未来一定是多生态的,多个生态之间的资金和消息怎么做传递呢,就一定需要有跨链/跨生态技术!


跨链这件事情上用户最关注什么呢?无非是以下几点:


速度:一笔跨链操作需要多久完成


费用:我需要为一笔跨链操作支付多少


安全:跨链桥是否安全,资金会不会丢失


流动性:是否有足够的流动性以支持我的交易以及可接受的price impact


连接范围:你支持多少条链,是否支持我的跨链操作中需要用到的链


体验:跨链操作是否方便,例如是否支持Gas代付、费用预估是否准确、是否支持进度查询和浏览器查看,出现失败的情况是否频繁,失败如何处理等等。


我们先从安全、费用、连接范围三个比较清晰的角度来概览一下一些项目的特性。

点击链接查看清晰表格(表格不断更新中):

https://docs.google.com/spreadsheets/d/1LKlbd5KJUnQIx3ZBTgyMADhxHtWVwBH9qDRm765tPMw/

为了完全说清楚跨链桥,其实还有很多维度的细节需要讨论,例如上面表格里面的所有维度和数据分析。那么你在跨链时,会在意哪些要素呢?你经常使用的跨链桥有哪几个?你认为跨链桥应该着重在哪些方面优化?如果你有你的想法,欢迎与作者交流。