接下来,我们将通过几个步骤来看一下 CCIP 消息的工作流程。
发送方准备一条 CCIP 消息 (EVM2AnyMessage),用于其到目标区块链(chainSelector)的跨链交易。一条CCIP 消息包括以下信息:
接收方
数据载荷
代币地址和金额
费用代币
其他参数(gasLimit,strict)
发送方调用 Router.getFee()
获得支付给 CCIP 的总费用(包括 gas 和溢价),并授权这部分费用金额。
发送方调用 Router.ccipSend()
,提供他们想要发送的 CCIP 消息及其期望的目标链chainSelector
。考虑到要进行代币的转移,这部分金额必须被授权给 Router。
Router 验证接收到的消息(例如,支持的目标链IDchainId
和支持的目标链上的代币)。
Router 接收手续费并将其转给 OnRamp。
Router 接收代币并将其转到对应的代币池。如果发送方未将此代币授权给 Router,此操作将失败。
Router 将消息转发给正确的 OnRamp(基于目标链选择器chainSelector
)进行处理:
验证消息(代币数量、gasLimit、数据长度等)。
[对于代币转移] 确保转移的金额不超过该通道的总速率限制。
使用序列号sequence number对消息进行排序。
对于消息中包含的每种代币:通知代币池锁定/销毁代币。这也将验证该通道的代币池速率限制。
OnRamp 抛出包含已排序消息的事件。这会触发 DONs 处理消息。
生成一个 messageId 并返回给发送方。
Commiting DON中的节点监听已准备好发送的消息事件。
考虑到消息的安全性,为了防止重组攻击,消息必须处于finalized状态。
当 OnRamp 中的消息队列达到一定数量或时间时,将触发Committing DON 创建一个包含所有发送消息的带有承诺的Report(以批次形式)。此承诺以 Merkle Root的形式表示。
在Committing DON 达成共识后,包含 Merkle Root的Report被传送给目标链上的 CommitStore 合约。
风险管理网络(Risk Managemendt Network)通过CommitStore合约中“批准”该Merkle Root,以确保它可以正确代表 OnRamp 中经过排序的消息。
Merkle Root:Merkle Tree的根哈希值。它是对树中所有叶子节点(消息 M1-M4)的承诺。树中的每个节点都是其下方节点的哈希值。
Merkle Proof:为了证明消息 M1 被包含在 Merkle Root(承诺)中,证明者向仅持有Merkle Root的Verifier提供以下元素作为证明:
M1
H(M2)
H(H(M3),H(M4))
使用这个Merkle Proof,Verifier可以轻松地验证M1确实包含在其拥有的承诺(Merkle Root)中。
执行 DON 中的节点监听准备发送的消息事件,该过程类似于Committing DON。
考虑到消息的安全性,为了防止重组攻击,消息必须处于finalized状态。
除了监控时间或OnRamp
中消息队列中的消息数量外,Executing DON还监控CommitStore
合约,以确保消息已准备好在目标链上执行,即消息是否包含在被批准的链上承诺中。
如果条件满足,Executing DON将创建一个包含所有准备发送的消息的Report(以批次形式)。它在批处理逻辑中说明每条消息的 gasLimit。它还为每条消息计算相关的Merkle Proof,以证明该消息包含在Committing DON向CommitStore合约提交的Merkle Root中。注意,Executing DON 的批次可以是Committing DON批次的任何子集。
达成共识后,Report将被传送到目标链上的OffRamp
合约。
对于接收到的批次中的每条消息,OffRamp
合约使用提供的Merkle Proof验证该交易是否包含在CommitStore
合约中被批准的承诺中。
如果交易中包含代币,OffRamp
合约将验证通道的总速率限制并去匹配对应的代币池。
OffRamp
调用代币池的unlock
/mint
函数。这将验证代币池的速率限制,并解锁或铸造代币并将其转移给指定的接收方。
如果接收方是一个合约地址并且实现了正确的接口,OffRamp
使用Router来调用接收方的 ccipReceive()
函数。
接收方处理消息,并被告知此消息的来源(区块链 + 发送方)、转移的代币和数据载荷(含相关指令)。
根据数据载荷,接收方可能将代币转移给最终接收者(终端用户)。
那么,你是否需要了解 CCIP消息处理的具体过程呢?完全不需要。你只需通过与Router合约交互来发送跨链消息,Chainlink CCIP会将其投递出去。这就像寄包裹一样——你只需将包裹交给邮局,标明收件人并支付费用即可。
就像国际航班中涉及各种检查站和相应程序确保从一个国家到另一个国家的旅程安全一样,Chainlink CCIP确保了不同区块链网络之间在被验证状态下的安全通信。
在任何飞机起飞之前,都需要进行一系列严格的检查——类似于CCIP 的初始化阶段。这里,Router充当了我们的值机柜台,用户在这里提交他们的跨链请求,就像乘客确认他们的航班细节一样。
旅行者检查他们的行李,然后由机场工作人员处理。就像长途航班上的任何行李一样,跨链消息也要遵循安全协议。同样在CCIP中,OnRamp合约检查目标区块链地址的有效性、消息大小、gas 限制和序列号,确保“行李”(或数据载荷)已为其旅程做好准备。
护照和签证的验证非常像 Commit Store 智能合约,它存储finalized状态消息的Merkle Root,并确保这些消息在目标链上执行之前会通过风险管理网络的“批准”来保证其真实性和安全性。
在飞行过程中,乘客和行李处于运输状态,类似于跨链消息在网络之间传播。Executing DON类似于幕后工作的机组人员,确保跨链交互的顺利进行。
正如我们所知,飞行的持续时间可能会有所不同——向东飞行可能会追逐太阳,缩短我们感受到的白天,而向西飞行则会延长它。同样,跨链消息的交付时间取决于源区块链的最终确定性。我们从 CCIP大师班 #1 中了解到,最终确定性是指区块链上交易的不可逆性和永久记录状态。
到达时,OffRamp合约通过验证已提交和批准的Merkle Root来确保消息的真实性。
就像风险管理网络在幕后进行的最终检查(乘客看不到)一样,行李或我们的跨链消息也要经过各种安全检查,确保其符合目标区块链的规则及规范。
最后,目标链上的Router扮演边境管制的角色,将消息数据和/或代币传递到接收方地址,就像旅客拿到盖了章的护照进入新国家一样。
尽管整个过程很复杂,但对于终端用户来说大多是不可见的,他们仅仅体验到数字资产从一个区块链到另一个区块链的无缝转移。从值机到取回行李的喜悦,通过CCIP进行跨链消息传递的整个过程可谓是现代密码学的奇迹,它确保我们收到的东西就是之前我们交付给网络的。