Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x05a32f2146d381c8331f51427cD4ea19815Fe9ae
Balance 4.3689 ETH ($8473.70)
Nonce 1
Code Size 4304 bytes
Last Active
Indexed Transactions 5 (10,701,70224,321,770)
Value (indexed) ↓ 0.303400 ETH
Gas Used (indexed) 236,838
External Etherscan · Sourcify

Contract Bytecode

4304 bytes
0x60806040526004361061011f5760003560e01c80637362377b116100a05780639870d7fe116100645780639870d7fe14610401578063ac8a584a14610434578063c14e50ce14610467578063f2fde38b1461049a578063fe6b2f10146104cd5761011f565b80637362377b146103505780638456cb59146103655780638da5cb5b1461037a5780639004e5c51461038f57806397e08275146103c25761011f565b80634fadb5b1116100e75780634fadb5b11461025d57806356788a8c146102a25780635c975abb146102d55780636d70f7ae146102ea578063711bd9eb1461031d5761011f565b806301ffc9a71461012457806316aa2b981461016c578063299bb1e9146101e75780633a5381b5146102175780633f4ba83a14610248575b600080fd5b34801561013057600080fd5b506101586004803603602081101561014757600080fd5b50356001600160e01b0319166104e2565b604080519115158252519081900360200190f35b6101e56004803603606081101561018257600080fd5b81019060208101813564010000000081111561019d57600080fd5b8201836020820111156101af57600080fd5b803590602001918460018302840111640100000000831117156101d157600080fd5b91935091508035906020013560070b610501565b005b3480156101f357600080fd5b506101e56004803603604081101561020a57600080fd5b5080359060200135610685565b34801561022357600080fd5b5061022c6106dd565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b506101e56106ec565b34801561026957600080fd5b506102906004803603602081101561028057600080fd5b50356001600160a01b03166107d0565b60408051918252519081900360200190f35b3480156102ae57600080fd5b506101e5600480360360208110156102c557600080fd5b50356001600160a01b03166107e2565b3480156102e157600080fd5b50610158610879565b3480156102f657600080fd5b506101586004803603602081101561030d57600080fd5b50356001600160a01b0316610889565b34801561032957600080fd5b506101e56004803603602081101561034057600080fd5b50356001600160a01b03166108a2565b34801561035c57600080fd5b506101e5610939565b34801561037157600080fd5b506101e56109b7565b34801561038657600080fd5b5061022c610a9e565b34801561039b57600080fd5b50610158600480360360208110156103b257600080fd5b50356001600160a01b0316610aad565b3480156103ce57600080fd5b50610158600480360360608110156103e557600080fd5b506001600160a01b038135169060208101359060400135610ac0565b34801561040d57600080fd5b506101e56004803603602081101561042457600080fd5b50356001600160a01b0316610b28565b34801561044057600080fd5b506101e56004803603602081101561045757600080fd5b50356001600160a01b0316610bbd565b34801561047357600080fd5b506101e56004803603602081101561048a57600080fd5b50356001600160a01b0316610c52565b3480156104a657600080fd5b506101e5600480360360208110156104bd57600080fd5b50356001600160a01b0316610cc1565b3480156104d957600080fd5b50610158610d17565b6001600160e01b03191660009081526020819052604090205460ff1690565b600154600160a01b900460ff1615610553576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b61055e338343610ac0565b6105a1576040805162461bcd60e51b815260206004820152600f60248201526e313637b1b590373ab69032b93937b960891b604482015290519081900360640190fd5b6105e43383833488888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d2892505050565b610629576040805162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b604482015290519081900360640190fd5b336000818152600560209081526040918290208590558151858152600785810b900b9181019190915281517faf7f1dbe8979c53886deafe3799c119571d7d220dcaf900aa781da07d8182e2c929181900390910190a250505050565b61068e33610889565b6106d2576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b600691909155600755565b6004546001600160a01b031681565b6106f533610889565b610739576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b600154600160a01b900460ff1661078e576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6001805460ff60a01b191690556040805133815290517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9181900360200190a1565b60056020526000908152604090205481565b6107eb33610aad565b610831576040805162461bcd60e51b815260206004820152601260248201527126bab9ba103132903bb4ba34323930bbb2b960711b604482015290519081900360640190fd5b61084260038263ffffffff610d7b16565b6040516001600160a01b038216907fa1a8c5d4571c30d14645a130aa34aa21e2983b734153cce6cbc9eb750f5db49d90600090a250565b600154600160a01b900460ff1690565b600061089c60028363ffffffff610dfc16565b92915050565b6108ab33610aad565b6108f1576040805162461bcd60e51b815260206004820152601260248201527126bab9ba103132903bb4ba34323930bbb2b960711b604482015290519081900360640190fd5b61090260038263ffffffff610e1b16565b6040516001600160a01b038216907f4c2d50c11eee24ae13f209880951e560d483a69ccf4d53af33195df596295a9e90600090a250565b61094233610aad565b610988576040805162461bcd60e51b815260206004820152601260248201527126bab9ba103132903bb4ba34323930bbb2b960711b604482015290519081900360640190fd5b60405133904780156108fc02916000818181858888f193505050501580156109b4573d6000803e3d6000fd5b50565b6109c033610889565b610a04576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b600154600160a01b900460ff1615610a56576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001805460ff60a01b1916600160a01b1790556040805133815290517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589181900360200190a1565b6001546001600160a01b031690565b600061089c60038363ffffffff610dfc16565b6001600160a01b03831660009081526005602052604081205415610b0a576006546001600160a01b03851660009081526005602052604090205401831015610b0a57506000610b21565b60075482018310610b1d57506000610b21565b5060015b9392505050565b610b3133610889565b610b75576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b610b8660028263ffffffff610d7b16565b6040516001600160a01b038216907fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d90600090a250565b610bc633610889565b610c0a576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b610c1b60028263ffffffff610e1b16565b6040516001600160a01b038216907f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d90600090a250565b610c5b33610889565b610c9f576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610cca33610889565b610d0e576040805162461bcd60e51b815260206004820152601060248201526f26bab9ba1031329037b832b930ba37b960811b604482015290519081900360640190fd5b6109b481610e98565b6000610d24334343610ac0565b5090565b6004546000906001600160a01b0316610d4057600080fd5b6000610d5f610d59610d5489898989610ef6565b610f45565b84610f50565b6004546001600160a01b03908116911614979650505050505050565b610d858282610dfc565b15610dd7576040805162461bcd60e51b815260206004820152601c60248201527f726f6c6520616c72656164792068617320746865206163636f756e7400000000604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b03166000908152602091909152604090205460ff1690565b610e258282610dfc565b610e76576040805162461bcd60e51b815260206004820152601d60248201527f726f6c6520646f73656e2774206861766520746865206163636f756e74000000604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6000610ea2610a9e565b600180546001600160a01b0319166001600160a01b0385811691821790925560405192935091908316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080516001600160a01b039590951660208087019190915285820194909452600792830b90920b60608501526080808501919091528151808503909101815260a09093019052815191012090565b600061089c82610f5c565b6000610b218383610fad565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c8083019490945282518083039094018452605c909101909152815191012090565b60008151604114610fc05750600061089c565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115611006576000935050505061089c565b8060ff16601b1415801561101e57508060ff16601c14155b1561102f576000935050505061089c565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015611086573d6000803e3d6000fd5b5050604051601f19015197965050505050505056fea265627a7a72315820d7c43281c7654bf9a04d1757ef39c46f7a260c80b73af7dcb6b2134da0f0eeba64736f6c63430005110032

Verified Source Code Partial Match

Compiler: v0.5.17+commit.d19bba13 EVM: istanbul Optimization: Yes (200 runs)
MCHPrimeV2.sol 341 lines
// Copyright (c) 2018-2020 double jump.tokyo
pragma solidity 0.5.17;

interface IERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

/// @title ERC-165 Standard Interface Detection
/// @dev See https://eips.ethereum.org/EIPS/eip-165
contract ERC165 is IERC165 {
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * NOTE: This call _does not revert_ if the signature is invalid, or
     * if the signer is otherwise unable to be retrieved. In those scenarios,
     * the zero address is returned.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(signature, 0x20))
            s := mload(add(signature, 0x40))
            v := byte(0, mload(add(signature, 0x60)))
        }

        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return address(0);
        }

        if (v != 27 && v != 28) {
            return address(0);
        }

        // If the signature is valid (and not malleable), return the signer address
        return ecrecover(hash, v, r, s);
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * replicates the behavior of the
     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
     * JSON-RPC method.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }
}

library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    function add(Role storage role, address account) internal {
        require(!has(role, account), "role already has the account");
        role.bearer[account] = true;
    }

    function remove(Role storage role, address account) internal {
        require(has(role, account), "role dosen't have the account");
        role.bearer[account] = false;
    }

    function has(Role storage role, address account) internal view returns (bool) {
        return role.bearer[account];
    }
}

