Contract 0x19a9532d072688de19eec64b8c8b32d726ec801d

Contract Overview

Balance:
0 BNB
Txn Hash
Block
From
To
Value [Txn Fee]
0x21d48fde95cbfc165d4b77ab71a71b0b5e3f9be6a58ea4dfe84b130e2dc151fa91506482021-05-25 12:32:3321 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0x69ff1a6eef3548d08d0d19aa4ab9db712e37aebc5841dfc25c811d8e972158bc91506252021-05-25 12:31:2421 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x2c2223d60ef90a67f22e183c93dc27d3aaa33331b60855aad47bf2efec57dad691506012021-05-25 12:30:1221 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0x3bf31fce0ddf8dc8a3a3744f5ad930e99c5fe9fac2ffbd13c68f31146904b8b391505772021-05-25 12:29:0021 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0xf8d2c075e4abdc52b5131daebfebdd2b0d1688c330686f0306625477a40f39d091505532021-05-25 12:27:4821 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x773a80d16ea36e844527544c545460158fbb10f16c181c31ab54820e6393eea991505302021-05-25 12:26:3921 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0xffb20bc41f9d5352680eb1a92354e174325e3d56c32b4e593c727ceda7728e0091505062021-05-25 12:25:2721 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0x3a5d47795eb8191a1942ea077ba10eb2cdf83e66b43fda1912d6120d4188d44991504822021-05-25 12:24:1521 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0xc770c30027bfa85a9430add168a189860d62c4c74fe12c084a79b1eb575095ef91504582021-05-25 12:23:0321 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0x0eaf202184ca44de0c0cfcf8f20a9af23f7d8ae2cc24a28315699022ebca43d091504352021-05-25 12:21:5421 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0xb79d00030f2fab01a602441837a3732139819e136094aec229e9218729fcdb5791504122021-05-25 12:20:4521 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x09d4d34685f81f4838fbc62d6347eadba39c729e2a41b4f3878d07a65031ffc191503882021-05-25 12:19:3321 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0xc1920608673007ef7f018633bd923c684798e3b53fd259a1d8cff61aefde147291503652021-05-25 12:18:2421 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x36edd64dba773be07e52d39594f0b058fb39ae727a11d7877eaf200082fe17a291503402021-05-25 12:17:0921 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0xb167091198f96d4ca17beba5e8e498026d845aceb505b33ee8621ef45fd7eec391503172021-05-25 12:16:0021 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x1ac7f9a5ff553e7d886d4cb724793f91d3b07c47fed8e7c4dc14dc20ac98f4b791502932021-05-25 12:14:4821 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526353
0xc51dd9ad2af400e3e7869b8fef9f675080717310af91111dc554bf5144d4eaac91502702021-05-25 12:13:3921 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x82bbfc2857c4d1b3dd97f54aa9ad268e26faf5a399b458f7bdc54ba9fa8939be91502472021-05-25 12:12:3021 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0xf326d67ad17dfdf3105c8c31c14c346811ff04eac2177d2ef7f4665a99b5bb3691502232021-05-25 12:11:1821 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0x509de386fdf26fb92a29ce382f21be74290a9ba42b78f3fdced21a241e54cc4291502002021-05-25 12:10:0921 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0x8ed985cbccc6b2844bca1d9037123adaa9dbe1d957e6019e561b79ded9813b5991501762021-05-25 12:08:5721 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x6e536743e979113dbff08d99ae45cf28eafc067601590d986c3231bc481c683791501532021-05-25 12:07:4821 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0x6896b389120268f46e59a9922e5bb21b29b577d0f5df3422d52b422a5393c98e91501302021-05-25 12:06:3921 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
0x7bd82a60c3e3093789b5a071144d9f3d0b9a735601ae074dc35f581d53e3b6c091501052021-05-25 12:05:2421 days 4 hrs ago0x5a63f396933c6b63344b81745f9882b32070135d IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526377
0xd1b562a9455b88a5cf3e979cca1a4d40dd9699b8641f21741d64bb48fec714cf91500822021-05-25 12:04:1521 days 4 hrs ago0xd06ba784994088db12b8df1df59c571d15d9c03a IN  0x19a9532d072688de19eec64b8c8b32d726ec801d0 BNB0.00526365
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x21d48fde95cbfc165d4b77ab71a71b0b5e3f9be6a58ea4dfe84b130e2dc151fa91506482021-05-25 12:32:3321 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x21d48fde95cbfc165d4b77ab71a71b0b5e3f9be6a58ea4dfe84b130e2dc151fa91506482021-05-25 12:32:3321 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x21d48fde95cbfc165d4b77ab71a71b0b5e3f9be6a58ea4dfe84b130e2dc151fa91506482021-05-25 12:32:3321 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x21d48fde95cbfc165d4b77ab71a71b0b5e3f9be6a58ea4dfe84b130e2dc151fa91506482021-05-25 12:32:3321 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0x69ff1a6eef3548d08d0d19aa4ab9db712e37aebc5841dfc25c811d8e972158bc91506252021-05-25 12:31:2421 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x69ff1a6eef3548d08d0d19aa4ab9db712e37aebc5841dfc25c811d8e972158bc91506252021-05-25 12:31:2421 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x69ff1a6eef3548d08d0d19aa4ab9db712e37aebc5841dfc25c811d8e972158bc91506252021-05-25 12:31:2421 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x69ff1a6eef3548d08d0d19aa4ab9db712e37aebc5841dfc25c811d8e972158bc91506252021-05-25 12:31:2421 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0x2c2223d60ef90a67f22e183c93dc27d3aaa33331b60855aad47bf2efec57dad691506012021-05-25 12:30:1221 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x2c2223d60ef90a67f22e183c93dc27d3aaa33331b60855aad47bf2efec57dad691506012021-05-25 12:30:1221 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x2c2223d60ef90a67f22e183c93dc27d3aaa33331b60855aad47bf2efec57dad691506012021-05-25 12:30:1221 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x2c2223d60ef90a67f22e183c93dc27d3aaa33331b60855aad47bf2efec57dad691506012021-05-25 12:30:1221 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0x3bf31fce0ddf8dc8a3a3744f5ad930e99c5fe9fac2ffbd13c68f31146904b8b391505772021-05-25 12:29:0021 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x3bf31fce0ddf8dc8a3a3744f5ad930e99c5fe9fac2ffbd13c68f31146904b8b391505772021-05-25 12:29:0021 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x3bf31fce0ddf8dc8a3a3744f5ad930e99c5fe9fac2ffbd13c68f31146904b8b391505772021-05-25 12:29:0021 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x3bf31fce0ddf8dc8a3a3744f5ad930e99c5fe9fac2ffbd13c68f31146904b8b391505772021-05-25 12:29:0021 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0xf8d2c075e4abdc52b5131daebfebdd2b0d1688c330686f0306625477a40f39d091505532021-05-25 12:27:4821 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0xf8d2c075e4abdc52b5131daebfebdd2b0d1688c330686f0306625477a40f39d091505532021-05-25 12:27:4821 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0xf8d2c075e4abdc52b5131daebfebdd2b0d1688c330686f0306625477a40f39d091505532021-05-25 12:27:4821 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0xf8d2c075e4abdc52b5131daebfebdd2b0d1688c330686f0306625477a40f39d091505532021-05-25 12:27:4821 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0x773a80d16ea36e844527544c545460158fbb10f16c181c31ab54820e6393eea991505302021-05-25 12:26:3921 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x773a80d16ea36e844527544c545460158fbb10f16c181c31ab54820e6393eea991505302021-05-25 12:26:3921 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x773a80d16ea36e844527544c545460158fbb10f16c181c31ab54820e6393eea991505302021-05-25 12:26:3921 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
0x773a80d16ea36e844527544c545460158fbb10f16c181c31ab54820e6393eea991505302021-05-25 12:26:3921 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x3508848650bb8ea55390faeefa13312cb4d87e1d0 BNB
0xffb20bc41f9d5352680eb1a92354e174325e3d56c32b4e593c727ceda7728e0091505062021-05-25 12:25:2721 days 4 hrs ago 0x19a9532d072688de19eec64b8c8b32d726ec801d 0x7fdc96e73c82c42e7bbc5404f43f37b556795e860 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Chain

