Matic validators continuously monitor a contract on Ethereum chain called StateSender. Each time a registered contract on Ethreum chain calls this contract, it emits an event. Using this event Matic validators relay the data to another contract on Matic chain. This StateSync mechanism is used to send data from Ethereum to Matic.
Matic validators also periodically submit a hash of all transactions on Matic chain to Ethereum chain. This Checkpoint can be used to verify any transaction that happened on Matic. Once a transaction is verified to have happened on Matic chain, action can be taked accordingly on Ethereum.
These 2 mechanisms can be used together to enable two way data transfer between Ethereum and Matic. To abstract out all these interactions, you can directly inherit our BaseRootTunnel (on Ethereum) and BaseChildTunnel (on Matic) contracts.
Root Tunnel Contract
Use the BaseRootTunnel contract from here. This contract gives access to following functions -
_sendMessageToChild(bytes memory message)- This function can be called internally with any bytes data as message. This data will be sent as it is to ChildTunnel.
_processMessageFromChild(bytes memory message)- This is a virtual function that needs to be implemented to handle data being sent from ChildTunnel.
receiveMessage(bytes memory inputData)- This function needs to be called to receive the message emitted by ChildTunnel. The proof of transaction needs to be provided as calldata. An example script to generate proof using matic SDK in given here.
Child Tunnel Contract
Use the BaseChildTunnel contract from here. This contract gives access to following functions -
_sendMessageToRoot(bytes memory message)- This function can be called internally to send any bytes message to RootTunnel.
_processMessageFromRoot(bytes memory message)- This is a virtual function that needs to implement the logic to handle message sent from RootTunnel.
As an example we will implement contracts where we want to calculate sum till a provied number. The sum can be calculated on Ethereum chain by calling
calculateSum function. This will be too expensive due to high gas fees.
Alternatively we can call
calculateSumOnChildChain. This will internally send the number to ChildTunnel by calling
_sendMessageToChild. Then on Matic chain
_processMessageFromRoot will receive this number and do required calculation. After calculation is done call
_sendMessageToRoot to emit this calculated result. Now finally call
receiveMessage on RootTunnel giving proof of emitted result. This will internally call
_processMessageFromChild to store it in variable.
Both these methods will give the same final result. Second method takes some more transactions but overall gas cost will be less because all heavy processing is done on Matic chain and only result is stored on Ethereum.
Please note that you have to set the child tunnel contract address and checkpoint manager address in the root tunnel contract.
setChildTunnel are the two functions exposed on the root tunnel contract for this purpose. The child tunnel contract address has to be passed to
0x2890bA17EfE978480615e330ecB65333b880928e has to be passed to
setCheckpointManager. This address is the contract address of the root chain proxy on Goerli. Its mainnet equivalent is
Once you are ready with implementing your version of RootTunnel and ChildTunnel contracts, you need to register them on StateSender contract.