contract Withdrawable {
    using Roles for Roles.Role;

    event WithdrawerAdded(address indexed account);
    event WithdrawerRemoved(address indexed account);

    Roles.Role private withdrawers;

    constructor() public {
        withdrawers.add(msg.sender);
    }

    modifier onlyWithdrawer() {
        require(isWithdrawer(msg.sender), "Must be withdrawer");
        _;
    }

    function isWithdrawer(address account) public view returns (bool) {
        return withdrawers.has(account);
    }

    function addWithdrawer(address account) public onlyWithdrawer() {
        withdrawers.add(account);
        emit WithdrawerAdded(account);
    }

    function removeWithdrawer(address account) public onlyWithdrawer() {
        withdrawers.remove(account);
        emit WithdrawerRemoved(account);
    }

    function withdrawEther() public onlyWithdrawer() {
        msg.sender.transfer(address(this).balance);
    }

}

interface IERC173 /* is ERC165 */ {
    /// @dev This emits when ownership of a contract changes.
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Get the address of the owner
    /// @return The address of the owner.
    function owner() external view returns (address);

    /// @notice Set the address of the new owner of the contract
    /// @param _newOwner The address of the new owner of the contract
    function transferOwnership(address _newOwner) external;
}

contract ERC173 is IERC173, ERC165  {
    address private _owner;

    constructor() public {
        _registerInterface(0x7f5828d0);
        _transferOwnership(msg.sender);
    }

    modifier onlyOwner() {
        require(msg.sender == owner(), "Must be owner");
        _;
    }

    function owner() public view returns (address) {
        return _owner;
    }

    function transferOwnership(address _newOwner) public onlyOwner() {
        _transferOwnership(_newOwner);
    }

    function _transferOwnership(address _newOwner) internal {
        address previousOwner = owner();
	_owner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }
}

contract Operatable is ERC173 {
    using Roles for Roles.Role;

    event OperatorAdded(address indexed account);
    event OperatorRemoved(address indexed account);

    event Paused(address account);
    event Unpaused(address account);

    bool private _paused;
    Roles.Role private operators;

    constructor() public {
        operators.add(msg.sender);
        _paused = false;
    }

    modifier onlyOperator() {
        require(isOperator(msg.sender), "Must be operator");
        _;
    }

    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    function transferOwnership(address _newOwner) public onlyOperator() {
        _transferOwnership(_newOwner);
    }

    function isOperator(address account) public view returns (bool) {
        return operators.has(account);
    }

    function addOperator(address account) public onlyOperator() {
        operators.add(account);
        emit OperatorAdded(account);
    }

    function removeOperator(address account) public onlyOperator() {
        operators.remove(account);
        emit OperatorRemoved(account);
    }

    function paused() public view returns (bool) {
        return _paused;
    }

    function pause() public onlyOperator() whenNotPaused() {
        _paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyOperator() whenPaused() {
        _paused = false;
        emit Unpaused(msg.sender);
    }

}

contract MCHPrimeV2 is Operatable,Withdrawable {

    address public validator;
    mapping (address => uint256) public lastSignedBlock;
    uint256 ableToBuyAfterRange;
    uint256 sigExpireBlock;

    event BuyPrimeRight(
        address indexed buyer,
        uint256 signedBlock,
        int64 signedAt
    );

    constructor(address _varidator) public {
        setValidater(_varidator);
        setBlockRanges(20000, 10000);
    }

    function setValidater(address _varidator) public onlyOperator() {
        validator = _varidator;
    }

    function setBlockRanges(uint256 _ableToBuyAfterRange, uint256 _sigExpireBlock) public onlyOperator() {
        ableToBuyAfterRange = _ableToBuyAfterRange;
        sigExpireBlock = _sigExpireBlock;
    }

    function isApplicableNow() public view returns (bool) {
        isApplicable(msg.sender, block.number, block.number);
    }

    function isApplicable(address _buyer, uint256 _blockNum, uint256 _currentBlock) public view returns (bool) {
        if (lastSignedBlock[_buyer] != 0) {
            if (_blockNum < lastSignedBlock[_buyer] + ableToBuyAfterRange) {
                return false;
            }
        }

        if (_blockNum >= _currentBlock + sigExpireBlock) {
            return false;
        }
        return true;
    }

    function buyPrimeRight(bytes calldata _signature, uint256 _blockNum, int64 _signedAt) external payable whenNotPaused() {
        require(isApplicable(msg.sender, _blockNum, block.number), "block num error");
        require(validateSig(msg.sender, _blockNum, _signedAt, msg.value, _signature), "invalid signature");
        lastSignedBlock[msg.sender] = _blockNum;
        emit BuyPrimeRight(msg.sender, _blockNum, _signedAt);
    }

    function validateSig(address _from, uint256 _blockNum, int64 _signedAt, uint256 _priceWei, bytes memory _signature) internal view returns (bool) {
        require(validator != address(0));
        address signer = recover(ethSignedMessageHash(encodeData(_from, _blockNum, _signedAt, _priceWei)), _signature);
        return (signer == validator);
    }

    function encodeData(address _from, uint256 _blockNum, int64 _signedAt, uint256 _priceWei) internal pure returns (bytes32) {
        return keccak256(abi.encode(
                                _from,
                                _blockNum,
                                _signedAt,
                                _priceWei
                                )
                     );
    }

    function ethSignedMessageHash(bytes32 _data) internal pure returns (bytes32) {
        return ECDSA.toEthSignedMessageHash(_data);
    }

    function recover(bytes32 _data, bytes memory _signature) internal pure returns (address) {
        return ECDSA.recover(_data, _signature);
    }
}

Read Contract

isApplicable 0x97e08275 → bool
isApplicableNow 0xfe6b2f10 → bool
isOperator 0x6d70f7ae → bool
isWithdrawer 0x9004e5c5 → bool
lastSignedBlock 0x4fadb5b1 → uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
supportsInterface 0x01ffc9a7 → bool
validator 0x3a5381b5 → address

Write Contract 11 functions

These functions modify contract state and require a wallet transaction to execute.

addOperator 0x9870d7fe
address account
addWithdrawer 0x56788a8c
address account
buyPrimeRight 0x16aa2b98
bytes _signature
uint256 _blockNum
int64 _signedAt
pause 0x8456cb59
No parameters
removeOperator 0xac8a584a
address account
removeWithdrawer 0x711bd9eb
address account
setBlockRanges 0x299bb1e9
uint256 _ableToBuyAfterRange
uint256 _sigExpireBlock
setValidater 0xc14e50ce
address _varidator
transferOwnership 0xf2fde38b
address _newOwner
unpause 0x3f4ba83a
No parameters
withdrawEther 0x7362377b
No parameters

Top Interactions

Recent Transactions

CSV
|
Hash Method Block Age From/To Value Txn Fee Type
0xd0760529...3ee942 0x16aa2b98 24,321,770 IN 0x46840649...8c8e 0.001700 ETH 0.000097196349 ETH EIP-1559
0x42f818d9...e29d15 0x16aa2b98 24,312,864 IN 0xE9C6F465...6a39 0.001700 ETH 0.000217490000 ETH EIP-1559
0x00838dc7...c49b17 0x16aa2b98 10,729,264 IN 0xC5A32813...067a 0.100000 ETH 0.00345122 ETH Legacy
0xf4a01cef...6d83f8 0x16aa2b98 10,729,110 IN 0x5C4bCa8F...bbf0 0.100000 ETH 0.00516496 ETH Legacy
0x8d1e2271...fa989d 0x16aa2b98 10,701,702 IN 0x68d15507...192F 0.100000 ETH 0.00538705 ETH Legacy