Created
December 16, 2021 21:46
-
-
Save dbeal-eth/5f88d0f51d49cc0fc12389227f84ca1a to your computer and use it in GitHub Desktop.
theoretically cross chain messaging implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.16; | |
// Inheritance | |
import "./Owned.sol"; | |
import "./interfaces/IAddressResolver.sol"; | |
import "./interfaces/ISystemMessenger.sol"; | |
// https://docs.synthetix.io/contracts/source/contracts/systemstatus | |
contract SystemMessenger is Owned, ISystemMessenger { | |
bytes32 public constant CONTRACT_NAME = "SystemMessenger"; | |
IAddressResolver public resolver; | |
uint[] public activeChains; | |
mapping(uint => address) public messengerAddresses; | |
mapping(uint => uint) public outgoingNonces; | |
mapping(uint => uint) public incomingNonces; | |
constructor(address _owner, IAddressResolver _resolver) public Owned(_owner) { | |
resolver = _resolver; | |
} | |
/* ========== VIEWS ========== */ | |
/* ========== MUTATIVE FUNCTIONS ========== */ | |
// send a message only to one chain | |
function post( | |
uint targetChainId, | |
bytes32 targetContract, | |
bytes data, | |
uint32 gasLimit | |
) public onlyAuthorizedMessenger { | |
emit MessagePosted(targetChainId, outgoingNonces[targetChainId]++, targetContract, data, gasLimit); | |
} | |
// sends a copy of this message to all chains synthetix is deployed to | |
function broadcast( | |
bytes32 targetContract, | |
bytes data, | |
uint32 gasLimit | |
) public onlyAuthorizedMessenger { | |
for (uint i = 0;i < activeChains.length;i++) { | |
post(activeChains[i], targetContract, data, gasLimit); | |
} | |
} | |
function receive( | |
uint srcChainId, | |
uint srcNonce, | |
bytes32 targetContract, | |
bytes data, | |
uint32 gasLimit | |
) external onlyRelayer { | |
require(incomingNonces[srcChainId]++ == srcNonce, "can only submit next message nonce"); | |
address target = resolver.requireAndGetAddress(targetContract, "Target address resolver contract does not exist"); | |
target.call{gas:gasLimit}(data); | |
} | |
function addChain(uint chainId, address messenger) external onlyOwnerOrSelf { | |
broadcast("SystemMessenger", abi.encodeWithSelector("", chainId, messenger), msg.gas); | |
messengerAddresses[chainId] = messenger; | |
activeChains.push(chainId); | |
} | |
function addChain(uint chainId, address messenger) external onlyOwnerOrSelf { | |
broadcast("SystemMessenger", abi.encodeWithSelector("", chainId, messenger), msg.gas); | |
messengerAddresses[chainId] = address(0); | |
for (uint i = 0;i < activeChains.length;i++) { | |
if (activeChains[i] == chainId) { | |
activeChains[i] = activeChains[activeChains.length - 1]; | |
activeChains.pop(); | |
return; | |
} | |
} | |
revert("could not find specified chain id"); | |
} | |
/* ========== EVENTS ========== */ | |
event MessagePosted(uint indexed targetChainId, uint indexed nonce, bytes32 indexed targetContract, bytes data, uint32 gasLimit); | |
event MessageProcessed(bytes32 indexed srcChainId, uint indexed nonce, bytes32 indexed targetContract, bytes data, uint32 gasLimit); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment