研究了一下Stargate是怎么实现的

https://github.com/stargate-protocol/stargate/blob/main/whitepaper/Delta-Solving.The.Bridging-Trilemma.pdf

跨链桥的不可能三角:

  1. 即时确定性,从A链提交的向B链的跨链请求能够被立即响应

  2. 统一流动性,如果跨链桥对于每两条链都要单独创建一个池子,那么池子总数会随着链的数量呈平方增长

  3. 原生资产,而不是再印一种跨链桥承兑的资产

目前的跨链桥大都放弃了第三条,本质上是自己印一种中间资产来承兑,跨到目标链之后还要再swap一次,而这个中间资产可能流动性很差。有一些跨链桥本质上是钱庄,两边都是原生资产,中间靠中心化核对和承兑,不知道属于放弃了哪一条。stargate提出了一种基于layerzero的跨链桥算法,能够保证你提交的任意一笔转账,要么因为目标链没有足够额度而直接被拒绝,要么必然能转账成功。证明用的是数学归纳法,即对于初始情况(第一笔转账),证明了结论必然成立,并且对于任意已知的历史H,新增的一笔转账也能使结论成立,那么由归纳法可知,结论必然成立。我们更关心的是具体如何实现,下边我用论文里的例子拆解一下。 需要补充说明:为了让模型尽量简洁,以下讨论时我们忽略了跨链手续费和gas fee,并认为智能合约和跨链通信是绝对安全可信的。实际上,跨链桥应当积累手续费,并在池子比例极端的情况下,向此时的流动性提供者发放奖励,或动态调整手续费以鼓励让桥恢复平衡的行为。我们假定要在XYZ三条链上部署Stargate,对于X链,我们会设置一些变量,Y链和Z链同理: 初始流动性 lp_x,向跨链桥存入的初始资产,只会在发生存取款行为时改变,不会在发生跨链活动时改变; 权重 w_xy,w_xz,要理解成是看待其他链的权重,权重越高代表向相应链的额度越高,权重总和是1; 总资产 a_x,是经过了存取款、跨链行为之后,剩余的资产,初始情况下a_x = lp_x; 可跨链资产 b_xy,b_yz,意思是最大可充值的额度,也就是目标链上能被提走的额度,如果跨链需求大于它,会被拒绝,比如b_xy=10,意思就是在x链发起向y的跨链,最多可以跨10; 最近一次被知道的额度 lkb_yx,lkb_zx,名字有点抽象,实际上就是跨链桥里能被相应的链支配的资产额度,或者对于某一条链,最多能被提走的额度,lkb_yx=20,意思就是y链想发起向x的跨链,最多可以跨20; 信用 c_xy,c_xz,是在跨链过程中产生的相对于其他链的欠款,会随着每次跨链提币同步,计入lkb的资产端。 在每一笔跨链完成后,对于任一条链,可被支配总额lkb与向其他链的负债c的总和即为总资产。我们把“从S链向D链跨一笔大小为t的资产”称为一次跨链操作,跨链桥在执行此操作时,遵循以下算法过程:

  1. 检查目标链是否有足够资金可供这笔跨链需求,若b_sd < t 则拒绝此交易;

  2. 使用lp和w计算出对每一条链的目标额度。对于存入的跨链资产,优先补满全部的目标额度,在不存在赤字之后,再按照w来分配多余的额度。

  3. 按照可被提款的比例来分配本地对于其他各条链的负债

  4. 更新资产负债表,向目标链发送数据

  5. 目标链更新资产负债表,转出跨链的资产

接下来是具体例子: 三条链X,Y,Z的初始状态: 初始资产都是100,全部是LP存进来的钱 X链初始权重 w_xy = 0.5,w_xz = 0.5,可充值额度 b_xy = 60,b_xz = 50 被跨链额度 lkb_yx = 50,lkb_zx = 50,债务 c_xy = 0,c_xz = 0 YZ不赘述第一笔跨链,向X存入40,从Y提走40,算法会执行以下步骤:

  1. X可以支配Y的额度60 > 40,这笔跨链能够实现,不会拒绝

  2. 从X可支配Y的额度中扣除40,b_xy = 20

  3. X此时可以被YZ支配的资产都是50,已经达到了初始额度,所以存款按照weight来分配,记为X欠了YZ各20,c_xy = 20,c_xz = 20

  4. X链把向Y的负债计入资产,也就是X可以被Y支配的额度 lkb_yx = 70,向Y链发送同步信息

  5. Y链更新账本,Y可支配X的额度 b_yx = 70,并把本地资产发送给目标用户,更新本地资产 lkb_xy = 20

执行完以上步骤后,用户实现了向X存入40,从Y提走40。跨链桥上X的账本变成了:可被Y支配70,可被Z支配50,向Z负债20,合计140;Y的账本变成了:可支配X 70,可支配Z 50,可被X支配20,可被Y支配40,合计60。Z链上的账本没有变化。第二笔跨链,向Y存入30,从Z提走30,以下是算法步骤:

  1. Y可以支配Z的额度 b_yz = 50 > 30,所以不会拒绝

  2. 从Y可支配Z的额度扣除30,剩余 b_yz = 20

  3. 由于Y可被X支配的初始额度是60,现在只剩20,存款会优先补充这个额度,此处记为Y增加了30对X的负债,c_yx = 30

  4. Y向Z发送同步,Z可支配Y额度 lkb_yz = 20,Z向用户转账30

执行完以上步骤后,Y多了30向X的负债,Z减少了30的资产。第三笔跨链,向Y存20,从X取20:

  1. Y可以支配X的额度 b_yx = 70 > 20,不会拒绝,扣除20,b_yx = 50

  2. 由于Y可被X支配的初始额度是60,现在剩20+30=50,还差10,存款会优先补充这个额度;存款是20,补了10,剩下的10会按照weight来分配,所以最后Y向X的负债 c_yx = 30 + 10 + 6 = 46,Y向Z的负债 c_yz = 4

  3. Y向X的负债并入X的可支配资产,向X发送同步消息,此时lkb_xy = 20 + 46 = 66

  4. X收到信息,修改可支配Y的资产 b_xy = 66,并向用户转账20,此时lkb_yx = 70 - 20 = 50

执行完以上步骤后,Y对X的负债并入了资产,对Z产生了负债;X增加了可支配X的资产。总的来说,这个算法靠一笔转入、一次链间发送消息和一笔转出,实现了多链转账系统,还是挺不错的。