Compiler Version
v0.6.8+commit.0bbfe453

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-04-27
*/

// File: @openzeppelin/contracts/math/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

// File: @openzeppelin/contracts/utils/ReentrancyGuard.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

// File: @openzeppelin/contracts/cryptography/MerkleProof.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev These functions deal with verification of Merkle trees (hash trees),
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/lib/LeafDecoder.sol

pragma solidity 0.6.8;


library LeafDecoder {
  using SafeMath for uint256;

  function leafToUint(bytes memory _leafBytes) internal pure returns (uint256 number) {
    uint length = _leafBytes.length;
    require(length >= 2, "invalid leaf bytes - missing type metadata");
    require(_leafBytes[length - 2] == 0xFF, "invalid leaf - missing type marker");
    require(_leafBytes[length - 1] == 0x02, "invalid leaf - invalid type - expect 02:int");

    if (length == 2) {
      return 0;
    }

    length -= 2;

    for(uint i = 0; i < length; i++) {
      number = number + uint(uint8(_leafBytes[i])) * (2**(8*(length-(i+1))));
    }

    return number;
  }

  function leafTo18DecimalsFloat(bytes memory _leafBytes) internal pure returns (uint256 float){
    uint length = _leafBytes.length;
    require(length >= 3, "invalid leaf bytes - missing type metadata");
    require(_leafBytes[length - 2] == 0xFF, "invalid leaf - missing type marker");
    require(_leafBytes[length - 1] == 0x03, "invalid leaf - invalid type - expect 03:float");

    if (length == 3) {
      return 0;
    }

    uint power = 18;

    if (_leafBytes[length - 3] != 0xee) {
      require(length >= 4, "invalid leaf bytes - missing type metadata");

      power = 18 - uint(uint8(_leafBytes[length - 3]));
      length -= 4;
    } else {
      length -= 3;
    }

    for(uint i = 0; i < length; i++) {
      float = float + uint(uint8(_leafBytes[i])) * (2**(8*(length-(i+1))));
    }

    return float.mul(10 ** power);
  }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: contracts/interfaces/IStakingBank.sol

pragma solidity ^0.6.8;


interface IStakingBank is IERC20 {
  function receiveApproval(address _from) external returns (bool success);

  function withdraw(uint256 _value) external returns (bool success);
}

// File: contracts/interfaces/IValidatorRegistry.sol

pragma solidity ^0.6.8;

interface IValidatorRegistry {
  function create(address _id, string calldata _location) external;

  function update(address _id, string calldata _location) external;

  function addresses(uint256 _ix) external view returns (address);

  function validators(address _id) external view returns (address id, string memory location);

  function getNumberOfValidators() external view returns (uint256);

  function getName() external pure returns (bytes32);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


pragma solidity >=0.6.0 <0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal virtual {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

// File: contracts/interfaces/IRegistry.sol

pragma solidity 0.6.8;


interface IRegistry {
    function getAddress(bytes32 name) external view returns (address);

    function requireAndGetAddress(bytes32 name) external view returns (address);
}

// File: contracts/extensions/Registrable.sol

pragma solidity 0.6.8;





abstract contract Registrable {
  IRegistry public contractRegistry;

  // ========== CONSTRUCTOR ========== //

  constructor(address _contractRegistry) internal {
    require(_contractRegistry != address(0x0), "_registry is empty");
    contractRegistry = IRegistry(_contractRegistry);
  }

  // ========== MODIFIERS ========== //

  modifier onlyFromContract(address _msgSender, bytes32 _contractName) {
    require(
      contractRegistry.getAddress(_contractName) == _msgSender,
        string(abi.encodePacked("caller is not ", _contractName))
    );
    _;
  }

  modifier withRegistrySetUp() {
    require(address(contractRegistry) != address(0x0), "_registry is empty");
    _;
  }

  // ========== VIEWS ========== //

  function getName() virtual external pure returns (bytes32);

  function validatorRegistryContract() public view returns (IValidatorRegistry) {
    return IValidatorRegistry(contractRegistry.requireAndGetAddress("ValidatorRegistry"));
  }

  function stakingBankContract() public view returns (IStakingBank) {
    return IStakingBank(contractRegistry.requireAndGetAddress("StakingBank"));
  }

  function tokenContract() public view withRegistrySetUp returns (ERC20) {
    return ERC20(contractRegistry.requireAndGetAddress("UMB"));
  }
}

// File: contracts/Registry.sol

pragma solidity 0.6.8;

// Inheritance



contract Registry is Ownable {
  mapping(bytes32 => address) public registry;

  // ========== EVENTS ========== //

  event LogRegistered(address indexed destination, bytes32 name);

  // ========== MUTATIVE FUNCTIONS ========== //

  function importAddresses(bytes32[] calldata _names, address[] calldata _destinations) external onlyOwner {
    require(_names.length == _destinations.length, "Input lengths must match");

    for (uint i = 0; i < _names.length; i++) {
      registry[_names[i]] = _destinations[i];
      emit LogRegistered(_destinations[i], _names[i]);
    }
  }

  function importContracts(address[] calldata _destinations) external onlyOwner {
    for (uint i = 0; i < _destinations.length; i++) {
      bytes32 name = Registrable(_destinations[i]).getName();
      registry[name] = _destinations[i];
      emit LogRegistered(_destinations[i], name);
    }
  }

  // ========== VIEWS ========== //

  function requireAndGetAddress(bytes32 name) external view returns (address) {
    address _foundAddress = registry[name];
    require(_foundAddress != address(0), string(abi.encodePacked("Name not registered: ", name)));
    return _foundAddress;
  }

  function getAddress(bytes32 _bytes) external view returns (address) {
    return registry[_bytes];
  }

  function getAddressByString(string memory _name) public view returns (address) {
    return registry[stringToBytes32(_name)];
  }

  function stringToBytes32(string memory _string) public pure returns (bytes32 result) {
    bytes memory tempEmptyStringTest = bytes(_string);

    if (tempEmptyStringTest.length == 0) {
      return 0x0;
    }

    assembly {
      result := mload(add(_string, 32))
    }
  }
}

// File: contracts/Chain.sol

pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;










contract Chain is ReentrancyGuard, Registrable, Ownable {
  using SafeMath for uint256;
  using LeafDecoder for bytes;

  // ========== STATE VARIABLES ========== //

  uint256 public blockPadding;

  bytes constant public ETH_PREFIX = "\x19Ethereum Signed Message:\n32";

  struct Block {
    bytes32 root;
    address minter;
    uint256 staked;
    uint256 power;
    uint256 anchor;
    uint256 timestamp;
    uint256 dataTimestamp;
  }

  struct ExtendedBlock {
    Block data;
    address[] voters;
    mapping(address => uint256) votes;
    mapping(bytes32 => uint256) numericFCD;
  }

  mapping(uint256 => ExtendedBlock) public blocks;

  uint256 public blocksCount;
  uint256 public blocksCountOffset;

  // ========== CONSTRUCTOR ========== //

  constructor(address _contractRegistry, uint256 _blockPadding) public Registrable(_contractRegistry) {
    blockPadding = _blockPadding;

    Chain oldChain = Chain(Registry(_contractRegistry).getAddress("Chain"));

    if (address(oldChain) != address(0x0)) {
      // +1 because it might be situation when tx is already in progress in old contract
      blocksCountOffset = oldChain.blocksCount() + oldChain.blocksCountOffset() + 1;
    }
  }

  // ========== MUTATIVE FUNCTIONS ========== //

  function setBlockPadding(uint256 _blockPadding) external onlyOwner {
    blockPadding = _blockPadding;
    emit LogBlockPadding(msg.sender, _blockPadding);
  }

  function submit(
    uint256 _dataTimestamp,
    bytes32 _root,
    bytes32[] memory _keys,
    uint256[] memory _values,
    uint8[] memory _v,
    bytes32[] memory _r,
    bytes32[] memory _s
  ) public nonReentrant returns (bool) {
    uint256 blockHeight = getBlockHeight();
    require(blocks[blockHeight].data.anchor == 0, "block already mined for current blockHeight");
    // in future we can add timePadding and remove blockPadding
    require(blocks[blockHeight - 1].data.dataTimestamp < _dataTimestamp, "can NOT submit older data");

    bytes memory testimony = abi.encodePacked(blockHeight, _dataTimestamp, _root);

    require(_keys.length == _values.length, "numbers of keys and values not the same");

    for (uint256 i = 0; i < _keys.length; i++) {
      blocks[blockHeight].numericFCD[_keys[i]] = _values[i];
      testimony = abi.encodePacked(testimony, _keys[i], _values[i]);
    }

    bytes32 affidavit = keccak256(testimony);

    (blocks[blockHeight].data.staked, blocks[blockHeight].data.power) =
      _validateSignatures(blockHeight, affidavit, _v, _r, _s);

    blocks[blockHeight].data.root = _root;
    blocks[blockHeight].data.minter = msg.sender; //TODO check if validator is registered
    blocks[blockHeight].data.anchor = block.number;
    blocks[blockHeight].data.timestamp = block.timestamp;
    blocks[blockHeight].data.dataTimestamp = _dataTimestamp;

    blocksCount++;

    emit LogMint(msg.sender, blockHeight, block.number);

    return true;
  }

  function _validateSignatures(
    uint256 _blockHeight,
    bytes32 _affidavit,
    uint8[] memory _v,
    bytes32[] memory _r,
    bytes32[] memory _s
  ) internal returns (uint256 staked, uint256 power){
    IStakingBank stakingBank = stakingBankContract();
    staked = stakingBank.totalSupply();

    power = 0;

    for (uint256 i = 0; i < _v.length; i++) {
      address signer = recoverSigner(_affidavit, _v[i], _r[i], _s[i]);
      uint256 balance = stakingBank.balanceOf(signer);
      require(blocks[_blockHeight].votes[signer] == 0, "validator included more than once");

      if (balance == 0) {
        // if no balance -> move on, it can be invalid address but also fresh validator with no balance
        // we can spend gas and check if address is validator address, but I see no point, its cheaper to ignore
        // if we calculated root for other blockHeight, then recovering signer will not work -> move on
        continue;
      }

      blocks[_blockHeight].voters.push(signer);
      blocks[_blockHeight].votes[signer] = balance;
      power = power.add(balance);
    }

    require(power.mul(100) > staked.mul(66), "not enough power was gathered");
  }

  // ========== VIEWS ========== //

  function getName() override external pure returns (bytes32) {
    return "Chain";
  }

  function recoverSigner(bytes32 affidavit, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
    bytes32 hash = keccak256(abi.encodePacked(ETH_PREFIX, affidavit));
    return ecrecover(hash, _v, _r, _s);
  }

  function getStatus() external view returns(
    uint256 blockNumber,
    uint256 lastDataTimestamp,
    uint256 lastBlockHeight,
    address nextLeader,
    uint256 nextBlockHeight,
    address[] memory validators,
    uint256[] memory powers,
    string[] memory locations,
    uint256 staked
  ) {
    blockNumber = block.number;
    lastBlockHeight = getLatestBlockHeightWithData();
    lastDataTimestamp = blocks[lastBlockHeight].data.dataTimestamp;

    IValidatorRegistry vr = validatorRegistryContract();
    uint256 numberOfValidators = vr.getNumberOfValidators();
    validators = new address[](numberOfValidators);
    locations = new string[](numberOfValidators);

    for (uint256 i = 0; i < numberOfValidators; i++) {
      validators[i] = vr.addresses(i);
      (, locations[i]) = vr.validators(validators[i]);
    }

    nextLeader = numberOfValidators > 0 ? validators[getLeaderIndex(numberOfValidators, blockNumber + 1)] : address(0);

    IStakingBank stakingBank = stakingBankContract();
    powers = new uint256[](numberOfValidators);
    staked = stakingBank.totalSupply();

    for (uint256 i = 0; i < numberOfValidators; i++) {
      powers[i] = stakingBank.balanceOf(validators[i]);
    }

    nextBlockHeight = getBlockHeightForBlock(blockNumber + 1);
  }

  function getBlockHeight() public view returns (uint256) {
    return getBlockHeightForBlock(block.number);
  }

  function getBlockHeightForBlock(uint256 _ethBlockNumber) public view returns (uint256) {
    uint _blocksCount = blocksCount + blocksCountOffset;

    if (_blocksCount == 0) {
      return 0;
    }

    return (blocks[_blocksCount - 1].data.anchor + blockPadding < _ethBlockNumber)
      ? _blocksCount
      : _blocksCount - 1;
  }

  function getLatestBlockHeightWithData() public view returns (uint256) {
    return blocksCount + blocksCountOffset - 1;
  }

  function getLeaderIndex(uint256 numberOfValidators, uint256 ethBlockNumber) public view returns (uint256) {
    uint256 latestBlockHeight = getLatestBlockHeightWithData();

    // blockPadding + 1 => because padding is a space between blocks, so next round starts on first block after padding
    uint256 validatorIndex = latestBlockHeight +
      (ethBlockNumber - blocks[latestBlockHeight].data.anchor) / (blockPadding + 1);

    return validatorIndex % numberOfValidators;
  }

  function getNextLeaderAddress() public view returns (address) {
    return getLeaderAddressAtBlock(block.number + 1);
  }

  function getLeaderAddress() public view returns (address) {
    return getLeaderAddressAtBlock(block.number);
  }

  // @todo - properly handled non-enabled validators, newly added validators, and validators with low stake
  function getLeaderAddressAtBlock(uint256 ethBlockNumber) public view returns (address) {
    IValidatorRegistry validatorRegistry = validatorRegistryContract();

    uint256 numberOfValidators = validatorRegistry.getNumberOfValidators();

    if (numberOfValidators == 0) {
      return address(0x0);
    }

    uint256 validatorIndex = getLeaderIndex(numberOfValidators, ethBlockNumber);

    return validatorRegistry.addresses(validatorIndex);
  }

  function verifyProof(bytes32[] memory _proof, bytes32 _root, bytes32 _leaf) public pure returns (bool) {
    if (_root == bytes32(0)) {
      return false;
    }

    return MerkleProof.verify(_proof, _root, _leaf);
  }

  function hashLeaf(bytes memory _key, bytes memory _value) public pure returns (bytes32) {
    return keccak256(abi.encodePacked(_key, _value));
  }

  function verifyProofForBlock(
    uint256 _blockHeight,
    bytes32[] memory _proof,
    bytes memory _key,
    bytes memory _value
  ) public view returns (bool) {
    return verifyProof(_proof, blocks[_blockHeight].data.root, hashLeaf(_key, _value));
  }

  function bytesToBytes32Array(
    bytes memory _data,
    uint256 _offset,
    uint256 _items
  ) public pure returns (bytes32[] memory) {
    bytes32[] memory dataList = new bytes32[](_items);

    for (uint256 i = 0; i < _items; i++) {
      bytes32 temp;
      uint256 idx = (i + 1 + _offset) * 32;

      assembly {
        temp := mload(add(_data, idx))
      }

      dataList[i] = temp;
    }

    return (dataList);
  }

  function verifyProofs(
    uint256[] memory _blockHeights,
    bytes memory _proofs,
    uint256[] memory _proofItemsCounter,
    bytes32[] memory _leaves
  ) public view returns (bool[] memory results) {
    results = new bool[](_leaves.length);
    uint256 offset = 0;

    for (uint256 i = 0; i < _leaves.length; i++) {
      results[i] = verifyProof(
        bytesToBytes32Array(_proofs, offset, _proofItemsCounter[i]),
        blocks[_blockHeights[i]].data.root,
        _leaves[i]
      );

      offset += _proofItemsCounter[i];
    }
  }

  function decodeLeafToNumber(bytes memory _leaf) public pure returns (uint) {
    return _leaf.leafToUint();
  }

  function decodeLeafToFloat(bytes memory _leaf) public pure returns (uint) {
    return _leaf.leafTo18DecimalsFloat();
  }

  function verifyProofForBlockForNumber(
    uint256 _blockHeight,
    bytes32[] memory _proof,
    bytes memory _key,
    bytes memory _value
  ) public view returns (bool, uint256) {
    return (verifyProof(_proof, blocks[_blockHeight].data.root, hashLeaf(_key, _value)), _value.leafToUint());
  }

  function verifyProofForBlockForFloat(
    uint256 _blockHeight,
    bytes32[] memory _proof,
    bytes memory _key,
    bytes memory _value
  ) public view returns (bool, uint256) {
    return (
      verifyProof(_proof, blocks[_blockHeight].data.root, hashLeaf(_key, _value)),
      _value.leafTo18DecimalsFloat()
    );
  }

  function getBlockData(uint256 _blockHeight) external view returns (Block memory) {
    return blocks[_blockHeight].data;
  }

  function getBlockRoot(uint256 _blockHeight) external view returns (bytes32) {
    return blocks[_blockHeight].data.root;
  }

  function getBlockMinter(uint256 _blockHeight) external view returns (address) {
    return blocks[_blockHeight].data.minter;
  }

  function getBlockStaked(uint256 _blockHeight) external view returns (uint256) {
    return blocks[_blockHeight].data.staked;
  }

  function getBlockPower(uint256 _blockHeight) external view returns (uint256) {
    return blocks[_blockHeight].data.power;
  }

  function getBlockAnchor(uint256 _blockHeight) external view returns (uint256) {
    return blocks[_blockHeight].data.anchor;
  }

  function getBlockTimestamp(uint256 _blockHeight) external view returns (uint256) {
    return blocks[_blockHeight].data.timestamp;
  }

  function getBlockVotersCount(uint256 _blockHeight) external view returns (uint256) {
    return blocks[_blockHeight].voters.length;
  }

  function getBlockVoters(uint256 _blockHeight) external view returns (address[] memory) {
    return blocks[_blockHeight].voters;
  }

  function getBlockVotes(uint256 _blockHeight, address _voter) external view returns (uint256) {
    return blocks[_blockHeight].votes[_voter];
  }

  function getNumericFCD(uint256 _blockHeight, bytes32 _key) public view returns (uint256 value, uint timestamp) {
    ExtendedBlock storage extendedBlock = blocks[_blockHeight];
    return (extendedBlock.numericFCD[_key], extendedBlock.data.timestamp);
  }

  function getNumericFCDs(
    uint256 _blockHeight, bytes32[] calldata _keys
  ) external view returns (uint256[] memory values, uint256 timestamp) {
    timestamp = blocks[_blockHeight].data.timestamp;
    values = new uint256[](_keys.length);

    for (uint i=0; i<_keys.length; i++) {
      values[i] = blocks[_blockHeight].numericFCD[_keys[i]];
    }
  }

  function getCurrentValue(bytes32 _key) external view returns (uint256 value, uint timestamp) {
    // it will revert when no blocks
    return getNumericFCD(getLatestBlockHeightWithData(), _key);
  }

  // ========== EVENTS ========== //

  event LogMint(address indexed minter, uint256 blockHeight, uint256 anchor);
  event LogBlockPadding(address indexed executor, uint256 blockPadding);
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_contractRegistry","type":"address"},{"internalType":"uint256","name":"_blockPadding","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockPadding","type":"uint256"}],"name":"LogBlockPadding","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockHeight","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"anchor","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"ETH_PREFIX","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockPadding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blocks","outputs":[{"components":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"staked","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"uint256","name":"anchor","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"dataTimestamp","type":"uint256"}],"internalType":"struct Chain.Block","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksCountOffset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_items","type":"uint256"}],"name":"bytesToBytes32Array","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractRegistry","outputs":[{"internalType":"contract IRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_leaf","type":"bytes"}],"name":"decodeLeafToFloat","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_leaf","type":"bytes"}],"name":"decodeLeafToNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockAnchor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockData","outputs":[{"components":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint256","name":"staked","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"uint256","name":"anchor","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"dataTimestamp","type":"uint256"}],"internalType":"struct Chain.Block","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethBlockNumber","type":"uint256"}],"name":"getBlockHeightForBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockMinter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockVoters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"}],"name":"getBlockVotersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"address","name":"_voter","type":"address"}],"name":"getBlockVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getCurrentValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestBlockHeightWithData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLeaderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethBlockNumber","type":"uint256"}],"name":"getLeaderAddressAtBlock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfValidators","type":"uint256"},{"internalType":"uint256","name":"ethBlockNumber","type":"uint256"}],"name":"getLeaderIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getNextLeaderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getNumericFCD","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"bytes32[]","name":"_keys","type":"bytes32[]"}],"name":"getNumericFCDs","outputs":[{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatus","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"lastDataTimestamp","type":"uint256"},{"internalType":"uint256","name":"lastBlockHeight","type":"uint256"},{"internalType":"address","name":"nextLeader","type":"address"},{"internalType":"uint256","name":"nextBlockHeight","type":"uint256"},{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"string[]","name":"locations","type":"string[]"},{"internalType":"uint256","name":"staked","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"hashLeaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"affidavit","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"recoverSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockPadding","type":"uint256"}],"name":"setBlockPadding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingBankContract","outputs":[{"internalType":"contract IStakingBank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dataTimestamp","type":"uint256"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"bytes32[]","name":"_keys","type":"bytes32[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"}],"name":"submit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validatorRegistryContract","outputs":[{"internalType":"contract IValidatorRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"bytes32","name":"_leaf","type":"bytes32"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"verifyProofForBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"verifyProofForBlockForFloat","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockHeight","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"verifyProofForBlockForNumber","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_blockHeights","type":"uint256[]"},{"internalType":"bytes","name":"_proofs","type":"bytes"},{"internalType":"uint256[]","name":"_proofItemsCounter","type":"uint256[]"},{"internalType":"bytes32[]","name":"_leaves","type":"bytes32[]"}],"name":"verifyProofs","outputs":[{"internalType":"bool[]","name":"results","type":"bool[]"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620051b9380380620051b98339818101604052810190620000379190620003ed565b816001600081905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620000b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000aa90620004c2565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000620001076200038b60201b60201c565b905080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3508060038190555060008273ffffffffffffffffffffffffffffffffffffffff166321f8a7216040518163ffffffff1660e01b8152600401620001e890620004e4565b60206040518083038186803b1580156200020157600080fd5b505afa15801562000216573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023c9190620003c1565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614620003825760018173ffffffffffffffffffffffffffffffffffffffff166377839fe66040518163ffffffff1660e01b815260040160206040518083038186803b158015620002bc57600080fd5b505afa158015620002d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f791906200042e565b8273ffffffffffffffffffffffffffffffffffffffff16637353cbcb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200033e57600080fd5b505afa15801562000353573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200037991906200042e565b01016006819055505b50505062000582565b600033905090565b600081519050620003a4816200054e565b92915050565b600081519050620003bb8162000568565b92915050565b600060208284031215620003d457600080fd5b6000620003e48482850162000393565b91505092915050565b600080604083850312156200040157600080fd5b6000620004118582860162000393565b92505060206200042485828601620003aa565b9150509250929050565b6000602082840312156200044157600080fd5b60006200045184828501620003aa565b91505092915050565b600062000469601283620004ff565b91507f5f726567697374727920697320656d70747900000000000000000000000000006000830152602082019050919050565b7f436861696e000000000000000000000000000000000000000000000000000000815250565b60006020820190508181036000830152620004dd816200045a565b9050919050565b6000602082019050620004fa600083016200049c565b919050565b600082825260208201905092915050565b60006200051d8262000524565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b620005598162000510565b81146200056557600080fd5b50565b620005738162000544565b81146200057f57600080fd5b50565b614c2780620005926000396000f3fe608060405234801561001057600080fd5b506004361061028a5760003560e01c80637bb96acb1161015c578063c5349f8d116100ce578063e41a5d1711610087578063e41a5d17146108f7578063ed9975c314610927578063f25b3f9914610945578063f2fde38b14610975578063f365a46614610991578063ff5e5c41146109af5761028a565b8063c5349f8d146107fd578063c70391671461082d578063c8661e4b1461084b578063c8d648dc14610867578063ca4d29d214610897578063d45167d0146108c75761028a565b8063a09609b711610120578063a09609b7146106ee578063a8f3e0291461071e578063aa7a30a01461074e578063abf410e51461077e578063adf1639d1461079c578063b5a420d0146107cd5761028a565b80637bb96acb1461063457806384c30cc2146106525780638da5cb5b146106825780639e4b221a146106a05780639f6119d7146106d05761028a565b806347e26f1a11610200578063637180a8116101b9578063637180a81461056f5780636449fd531461058d578063712e4321146105bd578063715018a6146105ee5780637353cbcb146105f857806377839fe6146106165761028a565b806347e26f1a1461046a5780634bc935d71461049a5780634e69d560146104ca578063518bd3dd146104f0578063522e793f1461052057806355a373d6146105515761028a565b8063199dadc511610252578063199dadc51461035c5780631a4635ba1461038c5780631c9ab3ad146103bc578063243b68f9146103ec57806324c89a491461041c57806333410fd71461043a5761028a565b806307219f2b1461028f5780630f2acc3e146102ad578063122e3721146102dd57806317d7de7c1461030d578063190e92b41461032b575b600080fd5b6102976109e0565b6040516102a491906146eb565b60405180910390f35b6102c760048036038101906102c291906133d7565b6109e6565b6040516102d491906143b7565b60405180910390f35b6102f760048036038101906102f29190613396565b610a19565b60405161030491906146eb565b60405180910390f35b610315610a2b565b60405161032291906143b7565b60405180910390f35b61034560048036038101906103409190613590565b610a53565b60405161035392919061438e565b60405180910390f35b61037660048036038101906103719190613590565b610a99565b6040516103839190614373565b60405180910390f35b6103a660048036038101906103a191906134aa565b610ad2565b6040516103b391906142c2565b60405180910390f35b6103d660048036038101906103d191906134aa565b610b15565b6040516103e391906146d0565b60405180910390f35b61040660048036038101906104019190613443565b610bd7565b6040516104139190614321565b60405180910390f35b610424610c79565b6040516104319190614417565b60405180910390f35b610454600480360381019061044f9190613247565b610cb2565b60405161046191906142ff565b60405180910390f35b610484600480360381019061047f91906134aa565b610dc6565b60405161049191906146eb565b60405180910390f35b6104b460048036038101906104af91906131e0565b610de9565b6040516104c19190614373565b60405180910390f35b6104d2610e14565b6040516104e79998979695949392919061472f565b60405180910390f35b61050a600480360381019061050591906134aa565b611309565b60405161051791906146eb565b60405180910390f35b61053a60048036038101906105359190613538565b61132c565b604051610548929190614343565b60405180910390f35b610559611411565b6040516105669190614439565b60405180910390f35b610577611552565b604051610584919061446f565b60405180910390f35b6105a760048036038101906105a29190613677565b611602565b6040516105b49190614373565b60405180910390f35b6105d760048036038101906105d29190613590565b6119e6565b6040516105e592919061438e565b60405180910390f35b6105f6611a2c565b005b610600611b69565b60405161060d91906146eb565b60405180910390f35b61061e611b6f565b60405161062b91906146eb565b60405180910390f35b61063c611b75565b60405161064991906146eb565b60405180910390f35b61066c600480360381019061066791906134fc565b611b85565b60405161067991906146eb565b60405180910390f35b61068a611be3565b60405161069791906142c2565b60405180910390f35b6106ba60048036038101906106b591906134aa565b611c0d565b6040516106c791906146eb565b60405180910390f35b6106d8611c67565b6040516106e591906142c2565b60405180910390f35b610708600480360381019061070391906134aa565b611c7a565b60405161071591906142c2565b60405180910390f35b610738600480360381019061073391906134aa565b611dbf565b60405161074591906146eb565b60405180910390f35b610768600480360381019061076391906134aa565b611de2565b60405161077591906146eb565b60405180910390f35b610786611e05565b6040516107939190614454565b60405180910390f35b6107b660048036038101906107b1919061330a565b611e2b565b6040516107c4929190614706565b60405180910390f35b6107e760048036038101906107e291906134aa565b611e48565b6040516107f491906142dd565b60405180910390f35b610817600480360381019061081291906134aa565b611eec565b60405161082491906146eb565b60405180910390f35b610835611f0f565b604051610842919061448a565b60405180910390f35b610865600480360381019061086091906134aa565b611fbf565b005b610881600480360381019061087c9190613396565b612093565b60405161088e91906146eb565b60405180910390f35b6108b160048036038101906108ac919061378d565b6120a5565b6040516108be91906146eb565b60405180910390f35b6108e160048036038101906108dc9190613333565b6120f6565b6040516108ee91906142c2565b60405180910390f35b610911600480360381019061090c91906134aa565b6121b3565b60405161091e91906143b7565b60405180910390f35b61092f6121d6565b60405161093c91906142c2565b60405180910390f35b61095f600480360381019061095a91906134aa565b6121e6565b60405161096c91906146d0565b60405180910390f35b61098f600480360381019061098a919061313a565b6122a0565b005b61099961244c565b6040516109a691906146eb565b60405180910390f35b6109c960048036038101906109c4919061363b565b61245d565b6040516109d7929190614706565b60405180910390f35b60035481565b600082826040516020016109fb929190614261565b60405160208183030381529060405280519060200120905092915050565b6000610a24826124a1565b9050919050565b60007f436861696e000000000000000000000000000000000000000000000000000000905090565b600080610a83856004600089815260200190815260200160002060000160000154610a7e87876109e6565b610de9565b610a8c846124a1565b9150915094509492505050565b6000610ac8846004600088815260200190815260200160002060000160000154610ac386866109e6565b610de9565b9050949350505050565b60006004600083815260200190815260200160002060000160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610b1d612deb565b600460008381526020019081526020016000206000016040518060e0016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815250509050919050565b6060808267ffffffffffffffff81118015610bf157600080fd5b50604051908082528060200260200182016040528015610c205781602001602082028036833780820191505090505b50905060008090505b83811015610c6d57600080602087600185010102905080880151915081848481518110610c5257fe5b60200260200101818152505050508080600101915050610c29565b50809150509392505050565b6040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525081565b6060815167ffffffffffffffff81118015610ccc57600080fd5b50604051908082528060200260200182016040528015610cfb5781602001602082028036833780820191505090505b509050600080905060008090505b8351811015610dbc57610d79610d338784888581518110610d2657fe5b6020026020010151610bd7565b600460008a8581518110610d4357fe5b6020026020010151815260200190815260200160002060000160000154868481518110610d6c57fe5b6020026020010151610de9565b838281518110610d8557fe5b602002602001019015159081151581525050848181518110610da357fe5b6020026020010151820191508080600101915050610d09565b5050949350505050565b600060046000838152602001908152602001600020600001600501549050919050565b60008060001b831415610dff5760009050610e0d565b610e0a848484612732565b90505b9392505050565b600080600080600060608060606000439850610e2e61244c565b9650600460008881526020019081526020016000206000016006015497506000610e56611f0f565b905060008173ffffffffffffffffffffffffffffffffffffffff16639031d9136040518163ffffffff1660e01b815260040160206040518083038186803b158015610ea057600080fd5b505afa158015610eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed891906134d3565b90508067ffffffffffffffff81118015610ef157600080fd5b50604051908082528060200260200182016040528015610f205781602001602082028036833780820191505090505b5095508067ffffffffffffffff81118015610f3a57600080fd5b50604051908082528060200260200182016040528015610f6e57816020015b6060815260200190600190039081610f595790505b50935060008090505b81811015611115578273ffffffffffffffffffffffffffffffffffffffff1663edf26d9b826040518263ffffffff1660e01b8152600401610fb891906146eb565b60206040518083038186803b158015610fd057600080fd5b505afa158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110089190613163565b87828151811061101457fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff1663fa52c7d888838151811061107657fe5b60200260200101516040518263ffffffff1660e01b815260040161109a91906142c2565b60006040518083038186803b1580156110b257600080fd5b505afa1580156110c6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906110ef919061318c565b90508582815181106110fd57fe5b60200260200101819052508080600101915050610f77565b5060008111611125576000611146565b856111338260018e016120a5565b8151811061113d57fe5b60200260200101515b97506000611152611552565b90508167ffffffffffffffff8111801561116b57600080fd5b5060405190808252806020026020018201604052801561119a5781602001602082028036833780820191505090505b5095508073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111e357600080fd5b505afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b91906134d3565b935060008090505b828110156112ec578173ffffffffffffffffffffffffffffffffffffffff166370a0823189838151811061125357fe5b60200260200101516040518263ffffffff1660e01b815260040161127791906142c2565b60206040518083038186803b15801561128f57600080fd5b505afa1580156112a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c791906134d3565b8782815181106112d357fe5b6020026020010181815250508080600101915050611223565b506112f960018d01611c0d565b9750505050909192939495969798565b600060046000838152602001908152602001600020600701805490509050919050565b60606000600460008681526020019081526020016000206000016005015490508383905067ffffffffffffffff8111801561136657600080fd5b506040519080825280602002602001820160405280156113955781602001602082028036833780820191505090505b50915060008090505b84849050811015611408576004600087815260200190815260200160002060090160008686848181106113cd57fe5b905060200201358152602001908152602001600020548382815181106113ef57fe5b602002602001018181525050808060010191505061139e565b50935093915050565b60008073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156114a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161149b90614557565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b81526004016114fd90614697565b60206040518083038186803b15801561151557600080fd5b505afa158015611529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154d9190613163565b905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b81526004016115ad90614525565b60206040518083038186803b1580156115c557600080fd5b505afa1580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd9190613163565b905090565b60006002600054141561164a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164190614677565b60405180910390fd5b6002600081905550600061165c611b75565b905060006004600083815260200190815260200160002060000160040154146116ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116b1906145f7565b60405180910390fd5b88600460006001840381526020019081526020016000206000016006015410611718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170f906146b0565b60405180910390fd5b6060818a8a60405160200161172f93929190614285565b60405160208183030381529060405290508651885114611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161177b90614577565b60405180910390fd5b60008090505b885181101561183e5787818151811061179f57fe5b60200260200101516004600085815260200190815260200160002060090160008b84815181106117cb57fe5b6020026020010151815260200190815260200160002081905550818982815181106117f257fe5b602002602001015189838151811061180657fe5b602002602001015160405160200161182093929190614228565b6040516020818303038152906040529150808060010191505061178a565b5060008180519060200120905061185883828989896127de565b600460008681526020019081526020016000206000016002016000600460008881526020019081526020016000206000016003016000849190505583919050555050896004600085815260200190815260200160002060000160000181905550336004600085815260200190815260200160002060000160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055504360046000858152602001908152602001600020600001600401819055504260046000858152602001908152602001600020600001600501819055508a60046000858152602001908152602001600020600001600601819055506005600081548092919060010191905055503373ffffffffffffffffffffffffffffffffffffffff167fa82a7ea15c804d00dba1b969024b510969fde70fac8e0d5da860cf1f7376d31784436040516119c4929190614706565b60405180910390a2600193505050506001600081905550979650505050505050565b600080611a16856004600089815260200190815260200160002060000160000154611a1187876109e6565b610de9565b611a1f84612b64565b9150915094509492505050565b611a34612d1e565b73ffffffffffffffffffffffffffffffffffffffff16611a52611be3565b73ffffffffffffffffffffffffffffffffffffffff1614611aa8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9f906145d7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60055481565b60065481565b6000611b8043611c0d565b905090565b60006004600084815260200190815260200160002060080160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806006546005540190506000811415611c2c576000915050611c62565b8260035460046000600185038152602001908152602001600020600001600401540110611c5c5760018103611c5e565b805b9150505b919050565b6000611c7560014301611c7a565b905090565b600080611c85611f0f565b905060008173ffffffffffffffffffffffffffffffffffffffff16639031d9136040518163ffffffff1660e01b815260040160206040518083038186803b158015611ccf57600080fd5b505afa158015611ce3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0791906134d3565b90506000811415611d1d57600092505050611dba565b6000611d2982866120a5565b90508273ffffffffffffffffffffffffffffffffffffffff1663edf26d9b826040518263ffffffff1660e01b8152600401611d6491906146eb565b60206040518083038186803b158015611d7c57600080fd5b505afa158015611d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db49190613163565b93505050505b919050565b600060046000838152602001908152602001600020600001600401549050919050565b600060046000838152602001908152602001600020600001600301549050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080611e3f611e3961244c565b8461245d565b91509150915091565b606060046000838152602001908152602001600020600701805480602002602001604051908101604052809291908181526020018280548015611ee057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611e96575b50505050509050919050565b600060046000838152602001908152602001600020600001600201549050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b8152600401611f6a9061453e565b60206040518083038186803b158015611f8257600080fd5b505afa158015611f96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fba9190613163565b905090565b611fc7612d1e565b73ffffffffffffffffffffffffffffffffffffffff16611fe5611be3565b73ffffffffffffffffffffffffffffffffffffffff161461203b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612032906145d7565b60405180910390fd5b806003819055503373ffffffffffffffffffffffffffffffffffffffff167facc5b61da0d1f472a8a34363bf49dfee3dc6fea150b5cf3b12a4d0e40b256bb58260405161208891906146eb565b60405180910390a250565b600061209e82612b64565b9050919050565b6000806120b061244c565b9050600060016003540160046000848152602001908152602001600020600001600401548503816120dd57fe5b04820190508481816120eb57fe5b069250505092915050565b6000806040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525086604051602001612141929190614200565b6040516020818303038152906040528051906020012090506001818686866040516000815260200160405260405161217c94939291906143d2565b6020604051602081039080840390855afa15801561219e573d6000803e3d6000fd5b50505060206040510351915050949350505050565b600060046000838152602001908152602001600020600001600001549050919050565b60006121e143611c7a565b905090565b6004602052806000526040600020600091509050806000016040518060e0016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481525050905081565b6122a8612d1e565b73ffffffffffffffffffffffffffffffffffffffff166122c6611be3565b73ffffffffffffffffffffffffffffffffffffffff161461231c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612313906145d7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561238c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612383906144a5565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600060016006546005540103905090565b600080600060046000868152602001908152602001600020905080600901600085815260200190815260200160002054816000016005015492509250509250929050565b6000808251905060038110156124ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e3906144e5565b60405180910390fd5b60ff60f81b83600283038151811061250057fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461256d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256490614617565b60405180910390fd5b600360f81b83600183038151811061258157fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146125ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125e590614637565b60405180910390fd5b600381141561260157600091505061272d565b60006012905060ee60f81b84600384038151811061261b57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146126c1576004821015612691576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612688906144e5565b60405180910390fd5b8360038303815181106126a057fe5b602001015160f81c60f81b60f81c60ff1660120390506004820391506126c8565b6003820391505b60008090505b828110156127115760018101830360080260020a8582815181106126ee57fe5b602001015160f81c60f81b60f81c60ff16028401935080806001019150506126ce565b5061272881600a0a84612d2690919063ffffffff16565b925050505b919050565b60008082905060008090505b85518110156127d057600086828151811061275557fe5b602002602001015190508083116127965782816040516020016127799291906141d4565b6040516020818303038152906040528051906020012092506127c2565b80836040516020016127a99291906141d4565b6040516020818303038152906040528051906020012092505b50808060010191505061273e565b508381149150509392505050565b60008060006127eb611552565b90508073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561283357600080fd5b505afa158015612847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286b91906134d3565b92506000915060008090505b8651811015612af05760006128c78989848151811061289257fe5b60200260200101518985815181106128a657fe5b60200260200101518986815181106128ba57fe5b60200260200101516120f6565b905060008373ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b815260040161290491906142c2565b60206040518083038186803b15801561291c57600080fd5b505afa158015612930573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295491906134d3565b90506000600460008d815260200190815260200160002060080160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146129ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129e390614597565b60405180910390fd5b60008114156129fc575050612ae3565b600460008c8152602001908152602001600020600701829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460008d815260200190815260200160002060080160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612ade8186612d9690919063ffffffff16565b945050505b8080600101915050612877565b50612b05604284612d2690919063ffffffff16565b612b19606484612d2690919063ffffffff16565b11612b59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b5090614657565b60405180910390fd5b509550959350505050565b600080825190506002811015612baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ba6906144e5565b60405180910390fd5b60ff60f81b836002830381518110612bc357fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612c30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2790614617565b60405180910390fd5b600260f81b836001830381518110612c4457fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca8906144c5565b60405180910390fd5b6002811415612cc4576000915050612d19565b60028103905060008090505b81811015612d135760018101820360080260020a848281518110612cf057fe5b602001015160f81c60f81b60f81c60ff1602830192508080600101915050612cd0565b50819150505b919050565b600033905090565b600080831415612d395760009050612d90565b6000828402905082848281612d4a57fe5b0414612d8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d82906145b7565b60405180910390fd5b809150505b92915050565b600080828401905083811015612de1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd890614505565b60405180910390fd5b8091505092915050565b6040518060e0016040528060008019168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081525090565b600081359050612e5081614b95565b92915050565b600081519050612e6581614b95565b92915050565b60008083601f840112612e7d57600080fd5b8235905067ffffffffffffffff811115612e9657600080fd5b602083019150836020820283011115612eae57600080fd5b9250929050565b600082601f830112612ec657600080fd5b8135612ed9612ed4826147fe565b6147d1565b91508181835260208401935060208101905083856020840282011115612efe57600080fd5b60005b83811015612f2e5781612f14888261303e565b845260208401935060208301925050600181019050612f01565b5050505092915050565b600082601f830112612f4957600080fd5b8135612f5c612f5782614826565b6147d1565b91508181835260208401935060208101905083856020840282011115612f8157600080fd5b60005b83811015612fb15781612f9788826130fb565b845260208401935060208301925050600181019050612f84565b5050505092915050565b600082601f830112612fcc57600080fd5b8135612fdf612fda8261484e565b6147d1565b9150818183526020840193506020810190508385602084028201111561300457600080fd5b60005b83811015613034578161301a8882613125565b845260208401935060208301925050600181019050613007565b5050505092915050565b60008135905061304d81614bac565b92915050565b600082601f83011261306457600080fd5b813561307761307282614876565b6147d1565b9150808252602083016020830185838301111561309357600080fd5b61309e838284614b2e565b50505092915050565b600082601f8301126130b857600080fd5b81516130cb6130c6826148a2565b6147d1565b915080825260208301602083018583830111156130e757600080fd5b6130f2838284614b3d565b50505092915050565b60008135905061310a81614bc3565b92915050565b60008151905061311f81614bc3565b92915050565b60008135905061313481614bda565b92915050565b60006020828403121561314c57600080fd5b600061315a84828501612e41565b91505092915050565b60006020828403121561317557600080fd5b600061318384828501612e56565b91505092915050565b6000806040838503121561319f57600080fd5b60006131ad85828601612e56565b925050602083015167ffffffffffffffff8111156131ca57600080fd5b6131d6858286016130a7565b9150509250929050565b6000806000606084860312156131f557600080fd5b600084013567ffffffffffffffff81111561320f57600080fd5b61321b86828701612eb5565b935050602061322c8682870161303e565b925050604061323d8682870161303e565b9150509250925092565b6000806000806080858703121561325d57600080fd5b600085013567ffffffffffffffff81111561327757600080fd5b61328387828801612f38565b945050602085013567ffffffffffffffff8111156132a057600080fd5b6132ac87828801613053565b935050604085013567ffffffffffffffff8111156132c957600080fd5b6132d587828801612f38565b925050606085013567ffffffffffffffff8111156132f257600080fd5b6132fe87828801612eb5565b91505092959194509250565b60006020828403121561331c57600080fd5b600061332a8482850161303e565b91505092915050565b6000806000806080858703121561334957600080fd5b60006133578782880161303e565b945050602061336887828801613125565b93505060406133798782880161303e565b925050606061338a8782880161303e565b91505092959194509250565b6000602082840312156133a857600080fd5b600082013567ffffffffffffffff8111156133c257600080fd5b6133ce84828501613053565b91505092915050565b600080604083850312156133ea57600080fd5b600083013567ffffffffffffffff81111561340457600080fd5b61341085828601613053565b925050602083013567ffffffffffffffff81111561342d57600080fd5b61343985828601613053565b9150509250929050565b60008060006060848603121561345857600080fd5b600084013567ffffffffffffffff81111561347257600080fd5b61347e86828701613053565b935050602061348f868287016130fb565b92505060406134a0868287016130fb565b9150509250925092565b6000602082840312156134bc57600080fd5b60006134ca848285016130fb565b91505092915050565b6000602082840312156134e557600080fd5b60006134f384828501613110565b91505092915050565b6000806040838503121561350f57600080fd5b600061351d858286016130fb565b925050602061352e85828601612e41565b9150509250929050565b60008060006040848603121561354d57600080fd5b600061355b868287016130fb565b935050602084013567ffffffffffffffff81111561357857600080fd5b61358486828701612e6b565b92509250509250925092565b600080600080608085870312156135a657600080fd5b60006135b4878288016130fb565b945050602085013567ffffffffffffffff8111156135d157600080fd5b6135dd87828801612eb5565b935050604085013567ffffffffffffffff8111156135fa57600080fd5b61360687828801613053565b925050606085013567ffffffffffffffff81111561362357600080fd5b61362f87828801613053565b91505092959194509250565b6000806040838503121561364e57600080fd5b600061365c858286016130fb565b925050602061366d8582860161303e565b9150509250929050565b600080600080600080600060e0888a03121561369257600080fd5b60006136a08a828b016130fb565b97505060206136b18a828b0161303e565b965050604088013567ffffffffffffffff8111156136ce57600080fd5b6136da8a828b01612eb5565b955050606088013567ffffffffffffffff8111156136f757600080fd5b6137038a828b01612f38565b945050608088013567ffffffffffffffff81111561372057600080fd5b61372c8a828b01612fbb565b93505060a088013567ffffffffffffffff81111561374957600080fd5b6137558a828b01612eb5565b92505060c088013567ffffffffffffffff81111561377257600080fd5b61377e8a828b01612eb5565b91505092959891949750929550565b600080604083850312156137a057600080fd5b60006137ae858286016130fb565b92505060206137bf858286016130fb565b9150509250929050565b60006137d5838361383d565b60208301905092915050565b60006137ed8383613a48565b60208301905092915050565b60006138058383613a66565b60208301905092915050565b600061381d8383613b41565b905092915050565b60006138318383614190565b60208301905092915050565b61384681614a3f565b82525050565b61385581614a3f565b82525050565b60006138668261491e565b61387081856149ac565b935061387b836148ce565b8060005b838110156138ac57815161389388826137c9565b975061389e8361496b565b92505060018101905061387f565b5085935050505092915050565b60006138c482614929565b6138ce81856149bd565b93506138d9836148de565b8060005b8381101561390a5781516138f188826137e1565b97506138fc83614978565b9250506001810190506138dd565b5085935050505092915050565b600061392282614934565b61392c81856149ce565b9350613937836148ee565b8060005b8381101561396857815161394f88826137f9565b975061395a83614985565b92505060018101905061393b565b5085935050505092915050565b60006139808261493f565b61398a81856149df565b93508360208202850161399c856148fe565b8060005b858110156139d857848403895281516139b98582613811565b94506139c483614992565b925060208a019950506001810190506139a0565b50829750879550505050505092915050565b60006139f58261494a565b6139ff81856149f0565b9350613a0a8361490e565b8060005b83811015613a3b578151613a228882613825565b9750613a2d8361499f565b925050600181019050613a0e565b5085935050505092915050565b613a5181614a51565b82525050565b613a6081614a51565b82525050565b613a6f81614a5d565b82525050565b613a7e81614a5d565b82525050565b613a95613a9082614a5d565b614b70565b82525050565b6000613aa682614955565b613ab08185614a01565b9350613ac0818560208601614b3d565b613ac981614b84565b840191505092915050565b6000613adf82614955565b613ae98185614a12565b9350613af9818560208601614b3d565b80840191505092915050565b613b0e81614a9e565b82525050565b613b1d81614ac2565b82525050565b613b2c81614ae6565b82525050565b613b3b81614b0a565b82525050565b6000613b4c82614960565b613b568185614a1d565b9350613b66818560208601614b3d565b613b6f81614b84565b840191505092915050565b6000613b87602683614a2e565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613bed602b83614a2e565b91507f696e76616c6964206c656166202d20696e76616c69642074797065202d20657860008301527f706563742030323a696e740000000000000000000000000000000000000000006020830152604082019050919050565b6000613c53602a83614a2e565b91507f696e76616c6964206c656166206279746573202d206d697373696e672074797060008301527f65206d65746164617461000000000000000000000000000000000000000000006020830152604082019050919050565b6000613cb9601b83614a2e565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b7f5374616b696e6742616e6b000000000000000000000000000000000000000000815250565b7f56616c696461746f725265676973747279000000000000000000000000000000815250565b6000613d45601283614a2e565b91507f5f726567697374727920697320656d70747900000000000000000000000000006000830152602082019050919050565b6000613d85602783614a2e565b91507f6e756d62657273206f66206b65797320616e642076616c756573206e6f74207460008301527f68652073616d65000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613deb602183614a2e565b91507f76616c696461746f7220696e636c75646564206d6f7265207468616e206f6e6360008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e51602183614a2e565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613eb7602083614a2e565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613ef7602b83614a2e565b91507f626c6f636b20616c7265616479206d696e656420666f722063757272656e742060008301527f626c6f636b4865696768740000000000000000000000000000000000000000006020830152604082019050919050565b6000613f5d602283614a2e565b91507f696e76616c6964206c656166202d206d697373696e672074797065206d61726b60008301527f65720000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613fc3602d83614a2e565b91507f696e76616c6964206c656166202d20696e76616c69642074797065202d20657860008301527f706563742030333a666c6f6174000000000000000000000000000000000000006020830152604082019050919050565b6000614029601d83614a2e565b91507f6e6f7420656e6f75676820706f776572207761732067617468657265640000006000830152602082019050919050565b6000614069601f83614a2e565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b7f554d420000000000000000000000000000000000000000000000000000000000815250565b60006140cf601983614a2e565b91507f63616e204e4f54207375626d6974206f6c6465722064617461000000000000006000830152602082019050919050565b60e0820160008201516141186000850182613a66565b50602082015161412b602085018261383d565b50604082015161413e6040850182614190565b5060608201516141516060850182614190565b5060808201516141646080850182614190565b5060a082015161417760a0850182614190565b5060c082015161418a60c0850182614190565b50505050565b61419981614a87565b82525050565b6141a881614a87565b82525050565b6141bf6141ba82614a87565b614b7a565b82525050565b6141ce81614a91565b82525050565b60006141e08285613a84565b6020820191506141f08284613a84565b6020820191508190509392505050565b600061420c8285613ad4565b91506142188284613a84565b6020820191508190509392505050565b60006142348286613ad4565b91506142408285613a84565b60208201915061425082846141ae565b602082019150819050949350505050565b600061426d8285613ad4565b91506142798284613ad4565b91508190509392505050565b600061429182866141ae565b6020820191506142a182856141ae565b6020820191506142b18284613a84565b602082019150819050949350505050565b60006020820190506142d7600083018461384c565b92915050565b600060208201905081810360008301526142f7818461385b565b905092915050565b6000602082019050818103600083015261431981846138b9565b905092915050565b6000602082019050818103600083015261433b8184613917565b905092915050565b6000604082019050818103600083015261435d81856139ea565b905061436c602083018461419f565b9392505050565b60006020820190506143886000830184613a57565b92915050565b60006040820190506143a36000830185613a57565b6143b0602083018461419f565b9392505050565b60006020820190506143cc6000830184613a75565b92915050565b60006080820190506143e76000830187613a75565b6143f460208301866141c5565b6144016040830185613a75565b61440e6060830184613a75565b95945050505050565b600060208201905081810360008301526144318184613a9b565b905092915050565b600060208201905061444e6000830184613b05565b92915050565b60006020820190506144696000830184613b14565b92915050565b60006020820190506144846000830184613b23565b92915050565b600060208201905061449f6000830184613b32565b92915050565b600060208201905081810360008301526144be81613b7a565b9050919050565b600060208201905081810360008301526144de81613be0565b9050919050565b600060208201905081810360008301526144fe81613c46565b9050919050565b6000602082019050818103600083015261451e81613cac565b9050919050565b600060208201905061453960008301613cec565b919050565b600060208201905061455260008301613d12565b919050565b6000602082019050818103600083015261457081613d38565b9050919050565b6000602082019050818103600083015261459081613d78565b9050919050565b600060208201905081810360008301526145b081613dde565b9050919050565b600060208201905081810360008301526145d081613e44565b9050919050565b600060208201905081810360008301526145f081613eaa565b9050919050565b6000602082019050818103600083015261461081613eea565b9050919050565b6000602082019050818103600083015261463081613f50565b9050919050565b6000602082019050818103600083015261465081613fb6565b9050919050565b600060208201905081810360008301526146708161401c565b9050919050565b600060208201905081810360008301526146908161405c565b9050919050565b60006020820190506146ab6000830161409c565b919050565b600060208201905081810360008301526146c9816140c2565b9050919050565b600060e0820190506146e56000830184614102565b92915050565b6000602082019050614700600083018461419f565b92915050565b600060408201905061471b600083018561419f565b614728602083018461419f565b9392505050565b600061012082019050614745600083018c61419f565b614752602083018b61419f565b61475f604083018a61419f565b61476c606083018961384c565b614779608083018861419f565b81810360a083015261478b818761385b565b905081810360c083015261479f81866139ea565b905081810360e08301526147b38185613975565b90506147c361010083018461419f565b9a9950505050505050505050565b6000604051905081810181811067ffffffffffffffff821117156147f457600080fd5b8060405250919050565b600067ffffffffffffffff82111561481557600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561483d57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561486557600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561488d57600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156148b957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b6000614a4a82614a67565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000614aa982614ab0565b9050919050565b6000614abb82614a67565b9050919050565b6000614acd82614ad4565b9050919050565b6000614adf82614a67565b9050919050565b6000614af182614af8565b9050919050565b6000614b0382614a67565b9050919050565b6000614b1582614b1c565b9050919050565b6000614b2782614a67565b9050919050565b82818337600083830152505050565b60005b83811015614b5b578082015181840152602081019050614b40565b83811115614b6a576000848401525b50505050565b6000819050919050565b6000819050919050565b6000601f19601f8301169050919050565b614b9e81614a3f565b8114614ba957600080fd5b50565b614bb581614a5d565b8114614bc057600080fd5b50565b614bcc81614a87565b8114614bd757600080fd5b50565b614be381614a91565b8114614bee57600080fd5b5056fea2646970667358221220fbb19f4b836596684b410a1db2eaff5533a298b34cb90b33a33d5407c0ec2a2964736f6c634300060800330000000000000000000000003508848650bb8ea55390faeefa13312cb4d87e1d0000000000000000000000000000000000000000000000000000000000000014

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000003508848650bb8ea55390faeefa13312cb4d87e1d0000000000000000000000000000000000000000000000000000000000000014

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000003508848650bb8ea55390faeefa13312cb4d87e1d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000014


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading