Polygon 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 Polygon validators relay the data to another contract on Polygon chain. This StateSync mechanism is used to send data from Ethereum to Polygon.
Polygon validators also periodically submit a hash of all transactions on Polygon chain to Ethereum chain. This Checkpoint can be used to verify any transaction that happened on Polygon. Once a transaction is verified to have happened on Polygon chain, action can be taked accordingly on Ethereum.
These 2 mechanisms can be used together to enable two way data(state) transfer between Ethereum and Polygon. To abstract out all these interactions, you can directly inherit our FxBaseRootTunnel (on Ethereum) and FxBaseChildTunnel (on Polygon) contracts.
Root Tunnel Contract
FxBaseRootTunnel contract from here. This contract gives access to following functions:
function _processMessageFromChild(bytes memory data): This is a virtual function that needs to be implemented in the contract which inherits it to handle data being sent from ChildTunnel.
_sendMessageToChild(bytes memory message): This function can be called internally with any bytes data as a message. This data will be sent as it is to the child tunnel.
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.js is included below.
Child Tunnel Contract
FxBaseChildTunnel contract from here. This contract gives access to following functions:
function _processMessageFromRoot(uint256 stateId, address sender, bytes memory data): This is a virtual function that needs to implement the logic to handle message sent from the RootTunnel.
function _sendMessageToRoot(bytes memory message): This function can be called internally to send any bytes message to the root tunnel.
- You'd need to inherit
FxBaseRootTunnelcontract in your root contract on ethereum. As an example, you can follow this contract . Similarly, inherit
FxBaseChildTunnelcontract in your child on Matic. Follow this contract as an example.
- While deploying your root contract on Goerli testnet, pass the address of
0x3d1d3E34f7fB6D26245E6640E1c50710eFFf15bA. For ethereum mainnet
- For deploying the child contract on Mumbai testnet, pass
_fxChildin constructor. For Polygon mainnet,
setFxChildTunnelon deployed root tunnel with the address of child tunnel (E.g: https://goerli.etherscan.io/tx/0x79cd30ace561a226258918b56ce098a08ce0c70707a80bba91197f127a48b5c2 )
setFxRootTunnelon deployed child tunnel with address of root tunnel (E.g: https://mumbai.polygonscan.com/tx/0xffd0cda35a8c3fd6d8c1c04cd79a27b7e5e00cfc2ffc4b864d2b45a8bb7e98b8/internal-transactions )
Example contracts of state transfer bridge
- Contracts: Fx-Portal Repository
- Goerli: 0xc4432e7dab6c1b43f4dc38ad2a594ca448aec9af
- Mumbai: 0xa0060Cc969d760c3FA85844676fB654Bba693C22
State transfer from Ethereum to Polygon
- You'd need to call
_sendMessageToChild()internally in your root contract and pass the data as an argument to be sent to Polygon. (E.g: https://goerli.etherscan.io/tx/0x28705fcae757a0c88694bd167cb94a2696a0bc9a645eb4ae20cff960537644c1 )
- In your child contract, implement
_processMessageFromRoot()virtual function in
FxBaseChildTunnelto retrieve data from Ethereum. The data will be received automatically from the state receiver when the state is synced.
State transfer from Polygon to Ethereum
_sendMessageToRoot()internally in your child contract with data as a parameter to be sent to Ethereum. ( E.g: https://mumbai.polygonscan.com/tx/0x3cc9f7e675bb4f6af87ee99947bf24c38cbffa0b933d8c981644a2f2b550e66a/logs )
- Note the transaction hash as it'll be used to generate proof after it has been included as a checkpoint. Use the following sample script to generate proof from transaction hash.
_processMessageFromChild()in your root contract.
- Use the generated proof as an input to
receiveMessage()to retrieve data sent from child tunnel into your contract. ( E.g: https://goerli.etherscan.io/tx/0x436dcd500659bea715a09d9257295ddc21290769daeea7f0b666166ef75e3515 )