项目介绍
Nomad是一个乐观跨链互操作协议。通过Nomad协议,Dapp能够在不同区块链间发送数据(包括rollups),Dapp通过Nomad的合约和链下的代理对跨链数据、消息进行验证、传输。其安全通过乐观验证机制和欺诈证明制约验证者实现,保证Nomad协议的安全性
市场情况
2022年4月13日,Nomad以2.25亿美元估值完成高达2200w美元种子轮融资,Polychain领投
重要事件
2022年8月2日,Nomad跨链桥被盗超过1.9亿美元
核心技术价值
- 跨链客户端中消息组织为Merkel Tree,方便提供欺诈证明
- 不需要对交互链的区块头进行中转,降低跨链代价
- 部署、重用方便
- Home、Replica的设计思想值得借鉴,但实现和文档描述不一致
竞品分析
Hyperlane | Nomad | |
---|---|---|
跨链消息验证 | 通过消息组成的Merkel Tree验证跨链消息存在性 | |
验证方式 | 多签验证 | 乐观验证+挑战期 |
链下 | 多个验证者对消息树树根进行多重签名,Relayer中转 | 单个验证者签名提交到源链合约,再由Relayer中转 |
欺诈证明 | 在实现中 | 提供不完全,目的链上无法提供欺诈证明 |
项目技术原理
组成组件
- 链上合约:
- Home合约,部署在所有链上,为所有Dapp发出跨链消息
- Replica合约,部署在所有链上,为Dapp接收Home合约发出的跨链消息
- XAppConnectionManager合约,管理上述合约注册、Watcher提供欺诈证明等
- 链下代理:
- Updater,观察Home合约发出的消息事件,对消息树证明进行签名,并再发布消息树证明到Home合约中,(都是源链Home合约)
- Watcher,观察Updater与Home合约的交互行为,对恶意行为进行监督并提供欺诈证明
- Relayer,中转消息树更新到目的链的Replica合约中,为该消息树根开启挑战期
- Processor,根据过了挑战期的消息树根,为跨链消息提供的对应的Merkel proof,证明跨链消息的有效性,并发起目的链调用
整体架构
跨链流程如下
源链Chain A上:
1、Dapp向跨链桥发起调用
2&3、跨链桥调用底层协议dispatch()发出跨链消息事件,同时跨链消息也会被添加到Home合约的消息树中
链下:
4、Updater监听到下Home合约的消息树更新事件,对更新的新的树根和上一次保存的树根进行签名,即<oldroot, newroot, sig>,该签名作为树累加消息的更新证明被提交到Home合约中
5&6、Relayer检测到Updater提交的签名发出更新事件,将树根的签名中转到目的链Replica合约,开启挑战期
目的链Chain B上:
7、Processor根据Relayer中转的签名,在挑战期内观察,若提交的签名与消息树更新过了挑战期,则说明消息树更新有效
8、Processor发起目的链调用,并提交跨链消息对应消息树的Merkel proof,根据消息树更新的树根和Merkel Proof验证跨链消息,最终完成跨链消息调用
Watcher行为:在Nomad协议中,Watcher主要观察Home合约内消息树的的更新是否有效,若存在问题则直接在跨链协议中终止Replica合约接收跨链消息。(代码层面没有体现欺诈证明的验证)
合约架构
上述为Nomad协议的合约架构,其中协议的核心是Home、Replica合约。
Home合约:
Home合约管理着由消息组成的Merkel Tree状态和树根的队列queue,该队列保存了每次向Merkel Tree添加消息而引起的树跟的变化。并且Updater通过update()方法会向Home合约提交两次相邻变化的消息树树根的签名,作为跨链消息引起消息树变化的证明,即<oldroot, newroot, sig>的形式,当签名验证通过是newroot会被认为是有效的,能够被用来进行跨链消息验证。
Replica合约:
Replica合约负责消息树树根变化的签名信息<oldroot, newroot, sig>,该消息会被Relayer中转到目的链,并且辅助验证跨链消息。跨链消息即,每次更新消息树的树根的负责发出跨链消息和跨链消息树根的Updater签名证明。最终Processor通过proveAndProcecss()方法提交跨链消息和对应的Merkel proof进行目的链验证和调用目的链合约。
XAppConnectionManager合约:
负责管理当前链上的Replica合约和远程链上的合约(与Replica接收端相对应Home发送端);同时接收Watcher的签名并对有问题的Home合约对应的Replica合约进行接收消息终止,保证跨链业务的安全。
安全
跨链消息验证
在Nomad协议中,Home合约和Replica合约相当于跨链消息的发送端和接收端,XAppConnectionManager负责管理二者,二者在服务于跨链流程时成对出现。
而Updater需要向Home提交消息树树根的签名作为跨链消息在消息树中存在的证明,该签名会在源链上和目的链上被验证,目的链上验证则是帮助验证跨链消息是否在消息树中。
核心:将跨链交易在区块中的存在性证明,转变为在交易树中的证明,但是需要链下的签名保证传递到目的链的消息树树根正确性。因此,引入了链下节点的签名来作为见证,但也是由此,该签名由链下Updater产生,消息树的正确性最终就委托到了链下的签名者身上,有一定的中心化风险。虽然官方文档中描述Updater是去中心化的,但是目前在合约中并没有体现,而是每个Home合约只绑定一个Updater。
欺诈证明
在源链的Home端为了保证链下的Updater不作恶,可以通过两种方式检测到Updater的恶意行为。
检测欺诈证明提供的两种方式:
1)在Updater提交对消息树根的签名时,检查是否Updater提交了不在树根队列中的错误的根
2)任何人可以通过提交两个新的矛盾的树根和签名,证明Updater曾经对两个树根进行签名
但Nomad协议中,并未给出具体的如何惩罚Updater的行为,或者一些经济行为的惩罚,这部分应该是交给了上层桥的开发者实现。
另外,在目的链上Replica中为每个被中转的消息树及证明设定了挑战期。由于目的链上不能感知到源链上哪一个消息树的树根是正确的,因此引入了Watcher来进行监督。若在挑战期内,任何诚实的Watcher发现Home合约和Updater交互出错,Watcher有权利直接通过XAppConnectionManager终止Replica合约接收跨链消息,阻止跨链消息在目的链被处理。Watcher并不需要提供任何证明,因为目的链上当前的实现中不跟踪每一个消息树的树根更新记录,也无法提供证明。
思考
1)Watcher不是去信任的,由于当前的Nomad设计中Replica上没有跟踪消息树更新,Watcher无法提供欺诈证明,Watcher需要在合约中经过许可才能进行管理、监督
2)Replica合约应该增加记录消息树更新的状态,以便能够在目的链端进行欺诈证明的检测
参考资料
官方文档:Funds Recovery | Nomad Docs
github:GitHub - nomad-xyz/monorepo: Nomad Monorepo -- SDKs, Contracts, and more!