编译器
0.8.19+commit.7dd6d404
文件 1 的 6:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 6:IMessenger.sol
pragma solidity ^0.8.12;
interface IMessenger {
function sendMessage(address target, bytes calldata message) external;
function callAllowed(address caller, address courier)
external
view
returns (bool);
}
文件 3 的 6:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 4 的 6:PolygonZkBridgeInterface.sol
pragma solidity ^0.8.19;
interface IPolygonZkEVMBridge {
function bridgeMessage(
uint32 destinationNetwork,
address destinationAddress,
bool forceUpdateGlobalExitRoot,
bytes calldata metadata
) external payable;
}
文件 5 的 6:PolygonZkEVMMessengers.sol
pragma solidity ^0.8.19;
import "../../../interfaces/IMessenger.sol";
import "../../RestrictedCalls.sol";
import "polygon_zkevm/PolygonZkBridgeInterface.sol";
contract PolygonZkEVMMessenger is IMessenger, RestrictedCalls {
IPolygonZkEVMBridge public immutable bridge;
address public immutable localCallee;
address public remoteMessenger;
uint32 public immutable remoteNetwork;
constructor(address _bridge, address _localCallee, uint32 _remoteNetwork) {
bridge = IPolygonZkEVMBridge(_bridge);
localCallee = _localCallee;
remoteNetwork = _remoteNetwork;
}
function setRemoteMessenger(address _remoteMessenger) public onlyOwner {
require(remoteMessenger == address(0), "Remote messenger already set");
remoteMessenger = _remoteMessenger;
}
function callAllowed(
address,
address courier
) external view returns (bool) {
return courier == address(this);
}
function onMessageReceived(
address originAddress,
uint32 originNetwork,
bytes memory data
) external payable {
require(msg.sender == address(bridge), "Call not allowed");
require(originNetwork == remoteNetwork, "Origin not allowed");
require(originAddress == remoteMessenger, "Call forbidden");
(bool sent, ) = localCallee.call(data);
require(sent, "Failed to execute call");
}
function sendMessage(
address,
bytes calldata message
) external restricted(block.chainid) {
bridge.bridgeMessage(remoteNetwork, remoteMessenger, true, message);
}
}
文件 6 的 6:RestrictedCalls.sol
pragma solidity ^0.8.19;
import "OpenZeppelin/openzeppelin-contracts@4.8.0/contracts/access/Ownable.sol";
import "../interfaces/IMessenger.sol";
contract RestrictedCalls is Ownable {
mapping(uint256 callerChainId => address[2]) public callers;
function _addCaller(
uint256 callerChainId,
address caller,
address messenger
) internal {
require(caller != address(0), "RestrictedCalls: caller cannot be 0");
require(
callers[callerChainId][0] == address(0),
"RestrictedCalls: caller already exists"
);
callers[callerChainId] = [caller, messenger];
}
function addCaller(address caller) external onlyOwner {
_addCaller(block.chainid, caller, address(0));
}
function addCaller(
uint256 callerChainId,
address caller,
address messenger
) external onlyOwner {
_addCaller(callerChainId, caller, messenger);
}
modifier restricted(uint256 callerChainId) {
address caller = callers[callerChainId][0];
if (callerChainId == block.chainid) {
require(msg.sender == caller, "RestrictedCalls: call disallowed");
} else {
address messenger = callers[callerChainId][1];
require(
messenger != address(0),
"RestrictedCalls: messenger not set"
);
require(
IMessenger(messenger).callAllowed(caller, msg.sender),
"RestrictedCalls: call disallowed"
);
}
_;
}
}
{
"compilationTarget": {
"PolygonZkEVMMessengers.sol": "PolygonZkEVMMessenger"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":OpenZeppelin/openzeppelin-contracts@4.8.0/contracts=.cache/OpenZeppelin/v4.8.0",
":interfaces=.cache/Interfaces/local",
":polygon_zkevm=.cache/Polygon-ZkEVM/local"
]
}
[{"inputs":[{"internalType":"address","name":"_bridge","type":"address"},{"internalType":"address","name":"_localCallee","type":"address"},{"internalType":"uint32","name":"_remoteNetwork","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256","name":"callerChainId","type":"uint256"},{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"messenger","type":"address"}],"name":"addCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"addCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IPolygonZkEVMBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"courier","type":"address"}],"name":"callAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"callerChainId","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"callers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localCallee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"originAddress","type":"address"},{"internalType":"uint32","name":"originNetwork","type":"uint32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onMessageReceived","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remoteMessenger","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remoteNetwork","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_remoteMessenger","type":"address"}],"name":"setRemoteMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]