So, it has been quite some while now that Chainlink has gone live on testnet with Chainlink CCIP – its offering for cross-chain communication. I have had my eyes on it for quite some while now. At EthIndia’23, I finally had the chance to build with it.
Considering I have had a hiatus of sorts with Web3 articles, this would be the perfect way to come back with another one. This is the first article in a series of architecture where we will build something with Chainlink CCIP and we will do it end-to-end.
But before we get on with the code and the mini-project, I feel some introduction is in order. I have always been a fan of concise articles (though my recent ones have been on the longer side). So, I thought why not try to explain Chainlink CCIP in 15 points.
Chainlink CCIP in 15 bullet points
Keep in mind that this is no substitute for the Chainlink Documentation. I would always refer my reader to it for an in-depth understanding. This is more of a Traversy Media-like Crash Course for Chainlink CCIP. So here goes…
Chainlink CCIP uses a library called
Client
on top of this theRouterClient
is built using theIRouterClient
interface.Extra payment as gas fees for cross-chain transactions is graciously accepted. It offers no refund.
On-Ramp is
sending message and/or token
. Off-Ramp isreceiving message and/or token
.For the on-ramp,
IRouterClient
needs to be implemented.There is a specific on-ramp contract for EVM-to-EVM messages. It is a specialized version of CCIP’s EVM to Any and implements
IEVM2AnyOnRamp
. TheIEVM2AnyOnRamp
inherits fromIEVM2AnyOnRampClient
.Similarly, there is a specific off-ramp contract for EVM-to-EVM messages. It is a specialized version of CCIP’s Any to EVM and implements
IAny2EVMOffRamp
.The
IEVM2AnyOnRampClient
is similar toIRouterClient
but with the difference that it is used only by the Router to route the message and spend the tokens whileIRouterClient
is called by the Initial sending contract.Intuitively think of yourself as a passenger on a train with
IRouterClient
as the starting point,IEVM2AnyOnRamp
as the first hop from where it goes toIAny2EVMOffRamp
and then to the terminusIAny2EVMMessageReceiver
. In between theIEVM2AnyOnRamp
andIAny2EVMOffRamp
there is anIRouter
junction station. You, the passenger, are the message transported from the starting to the terminal station.Chainlink provides an abstract contract called
ChainlinkReceiver
. This contract inherits but does not implement theIAny2EVMMessageReceiver
interface. The idea is that the developer can override and implement the_ccipReceive()
function with custom business logic. This is called byccipReceive()
external function defined inChainlinkReceiver
contract. Only the Router can call this external function (courtesy of theonlyRouter()
) modifier defined in the contract.A Contract inheriting
ChainlinkReceiver
needs to pass in the router address through constructor initialization. This address is defined asimmutable
in theChainlinkReceiver
contract. This means that once initialized, it cannot be changed. This is meant to provide gas optimization.Where does the “Risk Management Network” come here? The RMN is a network of nodes that run parallel to the Chainlink CCIP infrastructure. It helps to make sure that the transactions arising from the source chain and terminating on the destination chain are valid.
I will not go too deep into it. But if one were to try to understand it, picture a DAO where every node is a network and a CCIP transaction is a proposal. Every node has a weight (or “voting power”). If the Nodes “bless” (or vote “for”) the transaction (or “proposal”) to reach a quorum, then the transaction is valid. Otherwise, it is “cursed”.
To be more precise, there is a Merkle root of transactions for each chain whose validity the RMN nodes need to decide. If a Merkle root is invalidated (or “cursed”), CCIP functions on that specific chain are paused. For most parts, Smart Contract Devs trying CCIP for applications won’t have to touch the RMN.
To know if a Cross-chain transaction is successful, one needs to browse the CCIP explorer. Once finality is achieved and indexed on the CCIP explorer, the destination smart contract will have received the intended message.
At this time, the token transfer is ERC20. It consists of the sender contract spending (or “burning”) the tokens on the source chain. The destination chain needs to mint the token independently.
What’s next?
Well, next is the New Year. Best wishes for the upcoming year and may 2024 be the year my readers achieve their dev dreams. On a serious note, in the next article, we will dive into the Code for Chainlink CCIP and demo it with NFT token transfer and more. Till then, keep building awesome things on Web3 and WAGMI!