文件 1 的 4: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 的 4:Governable.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
abstract contract Governable is Context {
address private _governance;
event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance);
constructor() {
_transferGovernance(_msgSender());
}
function governance() public view virtual returns (address) {
return _governance;
}
modifier onlyGovernance() {
require(governance() == _msgSender(), "Governable: caller is not the governance");
_;
}
function renounceGovernance() public virtual onlyGovernance {
_transferGovernance(address(0));
}
function transferGovernance(address newGovernance) public virtual onlyGovernance {
require(newGovernance != address(0), "Governable: new governance is the zero address");
_transferGovernance(newGovernance);
}
function _transferGovernance(address newGovernance) internal virtual {
address oldGovernance = _governance;
_governance = newGovernance;
emit GovernanceTransferred(oldGovernance, newGovernance);
}
}
文件 3 的 4:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 4 的 4:TokenBridge.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./Governable.sol";
contract TokenBridge is Governable {
event Deposit(address indexed src, uint256 amount, address indexed token);
event Withdrawal(address indexed src, uint256 amount, address indexed token);
function deposit(uint256 amount, address token) public {
require (amount > 0, "!amount");
require (IERC20(token).transferFrom(_msgSender(), address(this), amount), "!transfer");
emit Deposit(_msgSender(), amount, token);
}
function withdraw(address to, uint256 amount, address token) public onlyGovernance {
require (amount > 0, "!amount");
require (IERC20(token).balanceOf(address(this)) >= amount, "!balance");
require (IERC20(token).transfer(to, amount), "!transfer");
emit Withdrawal(to, amount, token);
}
}
{
"compilationTarget": {
"contracts/TokenBridge.sol": "TokenBridge"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernance","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Withdrawal","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGovernance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]