ETH Price: $3,088.43 (-0.97%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xd06FC0D2...3B916AE01
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
VerifierExit

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

import "./KeysWithPlonkSingleVerifier.sol";

// Hardcoded constants to avoid accessing store
contract VerifierExit is KeysWithPlonkSingleVerifier {

    function initialize(bytes calldata) external {
    }

    /// @notice VerifierExit contract upgrade. Can be external because Proxy contract intercepts illegal calls of this function.
    /// @param upgradeParameters Encoded representation of upgrade parameters
    function upgrade(bytes calldata upgradeParameters) external {}

    function verifyExitProof(
        bytes32 _rootHash,
        uint32 _accountId,
        address _owner,
        uint16 _tokenId,
        uint128 _amount,
        uint256[] calldata _proof
    ) external view returns (bool) {
        bytes32 commitment = sha256(abi.encodePacked(_rootHash, _accountId, _owner, _tokenId, _amount));

        uint256[] memory inputs = new uint256[](1);
        uint256 mask = (~uint256(0)) >> 3;
        inputs[0] = uint256(commitment) & mask;
        Proof memory proof = deserialize_proof(inputs, _proof);
        VerificationKey memory vk = getVkExit();
        require(vk.num_inputs == inputs.length);
        return verify(proof, vk);
    }


    function verifyExitNFTProof(
        bytes32 _rootHash,
        uint64 _tokenId,
        uint32 _creatorId,
        uint32 _seqId,
        bytes32 _uri,
        address _owner,
        uint256[] calldata _proof
    ) external view returns (bool) {
        bytes32 commitment = sha256(abi.encodePacked(_rootHash, _tokenId, _creatorId, _seqId, _uri, _owner));

        uint256[] memory inputs = new uint256[](1);
        uint256 mask = (~uint256(0)) >> 3;
        inputs[0] = uint256(commitment) & mask;
        Proof memory proof = deserialize_proof(inputs, _proof);
        VerificationKey memory vk = getVkNFTExit();
        require(vk.num_inputs == inputs.length);
        return verify(proof, vk);
    }

    function concatBytes(bytes memory param1, bytes memory param2) public pure returns (bytes memory) {
        bytes memory merged = new bytes(param1.length + param2.length);

        uint k = 0;
        for (uint i = 0; i < param1.length; i++) {
            merged[k] = param1[i];
            k++;
        }

        for (uint i = 0; i < param2.length; i++) {
            merged[k] = param2[i];
            k++;
        }
        return merged;
    }

    function verifyLpExitProof(
        bytes calldata _account_data,
        bytes calldata _pair_data0,
        bytes calldata _pair_data1,
        uint256[] calldata _proof
    ) external view returns (bool) {
        bytes memory _data1 = concatBytes(_account_data, _pair_data0);
        bytes memory _data2 = concatBytes(_data1, _pair_data1);
        bytes32 commitment = sha256(_data2);

        uint256[] memory inputs = new uint256[](1);
        uint256 mask = (~uint256(0)) >> 3;
        inputs[0] = uint256(commitment) & mask;
        Proof memory proof = deserialize_proof(inputs, _proof);
        VerificationKey memory vk = getVkLpExit();
        require(vk.num_inputs == inputs.length);
        return verify(proof, vk);
    }
}

pragma solidity >=0.5.0 <0.7.0;

import "./PlonkSingleCore.sol";

// Hardcoded constants to avoid accessing store
contract KeysWithPlonkSingleVerifier is SingleVerifierWithDeserialize {

    function isBlockSizeSupportedInternal(uint32 _size) internal pure returns (bool) {
        if (_size == uint32(12)) { return true; }
        else if (_size == uint32(36)) { return true; }
        else if (_size == uint32(78)) { return true; }
        else if (_size == uint32(156)) { return true; }
        else if (_size == uint32(318)) { return true; }
        else { return false; }
    }

    
    function getVkExit() internal pure returns(VerificationKey memory vk) {
        vk.domain_size = 262144;
        vk.num_inputs = 1;
        vk.omega = PairingsBn254.new_fr(0x0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe);
        vk.selector_commitments[0] = PairingsBn254.new_g1(
            0x135a8971e309397099f1c5c0b9c2a141e83b888ff0504ba8c9a7c13b8c66873f,
            0x0eed3feed06aa8e4d3493aefd4c6f9a6c337e20b7e2f20d22b08b3b4129f8efc
        );
        vk.selector_commitments[1] = PairingsBn254.new_g1(
            0x0b97dc8947583759347e13c8f2abdccf1004e13f771fe9c46155af71d336de2e,
            0x1d39ffdb681fca7ce01b775e9aaaf5d8b71d9b7602ac00c60bbde91dca816dec
        );
        vk.selector_commitments[2] = PairingsBn254.new_g1(
            0x04b4d20919f8c66794a986ad27a0e4e820fb7a1bf863048017a59b1f7b3030f6,
            0x2da162d6902e64de2d4f6178f090bf9db7fbb9199d1640d5eab9c0a26869524f
        );
        vk.selector_commitments[3] = PairingsBn254.new_g1(
            0x242d28e776c833130fb04fb097c1c166c4293018e64947c46086f1bea2184732,
            0x277463020cda47c42366610a37cde00ef3a32b44906e1adee02fcd66bbe44a75
        );
        vk.selector_commitments[4] = PairingsBn254.new_g1(
            0x24d289d00964c5501b4a32521df5685264fb490a4549e794f998f18f169f3195,
            0x14307765ce1383efab72009df36fd97d28b94c9c1fce57a64697e5633d8d4e0d
        );
        vk.selector_commitments[5] = PairingsBn254.new_g1(
            0x0c3697df5aef9952def7b12d29447e9ae12fe6580f0e00399237bee51a5fa0e0,
            0x2b120b7d414a0843aa2e9e606bcec5ff8eb3c38d8b73479de42fc8901bb626e6
        );

        // we only have access to value of the d(x) witness polynomial on the next
        // trace step, so we only need one element here and deal with it in other places
        // by having this in mind
        vk.next_step_selector_commitments[0] = PairingsBn254.new_g1(
            0x0e09a50a8e0635250a3a200dab94a1a51de811b179f61df2d4683e59fd1774ee,
            0x251732ea6c2951b7b54f2dbc349b14db2b63def8d132f86499d2e43edc21ad51
        );

         vk.permutation_commitments[0] = PairingsBn254.new_g1(
            0x1889e41a3cebf0b097ec6cef8849e66480c344c422ed9a2e4d63fe75155af0d0,
            0x0ed098f479a2f229cd47f645517737f512612915010cb576398cd4ec7c803baf
        );
        vk.permutation_commitments[1] = PairingsBn254.new_g1(
            0x141171280664b7aea2c65ddb87f28391cab60913a74f4255b3dd4295d162a02c,
            0x033c1cc5f1e58a035eb5f3951e79cc90e9fccf3c82781c2553b1d49694a18991
        );
        vk.permutation_commitments[2] = PairingsBn254.new_g1(
            0x0fc9a25cc839ef11afab0a9f320cf2b7346054f566135611bb25b6cec46205b3,
            0x16ea53198b77ab1e469d166b36d89d9fd88b3c356958cdf377a534d73f47a9a3
        );
        vk.permutation_commitments[3] = PairingsBn254.new_g1(
            0x2040345b5f92cc70a9607cf5fc28e5be26f673852450488d4e65f70890649b45,
            0x2c0e0bf512b4aa690449b589513e2b34cbc5e748a4217947331e0350c73be310
        );

        vk.permutation_non_residues[0] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000005
        );
        vk.permutation_non_residues[1] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000007
        );
        vk.permutation_non_residues[2] = PairingsBn254.new_fr(
            0x000000000000000000000000000000000000000000000000000000000000000a
        );

        vk.g2_x = PairingsBn254.new_g2(
            [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1,
             0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0],
            [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4,
             0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55]
        );
    }
    
    function getVkLpExit() internal pure returns(VerificationKey memory vk) {
        vk.domain_size = 524288;
        vk.num_inputs = 1;
        vk.omega = PairingsBn254.new_fr(0x0cf1526aaafac6bacbb67d11a4077806b123f767e4b0883d14cc0193568fc082);
        vk.selector_commitments[0] = PairingsBn254.new_g1(
            0x26aafba448a6c22abfa5286eef01b17a6bffaacf20a8a0fca1a59035c8e45ddd,
            0x160835d2c20ea81f2f4c2c7f1644e30ae41b2541588a27552c08c190d5b32af8
        );
        vk.selector_commitments[1] = PairingsBn254.new_g1(
            0x20954e6cd2ad660dd9723263311b03986d6f8993ebfeb67a60a46608b35701fe,
            0x059ce6f6469bb72b8758473f86e86a959c4b9f74193d931dd172883c641a25c7
        );
        vk.selector_commitments[2] = PairingsBn254.new_g1(
            0x26245ff891a4328caa0da951efba1b5b3cc13136cd315ac7c8794053e47a4315,
            0x1681b7685491b5f8fb470a21a326bc91bd75178d411ead030aefcddd9b51bd06
        );
        vk.selector_commitments[3] = PairingsBn254.new_g1(
            0x2857e4543592da2693e7e97477f186736c4a0a325bd9477bbd996819dc0ca4ce,
            0x0ffe00e34dd8592675469bb7a92b1e78e7c9e4ace22343605fb3a48dd4f15970
        );
        vk.selector_commitments[4] = PairingsBn254.new_g1(
            0x0180059910e776f202efcb1b96d72ab597e811caef2a9af5d8b42fc79949d913,
            0x1a43d65fba7b7340f6cb120a31ad0a1d5a26e0a1151398d9a80d6930e623be21
        );
        vk.selector_commitments[5] = PairingsBn254.new_g1(
            0x007b755d547d62eaf1375f3efe8a62ef52ed1b40ef2ec0943ab9a1de7198f274,
            0x28f96cb876dc97aada23aa73d202682e3f29a29126d5711df0747234660cd83d
        );

        // we only have access to value of the d(x) witness polynomial on the next
        // trace step, so we only need one element here and deal with it in other places
        // by having this in mind
        vk.next_step_selector_commitments[0] = PairingsBn254.new_g1(
            0x00dfc41dc088a145be5a6978121abea7dffaef90012b9d6f1b577e957a28dd24,
            0x2ef1b64e6b0afe751b5531869a17dd9d5c90d734880de7fed3d3ae74a01d989a
        );

         vk.permutation_commitments[0] = PairingsBn254.new_g1(
            0x1d69be00b5e7d9d2af9d10da25eda41333effe6b9435caefe07ddae096d30ddf,
            0x162137b0ead7f1be6f448f36db186c5bee0e44f19a926e88b53f7760b64e9dbd
        );
        vk.permutation_commitments[1] = PairingsBn254.new_g1(
            0x179c8e2df764ec8a2a5f5dbd37ffdde057178b6c10ef04bbb3331a7843934331,
            0x1a71e27ade54b801c811bd10d93c2b9e6c80bfea3d808487cf375f50e065e896
        );
        vk.permutation_commitments[2] = PairingsBn254.new_g1(
            0x2fc48aa7bcba72e922843e8732398afe655368a3aedca1f204b0e1bd9ddbf981,
            0x2f6adc4261e3dd2fc80affdb39de386de5c38aa0066a8560f76dff220341071a
        );
        vk.permutation_commitments[3] = PairingsBn254.new_g1(
            0x2a096bb764588fb3f422291918e33c1d8d9f5a8ef6c9cf41d288a5ddea0cf26a,
            0x1e2ab7435be44f4101b1af83f76d5b621f4ecdd9d673a4b019ffb41072413f9b
        );

        vk.permutation_non_residues[0] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000005
        );
        vk.permutation_non_residues[1] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000007
        );
        vk.permutation_non_residues[2] = PairingsBn254.new_fr(
            0x000000000000000000000000000000000000000000000000000000000000000a
        );

        vk.g2_x = PairingsBn254.new_g2(
            [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1,
             0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0],
            [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4,
             0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55]
        );
    }
    
    function getVkNFTExit() internal pure returns(VerificationKey memory vk) {
        vk.domain_size = 262144;
        vk.num_inputs = 1;
        vk.omega = PairingsBn254.new_fr(0x0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe);
        vk.selector_commitments[0] = PairingsBn254.new_g1(
            0x27ad08e12b6087f6fe0d7e1d8d8f14f53e92aaabf05e4f7d1051b0fbe3db046d,
            0x11f1f49ccf9f433366c3dc71fe9efa794678b87cbb2b07deea0cfbb7093e5369
        );
        vk.selector_commitments[1] = PairingsBn254.new_g1(
            0x1ee701b0be61332b7de5d4260ad352a3f50a8e51ac4a761f6ab5077c8dffab51,
            0x21451115294a50d06c5c442e9a61b04699fd8f296e70ef00e78a5908ef541444
        );
        vk.selector_commitments[2] = PairingsBn254.new_g1(
            0x1eccd5e119cc4a7bc8d274e0d8f61a054ee38694796790dacd22a098642bf2bc,
            0x10bb95ce678a633560f0a704001e4c148aff47b7aee0856bfec735fb13884e02
        );
        vk.selector_commitments[3] = PairingsBn254.new_g1(
            0x013fa8820794811964f35f04adb7600a9a3c76c9960b9cbb162b8324e09a14f5,
            0x0c110889cdf3554c95c7876f3e9d64804b3f0a6effa2baaf8bcb4ca847e5ed1d
        );
        vk.selector_commitments[4] = PairingsBn254.new_g1(
            0x1d5d922608eb262a5b05dc872b81238a352ba3521a1e847b06606d0937c7a34c,
            0x291cd60f7f242bd5e1075f99ed70583f40460758aa58c8cd418cb5b6929e8c12
        );
        vk.selector_commitments[5] = PairingsBn254.new_g1(
            0x2bc438c9650f27fd6b4125e098c5d87f874cfd29efad4a3e4ecae04e23b05009,
            0x283af270ef1c1c897e85b844536745dbf4d744f2e0fe8dc113143b5209a60baa
        );

        // we only have access to value of the d(x) witness polynomial on the next
        // trace step, so we only need one element here and deal with it in other places
        // by having this in mind
        vk.next_step_selector_commitments[0] = PairingsBn254.new_g1(
            0x16f50151d8dccdd5e06a29eee62a9f614d534c542640bee31e9e9a3f2b708a83,
            0x120854cacf85957ca9777576bda620a21312769ab9596c7c64dc742156839882
        );

         vk.permutation_commitments[0] = PairingsBn254.new_g1(
            0x27d2cd3c7a778fed777f6410fca3a65521282818e187e901827b1e666281d38b,
            0x1f5484c3976cadaea11704759c33ecfffe4900b696febcffb397ec15324c484a
        );
        vk.permutation_commitments[1] = PairingsBn254.new_g1(
            0x26a13c2a6968f979cfc4ef24b965487c5f22f2dfc5e9008942fa32bbb72f7b3c,
            0x2bbb803702a9e0c0d4e3a078e2ffa2c525165f940a551555efbdd8876cc3f06e
        );
        vk.permutation_commitments[2] = PairingsBn254.new_g1(
            0x17210a663b894d0d08db4ba0f2da65bf67b5e4c94317d03e0eb6077b11e849ef,
            0x2c98fb45631bd244290296ce55afc885e0e3cc96b506037183338141e97fdf61
        );
        vk.permutation_commitments[3] = PairingsBn254.new_g1(
            0x1ef739c21d81d82ecb30445c5c6e775597aed256ee615b84c71dff243c81dd9e,
            0x072138b9876fc2f52d29b5cf35478fe4091f384c034fa59ab4b29deb69e98281
        );

        vk.permutation_non_residues[0] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000005
        );
        vk.permutation_non_residues[1] = PairingsBn254.new_fr(
            0x0000000000000000000000000000000000000000000000000000000000000007
        );
        vk.permutation_non_residues[2] = PairingsBn254.new_fr(
            0x000000000000000000000000000000000000000000000000000000000000000a
        );

        vk.g2_x = PairingsBn254.new_g2(
            [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1,
             0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0],
            [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4,
             0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55]
        );
    }
    

}

pragma solidity >=0.5.0 <0.7.0;

import "./PlonkCoreLib.sol";

contract Plonk4SingleVerifierWithAccessToDNext {
    using PairingsBn254 for PairingsBn254.G1Point;
    using PairingsBn254 for PairingsBn254.G2Point;
    using PairingsBn254 for PairingsBn254.Fr;

    using TranscriptLibrary for TranscriptLibrary.Transcript;

    uint256 constant STATE_WIDTH = 4;
    uint256 constant ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP = 1;

    struct VerificationKey {
        uint256 domain_size;
        uint256 num_inputs;
        PairingsBn254.Fr omega;
        PairingsBn254.G1Point[STATE_WIDTH+2] selector_commitments; // STATE_WIDTH for witness + multiplication + constant
        PairingsBn254.G1Point[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] next_step_selector_commitments;
        PairingsBn254.G1Point[STATE_WIDTH] permutation_commitments;
        PairingsBn254.Fr[STATE_WIDTH-1] permutation_non_residues;
        PairingsBn254.G2Point g2_x;
    }

    struct Proof {
        uint256[] input_values;
        PairingsBn254.G1Point[STATE_WIDTH] wire_commitments;
        PairingsBn254.G1Point grand_product_commitment;
        PairingsBn254.G1Point[STATE_WIDTH] quotient_poly_commitments;
        PairingsBn254.Fr[STATE_WIDTH] wire_values_at_z;
        PairingsBn254.Fr[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] wire_values_at_z_omega;
        PairingsBn254.Fr grand_product_at_z_omega;
        PairingsBn254.Fr quotient_polynomial_at_z;
        PairingsBn254.Fr linearization_polynomial_at_z;
        PairingsBn254.Fr[STATE_WIDTH-1] permutation_polynomials_at_z;

        PairingsBn254.G1Point opening_at_z_proof;
        PairingsBn254.G1Point opening_at_z_omega_proof;
    }

    struct PartialVerifierState {
        PairingsBn254.Fr alpha;
        PairingsBn254.Fr beta;
        PairingsBn254.Fr gamma;
        PairingsBn254.Fr v;
        PairingsBn254.Fr u;
        PairingsBn254.Fr z;
        PairingsBn254.Fr[] cached_lagrange_evals;
    }

    function evaluate_lagrange_poly_out_of_domain(
        uint256 poly_num,
        uint256 domain_size,
        PairingsBn254.Fr memory omega,
        PairingsBn254.Fr memory at
    ) internal view returns (PairingsBn254.Fr memory res) {
        require(poly_num < domain_size);
        PairingsBn254.Fr memory one = PairingsBn254.new_fr(1);
        PairingsBn254.Fr memory omega_power = omega.pow(poly_num);
        res = at.pow(domain_size);
        res.sub_assign(one);
        require(res.value != 0); // Vanishing polynomial can not be zero at point `at`
        res.mul_assign(omega_power);

        PairingsBn254.Fr memory den = PairingsBn254.copy(at);
        den.sub_assign(omega_power);
        den.mul_assign(PairingsBn254.new_fr(domain_size));

        den = den.inverse();

        res.mul_assign(den);
    }

    function evaluate_vanishing(
        uint256 domain_size,
        PairingsBn254.Fr memory at
    ) internal view returns (PairingsBn254.Fr memory res) {
        res = at.pow(domain_size);
        res.sub_assign(PairingsBn254.new_fr(1));
    }

    function verify_at_z(
        PartialVerifierState memory state,
        Proof memory proof,
        VerificationKey memory vk
    ) internal view returns (bool) {
        PairingsBn254.Fr memory lhs = evaluate_vanishing(vk.domain_size, state.z);
        require(lhs.value != 0); // we can not check a polynomial relationship if point `z` is in the domain
        lhs.mul_assign(proof.quotient_polynomial_at_z);

        PairingsBn254.Fr memory quotient_challenge = PairingsBn254.new_fr(1);
        PairingsBn254.Fr memory rhs = PairingsBn254.copy(proof.linearization_polynomial_at_z);

        // public inputs
        PairingsBn254.Fr memory tmp = PairingsBn254.new_fr(0);
        for (uint256 i = 0; i < proof.input_values.length; i++) {
            tmp.assign(state.cached_lagrange_evals[i]);
            tmp.mul_assign(PairingsBn254.new_fr(proof.input_values[i]));
            rhs.add_assign(tmp);
        }

        quotient_challenge.mul_assign(state.alpha);

        PairingsBn254.Fr memory z_part = PairingsBn254.copy(proof.grand_product_at_z_omega);
        for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) {
            tmp.assign(proof.permutation_polynomials_at_z[i]);
            tmp.mul_assign(state.beta);
            tmp.add_assign(state.gamma);
            tmp.add_assign(proof.wire_values_at_z[i]);

            z_part.mul_assign(tmp);
        }

        tmp.assign(state.gamma);
        // we need a wire value of the last polynomial in enumeration
        tmp.add_assign(proof.wire_values_at_z[STATE_WIDTH - 1]);

        z_part.mul_assign(tmp);
        z_part.mul_assign(quotient_challenge);

        rhs.sub_assign(z_part);

        quotient_challenge.mul_assign(state.alpha);

        tmp.assign(state.cached_lagrange_evals[0]);
        tmp.mul_assign(quotient_challenge);

        rhs.sub_assign(tmp);

        return lhs.value == rhs.value;
    }

    function reconstruct_d(
        PartialVerifierState memory state,
        Proof memory proof,
        VerificationKey memory vk
    ) internal view returns (PairingsBn254.G1Point memory res) {
        // we compute what power of v is used as a delinearization factor in batch opening of
        // commitments. Let's label W(x) = 1 / (x - z) *
        // [
        // t_0(x) + z^n * t_1(x) + z^2n * t_2(x) + z^3n * t_3(x) - t(z)
        // + v (r(x) - r(z))
        // + v^{2..5} * (witness(x) - witness(z))
        // + v^(6..8) * (permutation(x) - permutation(z))
        // ]
        // W'(x) = 1 / (x - z*omega) *
        // [
        // + v^9 (z(x) - z(z*omega)) <- we need this power
        // + v^10 * (d(x) - d(z*omega))
        // ]
        //
        // we pay a little for a few arithmetic operations to not introduce another constant
        uint256 power_for_z_omega_opening = 1 + 1 + STATE_WIDTH + STATE_WIDTH - 1;
        res = PairingsBn254.copy_g1(vk.selector_commitments[STATE_WIDTH + 1]);

        PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1();
        PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(0);

        // addition gates
        for (uint256 i = 0; i < STATE_WIDTH; i++) {
            tmp_g1 = vk.selector_commitments[i].point_mul(proof.wire_values_at_z[i]);
            res.point_add_assign(tmp_g1);
        }

        // multiplication gate
        tmp_fr.assign(proof.wire_values_at_z[0]);
        tmp_fr.mul_assign(proof.wire_values_at_z[1]);
        tmp_g1 = vk.selector_commitments[STATE_WIDTH].point_mul(tmp_fr);
        res.point_add_assign(tmp_g1);

        // d_next
        tmp_g1 = vk.next_step_selector_commitments[0].point_mul(proof.wire_values_at_z_omega[0]);
        res.point_add_assign(tmp_g1);

        // z * non_res * beta + gamma + a
        PairingsBn254.Fr memory grand_product_part_at_z = PairingsBn254.copy(state.z);
        grand_product_part_at_z.mul_assign(state.beta);
        grand_product_part_at_z.add_assign(proof.wire_values_at_z[0]);
        grand_product_part_at_z.add_assign(state.gamma);
        for (uint256 i = 0; i < vk.permutation_non_residues.length; i++) {
            tmp_fr.assign(state.z);
            tmp_fr.mul_assign(vk.permutation_non_residues[i]);
            tmp_fr.mul_assign(state.beta);
            tmp_fr.add_assign(state.gamma);
            tmp_fr.add_assign(proof.wire_values_at_z[i+1]);

            grand_product_part_at_z.mul_assign(tmp_fr);
        }

        grand_product_part_at_z.mul_assign(state.alpha);

        tmp_fr.assign(state.cached_lagrange_evals[0]);
        tmp_fr.mul_assign(state.alpha);
        tmp_fr.mul_assign(state.alpha);

        grand_product_part_at_z.add_assign(tmp_fr);

        PairingsBn254.Fr memory grand_product_part_at_z_omega = state.v.pow(power_for_z_omega_opening);
        grand_product_part_at_z_omega.mul_assign(state.u);

        PairingsBn254.Fr memory last_permutation_part_at_z = PairingsBn254.new_fr(1);
        for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) {
            tmp_fr.assign(state.beta);
            tmp_fr.mul_assign(proof.permutation_polynomials_at_z[i]);
            tmp_fr.add_assign(state.gamma);
            tmp_fr.add_assign(proof.wire_values_at_z[i]);

            last_permutation_part_at_z.mul_assign(tmp_fr);
        }

        last_permutation_part_at_z.mul_assign(state.beta);
        last_permutation_part_at_z.mul_assign(proof.grand_product_at_z_omega);
        last_permutation_part_at_z.mul_assign(state.alpha);

        // add to the linearization
        tmp_g1 = proof.grand_product_commitment.point_mul(grand_product_part_at_z);
        tmp_g1.point_sub_assign(vk.permutation_commitments[STATE_WIDTH - 1].point_mul(last_permutation_part_at_z));

        res.point_add_assign(tmp_g1);
        res.point_mul_assign(state.v);

        res.point_add_assign(proof.grand_product_commitment.point_mul(grand_product_part_at_z_omega));
    }

    function verify_commitments(
        PartialVerifierState memory state,
        Proof memory proof,
        VerificationKey memory vk
    ) internal view returns (bool) {
        PairingsBn254.G1Point memory d = reconstruct_d(state, proof, vk);

        PairingsBn254.Fr memory z_in_domain_size = state.z.pow(vk.domain_size);

        PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1();

        PairingsBn254.Fr memory aggregation_challenge = PairingsBn254.new_fr(1);

        PairingsBn254.G1Point memory commitment_aggregation = PairingsBn254.copy_g1(proof.quotient_poly_commitments[0]);
        PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(1);
        for (uint i = 1; i < proof.quotient_poly_commitments.length; i++) {
            tmp_fr.mul_assign(z_in_domain_size);
            tmp_g1 = proof.quotient_poly_commitments[i].point_mul(tmp_fr);
            commitment_aggregation.point_add_assign(tmp_g1);
        }

        aggregation_challenge.mul_assign(state.v);
        commitment_aggregation.point_add_assign(d);

        for (uint i = 0; i < proof.wire_commitments.length; i++) {
            aggregation_challenge.mul_assign(state.v);
            tmp_g1 = proof.wire_commitments[i].point_mul(aggregation_challenge);
            commitment_aggregation.point_add_assign(tmp_g1);
        }

        for (uint i = 0; i < vk.permutation_commitments.length - 1; i++) {
            aggregation_challenge.mul_assign(state.v);
            tmp_g1 = vk.permutation_commitments[i].point_mul(aggregation_challenge);
            commitment_aggregation.point_add_assign(tmp_g1);
        }

        aggregation_challenge.mul_assign(state.v);

        aggregation_challenge.mul_assign(state.v);

        tmp_fr.assign(aggregation_challenge);
        tmp_fr.mul_assign(state.u);
        tmp_g1 = proof.wire_commitments[STATE_WIDTH - 1].point_mul(tmp_fr);
        commitment_aggregation.point_add_assign(tmp_g1);

        // collect opening values
        aggregation_challenge = PairingsBn254.new_fr(1);

        PairingsBn254.Fr memory aggregated_value = PairingsBn254.copy(proof.quotient_polynomial_at_z);

        aggregation_challenge.mul_assign(state.v);

        tmp_fr.assign(proof.linearization_polynomial_at_z);
        tmp_fr.mul_assign(aggregation_challenge);
        aggregated_value.add_assign(tmp_fr);

        for (uint i = 0; i < proof.wire_values_at_z.length; i++) {
            aggregation_challenge.mul_assign(state.v);

            tmp_fr.assign(proof.wire_values_at_z[i]);
            tmp_fr.mul_assign(aggregation_challenge);
            aggregated_value.add_assign(tmp_fr);
        }

        for (uint i = 0; i < proof.permutation_polynomials_at_z.length; i++) {
            aggregation_challenge.mul_assign(state.v);

            tmp_fr.assign(proof.permutation_polynomials_at_z[i]);
            tmp_fr.mul_assign(aggregation_challenge);
            aggregated_value.add_assign(tmp_fr);
        }

        aggregation_challenge.mul_assign(state.v);

        tmp_fr.assign(proof.grand_product_at_z_omega);
        tmp_fr.mul_assign(aggregation_challenge);
        tmp_fr.mul_assign(state.u);
        aggregated_value.add_assign(tmp_fr);

        aggregation_challenge.mul_assign(state.v);

        tmp_fr.assign(proof.wire_values_at_z_omega[0]);
        tmp_fr.mul_assign(aggregation_challenge);
        tmp_fr.mul_assign(state.u);
        aggregated_value.add_assign(tmp_fr);

        commitment_aggregation.point_sub_assign(PairingsBn254.P1().point_mul(aggregated_value));

        PairingsBn254.G1Point memory pair_with_generator = commitment_aggregation;
        pair_with_generator.point_add_assign(proof.opening_at_z_proof.point_mul(state.z));

        tmp_fr.assign(state.z);
        tmp_fr.mul_assign(vk.omega);
        tmp_fr.mul_assign(state.u);
        pair_with_generator.point_add_assign(proof.opening_at_z_omega_proof.point_mul(tmp_fr));

        PairingsBn254.G1Point memory pair_with_x = proof.opening_at_z_omega_proof.point_mul(state.u);
        pair_with_x.point_add_assign(proof.opening_at_z_proof);
        pair_with_x.negate();

        return PairingsBn254.pairingProd2(pair_with_generator, PairingsBn254.P2(), pair_with_x, vk.g2_x);
    }

    function verify_initial(
        PartialVerifierState memory state,
        Proof memory proof,
        VerificationKey memory vk
    ) internal view returns (bool) {
        require(proof.input_values.length == vk.num_inputs);
        require(vk.num_inputs == 1);
        TranscriptLibrary.Transcript memory transcript = TranscriptLibrary.new_transcript();
        for (uint256 i = 0; i < vk.num_inputs; i++) {
            transcript.update_with_u256(proof.input_values[i]);
        }

        for (uint256 i = 0; i < proof.wire_commitments.length; i++) {
            transcript.update_with_g1(proof.wire_commitments[i]);
        }

        state.beta = transcript.get_challenge();
        state.gamma = transcript.get_challenge();

        transcript.update_with_g1(proof.grand_product_commitment);
        state.alpha = transcript.get_challenge();

        for (uint256 i = 0; i < proof.quotient_poly_commitments.length; i++) {
            transcript.update_with_g1(proof.quotient_poly_commitments[i]);
        }

        state.z = transcript.get_challenge();

        state.cached_lagrange_evals = new PairingsBn254.Fr[](1);
        state.cached_lagrange_evals[0] = evaluate_lagrange_poly_out_of_domain(
            0,
            vk.domain_size,
            vk.omega, state.z
        );

        bool valid = verify_at_z(state, proof, vk);

        if (valid == false) {
            return false;
        }

        for (uint256 i = 0; i < proof.wire_values_at_z.length; i++) {
            transcript.update_with_fr(proof.wire_values_at_z[i]);
        }

        for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) {
            transcript.update_with_fr(proof.wire_values_at_z_omega[i]);
        }

        for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) {
            transcript.update_with_fr(proof.permutation_polynomials_at_z[i]);
        }

        transcript.update_with_fr(proof.quotient_polynomial_at_z);
        transcript.update_with_fr(proof.linearization_polynomial_at_z);
        transcript.update_with_fr(proof.grand_product_at_z_omega);

        state.v = transcript.get_challenge();
        transcript.update_with_g1(proof.opening_at_z_proof);
        transcript.update_with_g1(proof.opening_at_z_omega_proof);
        state.u = transcript.get_challenge();

        return true;
    }

    // This verifier is for a PLONK with a state width 4
    // and main gate equation
    // q_a(X) * a(X) +
    // q_b(X) * b(X) +
    // q_c(X) * c(X) +
    // q_d(X) * d(X) +
    // q_m(X) * a(X) * b(X) +
    // q_constants(X)+
    // q_d_next(X) * d(X*omega)
    // where q_{}(X) are selectors a, b, c, d - state (witness) polynomials
    // q_d_next(X) "peeks" into the next row of the trace, so it takes
    // the same d(X) polynomial, but shifted

    function verify(Proof memory proof, VerificationKey memory vk) internal view returns (bool) {
        PartialVerifierState memory state;

        bool valid = verify_initial(state, proof, vk);

        if (valid == false) {
            return false;
        }

        valid = verify_commitments(state, proof, vk);

        return valid;
    }
}

contract SingleVerifierWithDeserialize is Plonk4SingleVerifierWithAccessToDNext {
    uint256 constant SERIALIZED_PROOF_LENGTH = 33;

    function deserialize_proof(
        uint256[] memory public_inputs,
        uint256[] memory serialized_proof
    ) internal pure returns(Proof memory proof) {
        require(serialized_proof.length == SERIALIZED_PROOF_LENGTH);
        proof.input_values = new uint256[](public_inputs.length);
        for (uint256 i = 0; i < public_inputs.length; i++) {
            proof.input_values[i] = public_inputs[i];
        }

        uint256 j = 0;
        for (uint256 i = 0; i < STATE_WIDTH; i++) {
            proof.wire_commitments[i] = PairingsBn254.new_g1_checked(
                serialized_proof[j],
                serialized_proof[j+1]
            );

            j += 2;
        }

        proof.grand_product_commitment = PairingsBn254.new_g1_checked(
            serialized_proof[j],
            serialized_proof[j+1]
        );
        j += 2;

        for (uint256 i = 0; i < STATE_WIDTH; i++) {
            proof.quotient_poly_commitments[i] = PairingsBn254.new_g1_checked(
                serialized_proof[j],
                serialized_proof[j+1]
            );

            j += 2;
        }

        for (uint256 i = 0; i < STATE_WIDTH; i++) {
            proof.wire_values_at_z[i] = PairingsBn254.new_fr(
                serialized_proof[j]
            );

            j += 1;
        }

        for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) {
            proof.wire_values_at_z_omega[i] = PairingsBn254.new_fr(
                serialized_proof[j]
            );

            j += 1;
        }

        proof.grand_product_at_z_omega = PairingsBn254.new_fr(
            serialized_proof[j]
        );

        j += 1;

        proof.quotient_polynomial_at_z = PairingsBn254.new_fr(
            serialized_proof[j]
        );

        j += 1;

        proof.linearization_polynomial_at_z = PairingsBn254.new_fr(
            serialized_proof[j]
        );

        j += 1;

        for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) {
            proof.permutation_polynomials_at_z[i] = PairingsBn254.new_fr(
                serialized_proof[j]
            );

            j += 1;
        }

        proof.opening_at_z_proof = PairingsBn254.new_g1_checked(
            serialized_proof[j],
            serialized_proof[j+1]
        );
        j += 2;

        proof.opening_at_z_omega_proof = PairingsBn254.new_g1_checked(
            serialized_proof[j],
            serialized_proof[j+1]
        );
    }
}

pragma solidity >=0.5.0 <0.7.0;

library PairingsBn254 {
    uint256 constant q_mod = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
    uint256 constant r_mod = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    uint256 constant bn254_b_coeff = 3;

    struct G1Point {
        uint256 X;
        uint256 Y;
    }

    struct Fr {
        uint256 value;
    }

    function new_fr(uint256 fr) internal pure returns (Fr memory) {
        require(fr < r_mod);
        return Fr({value: fr});
    }

    function copy(Fr memory self) internal pure returns (Fr memory n) {
        n.value = self.value;
    }

    function assign(Fr memory self, Fr memory other) internal pure {
        self.value = other.value;
    }

    function inverse(Fr memory fr) internal view returns (Fr memory) {
        require(fr.value != 0);
        return pow(fr, r_mod-2);
    }

    function add_assign(Fr memory self, Fr memory other) internal pure {
        self.value = addmod(self.value, other.value, r_mod);
    }

    function sub_assign(Fr memory self, Fr memory other) internal pure {
        self.value = addmod(self.value, r_mod - other.value, r_mod);
    }

    function mul_assign(Fr memory self, Fr memory other) internal pure {
        self.value = mulmod(self.value, other.value, r_mod);
    }

    function pow(Fr memory self, uint256 power) internal view returns (Fr memory) {
        uint256[6] memory input = [32, 32, 32, self.value, power, r_mod];
        uint256[1] memory result;
        bool success;
        assembly {
            success := staticcall(gas(), 0x05, input, 0xc0, result, 0x20)
        }
        require(success);
        return Fr({value: result[0]});
    }

    // Encoding of field elements is: X[0] * z + X[1]
    struct G2Point {
        uint[2] X;
        uint[2] Y;
    }

    function P1() internal pure returns (G1Point memory) {
        return G1Point(1, 2);
    }

    function new_g1(uint256 x, uint256 y) internal pure returns (G1Point memory) {
        return G1Point(x, y);
    }

    function new_g1_checked(uint256 x, uint256 y) internal pure returns (G1Point memory) {
        if (x == 0 && y == 0) {
            // point of infinity is (0,0)
            return G1Point(x, y);
        }

        // check encoding
        require(x < q_mod);
        require(y < q_mod);
        // check on curve
        uint256 lhs = mulmod(y, y, q_mod); // y^2
        uint256 rhs = mulmod(x, x, q_mod); // x^2
        rhs = mulmod(rhs, x, q_mod); // x^3
        rhs = addmod(rhs, bn254_b_coeff, q_mod); // x^3 + b
        require(lhs == rhs);

        return G1Point(x, y);
    }

    function new_g2(uint256[2] memory x, uint256[2] memory y) internal pure returns (G2Point memory) {
        return G2Point(x, y);
    }

    function copy_g1(G1Point memory self) internal pure returns (G1Point memory result) {
        result.X = self.X;
        result.Y = self.Y;
    }

    function P2() internal pure returns (G2Point memory) {
        // for some reason ethereum expects to have c1*v + c0 form

        return G2Point(
            [0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2,
            0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed],
            [0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b,
            0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa]
        );
    }

    function negate(G1Point memory self) internal pure {
        // The prime q in the base field F_q for G1
        if (self.Y == 0) {
            require(self.X == 0);
            return;
        }

        self.Y = q_mod - self.Y;
    }

    function point_add(G1Point memory p1, G1Point memory p2)
    internal view returns (G1Point memory r)
    {
        point_add_into_dest(p1, p2, r);
        return r;
    }

    function point_add_assign(G1Point memory p1, G1Point memory p2)
    internal view
    {
        point_add_into_dest(p1, p2, p1);
    }

    function point_add_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest)
    internal view
    {
        if (p2.X == 0 && p2.Y == 0) {
            // we add zero, nothing happens
            dest.X = p1.X;
            dest.Y = p1.Y;
            return;
        } else if (p1.X == 0 && p1.Y == 0) {
            // we add into zero, and we add non-zero point
            dest.X = p2.X;
            dest.Y = p2.Y;
            return;
        } else {
            uint256[4] memory input;

            input[0] = p1.X;
            input[1] = p1.Y;
            input[2] = p2.X;
            input[3] = p2.Y;

            bool success = false;
            assembly {
                success := staticcall(gas(), 6, input, 0x80, dest, 0x40)
            }
            require(success);
        }
    }

    function point_sub_assign(G1Point memory p1, G1Point memory p2)
    internal view
    {
        point_sub_into_dest(p1, p2, p1);
    }

    function point_sub_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest)
    internal view
    {
        if (p2.X == 0 && p2.Y == 0) {
            // we subtracted zero, nothing happens
            dest.X = p1.X;
            dest.Y = p1.Y;
            return;
        } else if (p1.X == 0 && p1.Y == 0) {
            // we subtract from zero, and we subtract non-zero point
            dest.X = p2.X;
            dest.Y = q_mod - p2.Y;
            return;
        } else {
            uint256[4] memory input;

            input[0] = p1.X;
            input[1] = p1.Y;
            input[2] = p2.X;
            input[3] = q_mod - p2.Y;

            bool success = false;
            assembly {
                success := staticcall(gas(), 6, input, 0x80, dest, 0x40)
            }
            require(success);
        }
    }

    function point_mul(G1Point memory p, Fr memory s)
    internal view returns (G1Point memory r)
    {
        point_mul_into_dest(p, s, r);
        return r;
    }

    function point_mul_assign(G1Point memory p, Fr memory s)
    internal view
    {
        point_mul_into_dest(p, s, p);
    }

    function point_mul_into_dest(G1Point memory p, Fr memory s, G1Point memory dest)
    internal view
    {
        uint[3] memory input;
        input[0] = p.X;
        input[1] = p.Y;
        input[2] = s.value;
        bool success;
        assembly {
            success := staticcall(gas(), 7, input, 0x60, dest, 0x40)
        }
        require(success);
    }

    function pairing(G1Point[] memory p1, G2Point[] memory p2)
    internal view returns (bool)
    {
        require(p1.length == p2.length);
        uint elements = p1.length;
        uint inputSize = elements * 6;
        uint[] memory input = new uint[](inputSize);
        for (uint i = 0; i < elements; i++)
        {
            input[i * 6 + 0] = p1[i].X;
            input[i * 6 + 1] = p1[i].Y;
            input[i * 6 + 2] = p2[i].X[0];
            input[i * 6 + 3] = p2[i].X[1];
            input[i * 6 + 4] = p2[i].Y[0];
            input[i * 6 + 5] = p2[i].Y[1];
        }
        uint[1] memory out;
        bool success;
        assembly {
            success := staticcall(gas(), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
        }
        require(success);
        return out[0] != 0;
    }

    /// Convenience method for a pairing check for two pairs.
    function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2)
    internal view returns (bool)
    {
        G1Point[] memory p1 = new G1Point[](2);
        G2Point[] memory p2 = new G2Point[](2);
        p1[0] = a1;
        p1[1] = b1;
        p2[0] = a2;
        p2[1] = b2;
        return pairing(p1, p2);
    }
}

library TranscriptLibrary {
    // flip                    0xe000000000000000000000000000000000000000000000000000000000000000;
    uint256 constant FR_MASK = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    uint32 constant DST_0 = 0;
    uint32 constant DST_1 = 1;
    uint32 constant DST_CHALLENGE = 2;

    struct Transcript {
        bytes32 state_0;
        bytes32 state_1;
        uint32 challenge_counter;
    }

    function new_transcript() internal pure returns (Transcript memory t) {
        t.state_0 = bytes32(0);
        t.state_1 = bytes32(0);
        t.challenge_counter = 0;
    }

    function update_with_u256(Transcript memory self, uint256 value) internal pure {
        bytes32 old_state_0 = self.state_0;
        self.state_0 = keccak256(abi.encodePacked(DST_0, old_state_0, self.state_1, value));
        self.state_1 = keccak256(abi.encodePacked(DST_1, old_state_0, self.state_1, value));
    }

    function update_with_fr(Transcript memory self, PairingsBn254.Fr memory value) internal pure {
        update_with_u256(self, value.value);
    }

    function update_with_g1(Transcript memory self, PairingsBn254.G1Point memory p) internal pure {
        update_with_u256(self, p.X);
        update_with_u256(self, p.Y);
    }

    function get_challenge(Transcript memory self) internal pure returns(PairingsBn254.Fr memory challenge) {
        bytes32 query = keccak256(abi.encodePacked(DST_CHALLENGE, self.state_0, self.state_1, self.challenge_counter));
        self.challenge_counter += 1;
        challenge = PairingsBn254.Fr({value: uint256(query) & FR_MASK});
    }
}

Settings
{
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  }
}

Contract Security Audit

Contract ABI

API
[{"constant":true,"inputs":[{"internalType":"bytes","name":"param1","type":"bytes"},{"internalType":"bytes","name":"param2","type":"bytes"}],"name":"concatBytes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"upgradeParameters","type":"bytes"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_rootHash","type":"bytes32"},{"internalType":"uint64","name":"_tokenId","type":"uint64"},{"internalType":"uint32","name":"_creatorId","type":"uint32"},{"internalType":"uint32","name":"_seqId","type":"uint32"},{"internalType":"bytes32","name":"_uri","type":"bytes32"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyExitNFTProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_rootHash","type":"bytes32"},{"internalType":"uint32","name":"_accountId","type":"uint32"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyExitProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_account_data","type":"bytes"},{"internalType":"bytes","name":"_pair_data0","type":"bytes"},{"internalType":"bytes","name":"_pair_data1","type":"bytes"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyLpExitProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]

0x608060405234801561001057600080fd5b50613a4a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80630bb0482f146100675780632539464514610090578063439fab9114610090578063ac95103d146100a5578063c81a27ad146100c5578063ea58ce3c146100d8575b600080fd5b61007a610075366004613570565b6100eb565b6040516100879190613820565b60405180910390f35b6100a361009e36600461347f565b6101d2565b005b6100b86100b33660046134c0565b6101d6565b6040516100879190613812565b6100b86100d3366004613324565b6103ba565b6100b86100e63660046133c8565b610503565b60608082518451016040519080825280601f01601f19166020018201604052801561011d576020820181803883390190505b5090506000805b85518110156101735785818151811061013957fe5b602001015160f81c60f81b83838151811061015057fe5b60200101906001600160f81b031916908160001a90535060019182019101610124565b5060005b84518110156101c65784818151811061018c57fe5b602001015160f81c60f81b8383815181106101a357fe5b60200101906001600160f81b031916908160001a90535060019182019101610177565b50909150505b92915050565b5050565b6000606061024d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b90819084018382808284376000920191909152506100eb92505050565b905060606102918288888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100eb92505050565b905060006002826040516102a59190613776565b602060405180830381855afa1580156102c2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506102e591908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061032557fe5b602002602001018181525050610339612e5d565b610376838a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610380612eff565b6103886108fb565b9050835181602001511461039b57600080fd5b6103a58282610db9565b97505050505050505098975050505050505050565b600080600289898989896040516020016103d89594939291906136b3565b60408051601f19818403018152908290526103f291613776565b602060405180830381855afa15801561040f573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061043291908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061047257fe5b602002602001018181525050610486612e5d565b6104c38388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b90506104cd612eff565b6104d5610df6565b905083518160200151146104e857600080fd5b6104f28282610db9565b9d9c50505050505050505050505050565b60008060028a8a8a8a8a8a6040516020016105239695949392919061370c565b60408051601f198184030181529082905261053d91613776565b602060405180830381855afa15801561055a573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061057d91908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b0391848316915083906000906105bd57fe5b6020026020010181815250506105d1612e5d565b61060e8388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610618612eff565b6106206111b7565b9050835181602001511461063357600080fd5b61063d8282610db9565b9e9d5050505050505050505050505050565b610657612e5d565b602182511461066557600080fd5b8251604051908082528060200260200182016040528015610690578160200160208202803883390190505b50815260005b83518110156106d6578381815181106106ab57fe5b6020026020010151826000015182815181106106c357fe5b6020908102919091010152600101610696565b506000805b600481101561073b576107178483815181106106f357fe5b602002602001015185846001018151811061070a57fe5b6020026020010151611578565b8360200151826004811061072757fe5b6020020152600291909101906001016106db565b5061076283828151811061074b57fe5b602002602001015184836001018151811061070a57fe5b604083015260020160005b60048110156107a9576107858483815181106106f357fe5b8360600151826004811061079557fe5b60200201526002919091019060010161076d565b5060005b60048110156107f3576107d28483815181106107c557fe5b602002602001015161165a565b836080015182600481106107e257fe5b6020020152600191820191016107ad565b5060005b60018110156108305761080f8483815181106107c557fe5b8360a00151826001811061081f57fe5b6020020152600191820191016107f7565b506108408382815181106107c557fe5b8260c0018190525060018101905061085d8382815181106107c557fe5b8260e0018190525060018101905061087a8382815181106107c557fe5b61010083015260010160005b60038110156108c05761089e8483815181106107c557fe5b83610120015182600381106108af57fe5b602002015260019182019101610886565b506108d083828151811061074b57fe5b8261014001819052506002810190506108ee83828151811061074b57fe5b6101608301525092915050565b610903612eff565b620800008152600160208201526109397f0cf1526aaafac6bacbb67d11a4077806b123f767e4b0883d14cc0193568fc08261165a565b60408201526109887f26aafba448a6c22abfa5286eef01b17a6bffaacf20a8a0fca1a59035c8e45ddd7f160835d2c20ea81f2f4c2c7f1644e30ae41b2541588a27552c08c190d5b32af861168e565b6060820151526109d87f20954e6cd2ad660dd9723263311b03986d6f8993ebfeb67a60a46608b35701fe7f059ce6f6469bb72b8758473f86e86a959c4b9f74193d931dd172883c641a25c761168e565b606082015160200152610a2b7f26245ff891a4328caa0da951efba1b5b3cc13136cd315ac7c8794053e47a43157f1681b7685491b5f8fb470a21a326bc91bd75178d411ead030aefcddd9b51bd0661168e565b606082015160400152610a7e7f2857e4543592da2693e7e97477f186736c4a0a325bd9477bbd996819dc0ca4ce7f0ffe00e34dd8592675469bb7a92b1e78e7c9e4ace22343605fb3a48dd4f1597061168e565b6060828101510152610ad07f0180059910e776f202efcb1b96d72ab597e811caef2a9af5d8b42fc79949d9137f1a43d65fba7b7340f6cb120a31ad0a1d5a26e0a1151398d9a80d6930e623be2161168e565b606082015160800152610b227e7b755d547d62eaf1375f3efe8a62ef52ed1b40ef2ec0943ab9a1de7198f2747f28f96cb876dc97aada23aa73d202682e3f29a29126d5711df0747234660cd83d61168e565b606082015160a00152610b747edfc41dc088a145be5a6978121abea7dffaef90012b9d6f1b577e957a28dd247f2ef1b64e6b0afe751b5531869a17dd9d5c90d734880de7fed3d3ae74a01d989a61168e565b608082015152610bc47f1d69be00b5e7d9d2af9d10da25eda41333effe6b9435caefe07ddae096d30ddf7f162137b0ead7f1be6f448f36db186c5bee0e44f19a926e88b53f7760b64e9dbd61168e565b60a082015152610c147f179c8e2df764ec8a2a5f5dbd37ffdde057178b6c10ef04bbb3331a78439343317f1a71e27ade54b801c811bd10d93c2b9e6c80bfea3d808487cf375f50e065e89661168e565b60a082015160200152610c677f2fc48aa7bcba72e922843e8732398afe655368a3aedca1f204b0e1bd9ddbf9817f2f6adc4261e3dd2fc80affdb39de386de5c38aa0066a8560f76dff220341071a61168e565b60a082015160400152610cba7f2a096bb764588fb3f422291918e33c1d8d9f5a8ef6c9cf41d288a5ddea0cf26a7f1e2ab7435be44f4101b1af83f76d5b621f4ecdd9d673a4b019ffb41072413f9b61168e565b60a082015160600152610ccd600561165a565b60c082015152610cdd600761165a565b60c082015160200152610cf0600a61165a565b60c082015160026020020181905250610db160405180604001604052807f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c181526020017f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b081525060405180604001604052807f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe481526020017f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e558152506116ac565b60e082015290565b6000610dc3612f62565b6000610dd08286866116b4565b905080610de2576000925050506101cc565b610ded82868661198c565b95945050505050565b610dfe612eff565b62040000815260016020820152610e347f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b6040820152610e837f135a8971e309397099f1c5c0b9c2a141e83b888ff0504ba8c9a7c13b8c66873f7f0eed3feed06aa8e4d3493aefd4c6f9a6c337e20b7e2f20d22b08b3b4129f8efc61168e565b606082015152610ed37f0b97dc8947583759347e13c8f2abdccf1004e13f771fe9c46155af71d336de2e7f1d39ffdb681fca7ce01b775e9aaaf5d8b71d9b7602ac00c60bbde91dca816dec61168e565b606082015160200152610f267f04b4d20919f8c66794a986ad27a0e4e820fb7a1bf863048017a59b1f7b3030f67f2da162d6902e64de2d4f6178f090bf9db7fbb9199d1640d5eab9c0a26869524f61168e565b606082015160400152610f797f242d28e776c833130fb04fb097c1c166c4293018e64947c46086f1bea21847327f277463020cda47c42366610a37cde00ef3a32b44906e1adee02fcd66bbe44a7561168e565b6060828101510152610fcb7f24d289d00964c5501b4a32521df5685264fb490a4549e794f998f18f169f31957f14307765ce1383efab72009df36fd97d28b94c9c1fce57a64697e5633d8d4e0d61168e565b60608201516080015261101e7f0c3697df5aef9952def7b12d29447e9ae12fe6580f0e00399237bee51a5fa0e07f2b120b7d414a0843aa2e9e606bcec5ff8eb3c38d8b73479de42fc8901bb626e661168e565b606082015160a001526110717f0e09a50a8e0635250a3a200dab94a1a51de811b179f61df2d4683e59fd1774ee7f251732ea6c2951b7b54f2dbc349b14db2b63def8d132f86499d2e43edc21ad5161168e565b6080820151526110c17f1889e41a3cebf0b097ec6cef8849e66480c344c422ed9a2e4d63fe75155af0d07f0ed098f479a2f229cd47f645517737f512612915010cb576398cd4ec7c803baf61168e565b60a0820151526111117f141171280664b7aea2c65ddb87f28391cab60913a74f4255b3dd4295d162a02c7f033c1cc5f1e58a035eb5f3951e79cc90e9fccf3c82781c2553b1d49694a1899161168e565b60a0820151602001526111647f0fc9a25cc839ef11afab0a9f320cf2b7346054f566135611bb25b6cec46205b37f16ea53198b77ab1e469d166b36d89d9fd88b3c356958cdf377a534d73f47a9a361168e565b60a082015160400152610cba7f2040345b5f92cc70a9607cf5fc28e5be26f673852450488d4e65f70890649b457f2c0e0bf512b4aa690449b589513e2b34cbc5e748a4217947331e0350c73be31061168e565b6111bf612eff565b620400008152600160208201526111f57f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b60408201526112447f27ad08e12b6087f6fe0d7e1d8d8f14f53e92aaabf05e4f7d1051b0fbe3db046d7f11f1f49ccf9f433366c3dc71fe9efa794678b87cbb2b07deea0cfbb7093e536961168e565b6060820151526112947f1ee701b0be61332b7de5d4260ad352a3f50a8e51ac4a761f6ab5077c8dffab517f21451115294a50d06c5c442e9a61b04699fd8f296e70ef00e78a5908ef54144461168e565b6060820151602001526112e77f1eccd5e119cc4a7bc8d274e0d8f61a054ee38694796790dacd22a098642bf2bc7f10bb95ce678a633560f0a704001e4c148aff47b7aee0856bfec735fb13884e0261168e565b60608201516040015261133a7f013fa8820794811964f35f04adb7600a9a3c76c9960b9cbb162b8324e09a14f57f0c110889cdf3554c95c7876f3e9d64804b3f0a6effa2baaf8bcb4ca847e5ed1d61168e565b606082810151015261138c7f1d5d922608eb262a5b05dc872b81238a352ba3521a1e847b06606d0937c7a34c7f291cd60f7f242bd5e1075f99ed70583f40460758aa58c8cd418cb5b6929e8c1261168e565b6060820151608001526113df7f2bc438c9650f27fd6b4125e098c5d87f874cfd29efad4a3e4ecae04e23b050097f283af270ef1c1c897e85b844536745dbf4d744f2e0fe8dc113143b5209a60baa61168e565b606082015160a001526114327f16f50151d8dccdd5e06a29eee62a9f614d534c542640bee31e9e9a3f2b708a837f120854cacf85957ca9777576bda620a21312769ab9596c7c64dc74215683988261168e565b6080820151526114827f27d2cd3c7a778fed777f6410fca3a65521282818e187e901827b1e666281d38b7f1f5484c3976cadaea11704759c33ecfffe4900b696febcffb397ec15324c484a61168e565b60a0820151526114d27f26a13c2a6968f979cfc4ef24b965487c5f22f2dfc5e9008942fa32bbb72f7b3c7f2bbb803702a9e0c0d4e3a078e2ffa2c525165f940a551555efbdd8876cc3f06e61168e565b60a0820151602001526115257f17210a663b894d0d08db4ba0f2da65bf67b5e4c94317d03e0eb6077b11e849ef7f2c98fb45631bd244290296ce55afc885e0e3cc96b506037183338141e97fdf6161168e565b60a082015160400152610cba7f1ef739c21d81d82ecb30445c5c6e775597aed256ee615b84c71dff243c81dd9e7f072138b9876fc2f52d29b5cf35478fe4091f384c034fa59ab4b29deb69e9828161168e565b611580612fc3565b8215801561158c575081155b156115ad5760405180604001604052808481526020018381525090506101cc565b6000805160206139c883398151915283106115c757600080fd5b6000805160206139c883398151915282106115e157600080fd5b60006000805160206139c8833981519152838409905060006000805160206139c883398151915285860990506000805160206139c883398151915285820990506000805160206139c883398151915260038208905080821461164257600080fd5b50506040805180820190915292835250602082015290565b611662612fdd565b6000805160206139e8833981519152821061167c57600080fd5b50604080516020810190915290815290565b611696612fc3565b5060408051808201909152918252602082015290565b611696612ff0565b6020810151825151600091146116c957600080fd5b81602001516001146116da57600080fd5b6116e2613010565b6116ea611ecc565b905060005b836020015181101561172d576117258560000151828151811061170e57fe5b602002602001015183611ee890919063ffffffff16565b6001016116ef565b5060005b60048110156117675761175f8560200151826004811061174d57fe5b6020020151839063ffffffff611f5b16565b600101611731565b5061177181611f77565b602086015261177f81611f77565b60408087019190915284015161179c90829063ffffffff611f5b16565b6117a581611f77565b855260005b60048110156117ce576117c68560600151826004811061174d57fe5b6001016117aa565b506117d881611f77565b60a086015260408051600180825281830190925290816020015b6117fa612fdd565b8152602001906001900390816117f257505060c08601528251604084015160a087015161182b926000929091611fe8565b8560c0015160008151811061183c57fe5b602002602001018190525060006118548686866120c9565b90508061186657600092505050611985565b60005b600481101561189f576118978660800151826004811061188557fe5b6020020151849063ffffffff61232216565b600101611869565b5060005b60018110156118c7576118bf8660a00151826001811061188557fe5b6001016118a3565b5060005b60038110156118f0576118e8866101200151826003811061188557fe5b6001016118cb565b5060e085015161190790839063ffffffff61232216565b61010085015161191e90839063ffffffff61232216565b60c085015161193490839063ffffffff61232216565b61193d82611f77565b606087015261014085015161195990839063ffffffff611f5b16565b61016085015161197090839063ffffffff611f5b16565b61197982611f77565b60808701525060019150505b9392505050565b6000611996612fc3565b6119a1858585612330565b90506119ab612fdd565b835160a08701516119c19163ffffffff61274116565b90506119cb612fc3565b6119d36127cd565b90506119dd612fdd565b6119e7600161165a565b90506119f1612fc3565b6060880151611a079060005b60200201516127ee565b9050611a11612fdd565b611a1b600161165a565b905060015b6004811015611a7857611a39828763ffffffff61280a16565b611a5e828b606001518360048110611a4d57fe5b60200201519063ffffffff61282416565b9450611a70838663ffffffff61283716565b600101611a20565b5060608a0151611a8f90849063ffffffff61280a16565b611a9f828763ffffffff61283716565b60005b6004811015611aef5760608b0151611ac190859063ffffffff61280a16565b611ad5848b602001518360048110611a4d57fe5b9450611ae7838663ffffffff61283716565b600101611aa2565b5060005b6003811015611b405760608b0151611b1290859063ffffffff61280a16565b611b26848a60a001518360048110611a4d57fe5b9450611b38838663ffffffff61283716565b600101611af3565b5060608a0151611b5790849063ffffffff61280a16565b60608a0151611b6d90849063ffffffff61280a16565b611b7d818463ffffffff61284216565b60808a0151611b9390829063ffffffff61280a16565b6020890151611ba59082906003611a4d565b9350611bb7828563ffffffff61283716565b611bc1600161165a565b9250611bcb612fdd565b611bd88a60e00151612847565b9050611bf18b606001518561280a90919063ffffffff16565b6101008a0151611c0890839063ffffffff61284216565b611c18828563ffffffff61280a16565b611c28818363ffffffff61285616565b60005b6004811015611c975760608c0151611c4a90869063ffffffff61280a16565b611c6f8b608001518260048110611c5d57fe5b6020020151849063ffffffff61284216565b611c7f838663ffffffff61280a16565b611c8f828463ffffffff61285616565b600101611c2b565b5060005b6003811015611cf65760608c0151611cba90869063ffffffff61280a16565b611cce8b61012001518260038110611c5d57fe5b611cde838663ffffffff61280a16565b611cee828463ffffffff61285616565b600101611c9b565b5060608b0151611d0d90859063ffffffff61280a16565b60c08a0151611d2390839063ffffffff61284216565b611d33828563ffffffff61280a16565b60808b0151611d4990839063ffffffff61280a16565b611d59818363ffffffff61285616565b60608b0151611d6f90859063ffffffff61280a16565b60a08a015151611d80908390612842565b611d90828563ffffffff61280a16565b60808b0151611da690839063ffffffff61280a16565b611db6818363ffffffff61285616565b611dde611dd182611dc56127cd565b9063ffffffff61282416565b849063ffffffff61287016565b611de6612fc3565b5060a08b01516101408b01518491611e1491611e079163ffffffff61282416565b829063ffffffff61283716565b60a08c0151611e2a90849063ffffffff61284216565b60408a0151611e4090849063ffffffff61280a16565b60808c0151611e5690849063ffffffff61280a16565b6101608b0151611e7090611e07908563ffffffff61282416565b611e78612fc3565b60808d01516101608d0151611e929163ffffffff61282416565b9050611eac8c61014001518261283790919063ffffffff16565b611eb58161287b565b6104f282611ec16128b1565b838e60e00151612971565b611ed4613010565b600080825260208201819052604082015290565b8151602080840151604051611f069260009285929091879101613782565b60408051601f1981840301815291815281516020928301208552848201519051611f399260019285929091879101613782565b60408051601f1981840301815291905280516020918201209301929092525050565b611f69828260000151611ee8565b6101d2828260200151611ee8565b611f7f612fdd565b60006002836000015184602001518560400151604051602001611fa594939291906137ca565b60408051808303601f190181529181528151602092830120948101805160010163ffffffff169052805191820190526001600160fd1b0390931683525090919050565b611ff0612fdd565b838510611ffc57600080fd5b612004612fdd565b61200e600161165a565b9050612018612fdd565b612028858863ffffffff61274116565b905061203a848763ffffffff61274116565b925061204c838363ffffffff612a5716565b825161205757600080fd5b612067838263ffffffff61280a16565b61206f612fdd565b61207885612847565b905061208a818363ffffffff612a5716565b6120a36120968861165a565b829063ffffffff61280a16565b6120ac81612a75565b90506120be848263ffffffff61280a16565b505050949350505050565b60006120d3612fdd565b6120e583600001518660a00151612ab2565b80519091506120f357600080fd5b60e084015161210990829063ffffffff61280a16565b612111612fdd565b61211b600161165a565b9050612125612fdd565b612133866101000151612847565b905061213d612fdd565b612147600061165a565b905060005b8751518110156121bb576121808960c00151828151811061216957fe5b60200260200101518361284290919063ffffffff16565b6121a3612196896000015183815181106107c557fe5b839063ffffffff61280a16565b6121b3838363ffffffff61285616565b60010161214c565b5087516121cf90849063ffffffff61280a16565b6121d7612fdd565b6121e48860c00151612847565b905060005b600381101561226f576122068961012001518260038110611c5d57fe5b60208a015161221c90849063ffffffff61280a16565b60408a015161223290849063ffffffff61285616565b6122578960800151826004811061224557fe5b6020020151849063ffffffff61285616565b612267828463ffffffff61280a16565b6001016121e9565b50604089015161228690839063ffffffff61284216565b60808801516060015161229a908390612856565b6122aa818363ffffffff61280a16565b6122ba818563ffffffff61280a16565b6122ca838263ffffffff612a5716565b88516122dd90859063ffffffff61280a16565b6122f18960c0015160008151811061216957fe5b612301828563ffffffff61280a16565b612311838363ffffffff612a5716565b505051915190911495945050505050565b6101d2828260000151611ee8565b612338612fc3565b606082015160099061234b9060056119fd565b9150612355612fc3565b61235d6127cd565b9050612367612fdd565b612371600061165a565b905060005b60048110156123c1576123a78760800151826004811061239257fe5b602002015187606001518360068110611a4d57fe5b92506123b9858463ffffffff61283716565b600101612376565b506080860151516123d3908290612842565b6080860151602001516123e790829061280a565b60608501516123f99082906004611a4d565b915061240b848363ffffffff61283716565b60a086015151608086015161242291906000611a4d565b9150612434848363ffffffff61283716565b61243c612fdd565b6124498860a00151612847565b905061246288602001518261280a90919063ffffffff16565b608087015151612473908290612856565b604088015161248990829063ffffffff61285616565b60005b600381101561252a5760a08901516124ab90849063ffffffff61284216565b6124d08760c0015182600381106124be57fe5b6020020151849063ffffffff61280a16565b60208901516124e690849063ffffffff61280a16565b60408901516124fc90849063ffffffff61285616565b6125128860800151826001016004811061224557fe5b612522828463ffffffff61280a16565b60010161248c565b50875161253e90829063ffffffff61280a16565b6125528860c0015160008151811061216957fe5b875161256590839063ffffffff61280a16565b875161257890839063ffffffff61280a16565b612588818363ffffffff61285616565b612590612fdd565b60608901516125a5908663ffffffff61274116565b90506125be89608001518261280a90919063ffffffff16565b6125c6612fdd565b6125d0600161165a565b905060005b600381101561266d5760208b01516125f490869063ffffffff61284216565b61261a8a6101200151826003811061260857fe5b6020020151869063ffffffff61280a16565b60408b015161263090869063ffffffff61285616565b6126558a60800151826004811061264357fe5b6020020151869063ffffffff61285616565b612665828663ffffffff61280a16565b6001016125d5565b5060208a015161268490829063ffffffff61280a16565b60c089015161269a90829063ffffffff61280a16565b89516126ad90829063ffffffff61280a16565b60408901516126c2908463ffffffff61282416565b60a08901519095506126e8906126db9083906003611a4d565b869063ffffffff61287016565b6126f8878663ffffffff61283716565b60608a015161270e90889063ffffffff612ae616565b604089015161273490612727908463ffffffff61282416565b889063ffffffff61283716565b5050505050509392505050565b612749612fdd565b612751613030565b6040518060c00160405280602081526020016020815260200160208152602001856000015181526020018481526020016000805160206139e8833981519152815250905061279d61304e565b600060208260c08560055afa9050806127b557600080fd5b50604080516020810190915290518152949350505050565b6127d5612fc3565b5060408051808201909152600181526002602082015290565b6127f6612fc3565b815181526020918201519181019190915290565b6000805160206139e8833981519152815183510990915250565b61282c612fc3565b6101cc838383612aed565b6101d2828284612b2f565b519052565b61284f612fdd565b9051815290565b6000805160206139e8833981519152815183510890915250565b6101d2828284612bc7565b60208101516128955780511561289057600080fd5b6128ae565b6020810180516000805160206139c88339815191520390525b50565b6128b9612ff0565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b82527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60208381019190915281019190915290565b60408051600280825260608281019093526000929190816020015b612994612fc3565b81526020019060019003908161298c57505060408051600280825260608083019093529293509091602082015b6129c9612ff0565b8152602001906001900390816129c157905050905086826000815181106129ec57fe5b60200260200101819052508482600181518110612a0557fe5b60200260200101819052508581600081518110612a1e57fe5b60200260200101819052508381600181518110612a3757fe5b6020026020010181905250612a4c8282612c61565b979650505050505050565b805182516000805160206139e8833981519152918203900890915250565b612a7d612fdd565b8151612a8857600080fd5b6101cc827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff612741565b612aba612fdd565b612aca828463ffffffff61274116565b90506101cc612ad9600161165a565b829063ffffffff612a5716565b6101d28282845b612af561306c565b835181526020840151816001602002015282518160026020020152600060408360608460075afa905080612b2857600080fd5b5050505050565b8151158015612b4057506020820151155b15612b58578251815260208084015190820152612bc2565b8251158015612b6957506020830151155b15612b81578151815260208083015190820152612bc2565b612b8961308a565b8351815260208085015181830152835160408301528301518160035b6020020152600060408360808460065afa905080612b2857600080fd5b505050565b8151158015612bd857506020820151155b15612bf0578251815260208084015190820152612bc2565b8251158015612c0157506020830151155b15612c2957815181526020808301516000805160206139c88339815191520390820152612bc2565b612c3161308a565b8351815260208085015181830152835160408301528301516000805160206139c883398151915203816003612ba5565b60008151835114612c7157600080fd5b8251604080516006830280825260c084028201602001909252606090828015612ca4578160200160208202803883390190505b50905060005b83811015612e2957868181518110612cbe57fe5b602002602001015160000151828260060260000181518110612cdc57fe5b602002602001018181525050868181518110612cf457fe5b602002602001015160200151828260060260010181518110612d1257fe5b602002602001018181525050858181518110612d2a57fe5b602090810291909101015151518251839060026006850201908110612d4b57fe5b602002602001018181525050858181518110612d6357fe5b60209081029190910101515160016020020151828260060260030181518110612d8857fe5b602002602001018181525050858181518110612da057fe5b602002602001015160200151600060028110612db857fe5b6020020151828260060260040181518110612dcf57fe5b602002602001018181525050858181518110612de757fe5b602002602001015160200151600160028110612dff57fe5b6020020151828260060260050181518110612e1657fe5b6020908102919091010152600101612caa565b50612e3261304e565b6000602082602086026020860160085afa905080612e4f57600080fd5b505115159695505050505050565b60405180610180016040528060608152602001612e786130a8565b8152602001612e85612fc3565b8152602001612e926130a8565b8152602001612e9f6130d5565b8152602001612eac613102565b8152602001612eb9612fdd565b8152602001612ec6612fdd565b8152602001612ed3612fdd565b8152602001612ee061312f565b8152602001612eed612fc3565b8152602001612efa612fc3565b905290565b6040518061010001604052806000815260200160008152602001612f21612fdd565b8152602001612f2e61315c565b8152602001612f3b613189565b8152602001612f486130a8565b8152602001612f5561312f565b8152602001612efa612ff0565b6040518060e00160405280612f75612fdd565b8152602001612f82612fdd565b8152602001612f8f612fdd565b8152602001612f9c612fdd565b8152602001612fa9612fdd565b8152602001612fb6612fdd565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060200160405280600081525090565b60405180604001604052806130036131b6565b8152602001612efa6131b6565b604080516060810182526000808252602082018190529181019190915290565b6040518060c001604052806006906020820280388339509192915050565b60405180602001604052806001906020820280388339509192915050565b60405180606001604052806003906020820280388339509192915050565b60405180608001604052806004906020820280388339509192915050565b60405180608001604052806004905b6130bf612fc3565b8152602001906001900390816130b75790505090565b60405180608001604052806004905b6130ec612fdd565b8152602001906001900390816130e45790505090565b60405180602001604052806001905b613119612fdd565b8152602001906001900390816131115790505090565b60405180606001604052806003905b613146612fdd565b81526020019060019003908161313e5790505090565b6040518060c001604052806006905b613173612fc3565b81526020019060019003908161316b5790505090565b60405180602001604052806001905b6131a0612fc3565b8152602001906001900390816131985790505090565b60405180604001604052806002906020820280388339509192915050565b80356101cc81613986565b60008083601f8401126131f157600080fd5b5081356001600160401b0381111561320857600080fd5b60208301915083602082028301111561322057600080fd5b9250929050565b80356101cc8161399a565b80516101cc8161399a565b60008083601f84011261324f57600080fd5b5081356001600160401b0381111561326657600080fd5b60208301915083600182028301111561322057600080fd5b600082601f83011261328f57600080fd5b81356132a261329d82613857565b613831565b915080825260208301602083018583830111156132be57600080fd5b6132c98382846138e0565b50505092915050565b80356101cc816139a3565b80356101cc816139ac565b80356101cc816139b5565b80356101cc816139be565b60006020828403121561331057600080fd5b600061331c8484613232565b949350505050565b600080600080600080600060c0888a03121561333f57600080fd5b600061334b8a8a613227565b975050602061335c8a828b016132e8565b965050604061336d8a828b016131d4565b955050606061337e8a828b016132dd565b945050608061338f8a828b016132d2565b93505060a08801356001600160401b038111156133ab57600080fd5b6133b78a828b016131df565b925092505092959891949750929550565b60008060008060008060008060e0898b0312156133e457600080fd5b60006133f08b8b613227565b98505060206134018b828c016132f3565b97505060406134128b828c016132e8565b96505060606134238b828c016132e8565b95505060806134348b828c01613227565b94505060a06134458b828c016131d4565b93505060c08901356001600160401b0381111561346157600080fd5b61346d8b828c016131df565b92509250509295985092959890939650565b6000806020838503121561349257600080fd5b82356001600160401b038111156134a857600080fd5b6134b48582860161323d565b92509250509250929050565b6000806000806000806000806080898b0312156134dc57600080fd5b88356001600160401b038111156134f257600080fd5b6134fe8b828c0161323d565b985098505060208901356001600160401b0381111561351c57600080fd5b6135288b828c0161323d565b965096505060408901356001600160401b0381111561354657600080fd5b6135528b828c0161323d565b945094505060608901356001600160401b0381111561346157600080fd5b6000806040838503121561358357600080fd5b82356001600160401b0381111561359957600080fd5b6135a58582860161327e565b92505060208301356001600160401b038111156135c157600080fd5b6135cd8582860161327e565b9150509250929050565b6135e86135e382613890565b61391c565b82525050565b6135e88161389b565b6135e8613603826138a0565b6138a0565b60006136138261387e565b61361d8185613882565b935061362d8185602086016138ec565b6136368161395e565b9093019392505050565b600061364b8261387e565b613655818561388b565b93506136658185602086016138ec565b9290920192915050565b6135e861367b826138a3565b613927565b6135e861368c826138b8565b613932565b6135e861369d826138cb565b613948565b6135e86136ae826138d4565b613953565b60006136bf82886135f7565b6020820191506136cf8287613691565b6004820191506136df82866135d7565b6014820191506136ef8285613680565b6002820191506136ff828461366f565b5060100195945050505050565b600061371882896135f7565b60208201915061372882886136a2565b6008820191506137388287613691565b6004820191506137488286613691565b60048201915061375882856135f7565b60208201915061376882846135d7565b506014019695505050505050565b60006119858284613640565b600061378e8287613691565b60048201915061379e82866135f7565b6020820191506137ae82856135f7565b6020820191506137be82846135f7565b50602001949350505050565b60006137d68287613691565b6004820191506137e682866135f7565b6020820191506137f682856135f7565b6020820191506138068284613691565b50600401949350505050565b602081016101cc82846135ee565b602080825281016119858184613608565b6040518181016001600160401b038111828210171561384f57600080fd5b604052919050565b60006001600160401b0382111561386d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b919050565b60006101cc826138bf565b151590565b90565b6fffffffffffffffffffffffffffffffff1690565b61ffff1690565b6001600160a01b031690565b63ffffffff1690565b6001600160401b031690565b82818337506000910152565b60005b838110156139075781810151838201526020016138ef565b83811115613916576000848401525b50505050565b60006101cc8261393d565b60006101cc82613968565b60006101cc8261397a565b60006101cc82613980565b60006101cc82613974565b60006101cc8261396e565b601f01601f191690565b60801b90565b60c01b90565b60e01b90565b60f01b90565b60601b90565b61398f81613890565b81146128ae57600080fd5b61398f816138a0565b61398f816138a3565b61398f816138b8565b61398f816138cb565b61398f816138d456fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a365627a7a72315820d4b1b0c8b8faf3db02641cc60cf25dce191cd6a2f14fcb0d486f616f4f5deada6c6578706572696d656e74616cf564736f6c63430005100040

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100625760003560e01c80630bb0482f146100675780632539464514610090578063439fab9114610090578063ac95103d146100a5578063c81a27ad146100c5578063ea58ce3c146100d8575b600080fd5b61007a610075366004613570565b6100eb565b6040516100879190613820565b60405180910390f35b6100a361009e36600461347f565b6101d2565b005b6100b86100b33660046134c0565b6101d6565b6040516100879190613812565b6100b86100d3366004613324565b6103ba565b6100b86100e63660046133c8565b610503565b60608082518451016040519080825280601f01601f19166020018201604052801561011d576020820181803883390190505b5090506000805b85518110156101735785818151811061013957fe5b602001015160f81c60f81b83838151811061015057fe5b60200101906001600160f81b031916908160001a90535060019182019101610124565b5060005b84518110156101c65784818151811061018c57fe5b602001015160f81c60f81b8383815181106101a357fe5b60200101906001600160f81b031916908160001a90535060019182019101610177565b50909150505b92915050565b5050565b6000606061024d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b90819084018382808284376000920191909152506100eb92505050565b905060606102918288888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100eb92505050565b905060006002826040516102a59190613776565b602060405180830381855afa1580156102c2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506102e591908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061032557fe5b602002602001018181525050610339612e5d565b610376838a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610380612eff565b6103886108fb565b9050835181602001511461039b57600080fd5b6103a58282610db9565b97505050505050505098975050505050505050565b600080600289898989896040516020016103d89594939291906136b3565b60408051601f19818403018152908290526103f291613776565b602060405180830381855afa15801561040f573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061043291908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061047257fe5b602002602001018181525050610486612e5d565b6104c38388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b90506104cd612eff565b6104d5610df6565b905083518160200151146104e857600080fd5b6104f28282610db9565b9d9c50505050505050505050505050565b60008060028a8a8a8a8a8a6040516020016105239695949392919061370c565b60408051601f198184030181529082905261053d91613776565b602060405180830381855afa15801561055a573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061057d91908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b0391848316915083906000906105bd57fe5b6020026020010181815250506105d1612e5d565b61060e8388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610618612eff565b6106206111b7565b9050835181602001511461063357600080fd5b61063d8282610db9565b9e9d5050505050505050505050505050565b610657612e5d565b602182511461066557600080fd5b8251604051908082528060200260200182016040528015610690578160200160208202803883390190505b50815260005b83518110156106d6578381815181106106ab57fe5b6020026020010151826000015182815181106106c357fe5b6020908102919091010152600101610696565b506000805b600481101561073b576107178483815181106106f357fe5b602002602001015185846001018151811061070a57fe5b6020026020010151611578565b8360200151826004811061072757fe5b6020020152600291909101906001016106db565b5061076283828151811061074b57fe5b602002602001015184836001018151811061070a57fe5b604083015260020160005b60048110156107a9576107858483815181106106f357fe5b8360600151826004811061079557fe5b60200201526002919091019060010161076d565b5060005b60048110156107f3576107d28483815181106107c557fe5b602002602001015161165a565b836080015182600481106107e257fe5b6020020152600191820191016107ad565b5060005b60018110156108305761080f8483815181106107c557fe5b8360a00151826001811061081f57fe5b6020020152600191820191016107f7565b506108408382815181106107c557fe5b8260c0018190525060018101905061085d8382815181106107c557fe5b8260e0018190525060018101905061087a8382815181106107c557fe5b61010083015260010160005b60038110156108c05761089e8483815181106107c557fe5b83610120015182600381106108af57fe5b602002015260019182019101610886565b506108d083828151811061074b57fe5b8261014001819052506002810190506108ee83828151811061074b57fe5b6101608301525092915050565b610903612eff565b620800008152600160208201526109397f0cf1526aaafac6bacbb67d11a4077806b123f767e4b0883d14cc0193568fc08261165a565b60408201526109887f26aafba448a6c22abfa5286eef01b17a6bffaacf20a8a0fca1a59035c8e45ddd7f160835d2c20ea81f2f4c2c7f1644e30ae41b2541588a27552c08c190d5b32af861168e565b6060820151526109d87f20954e6cd2ad660dd9723263311b03986d6f8993ebfeb67a60a46608b35701fe7f059ce6f6469bb72b8758473f86e86a959c4b9f74193d931dd172883c641a25c761168e565b606082015160200152610a2b7f26245ff891a4328caa0da951efba1b5b3cc13136cd315ac7c8794053e47a43157f1681b7685491b5f8fb470a21a326bc91bd75178d411ead030aefcddd9b51bd0661168e565b606082015160400152610a7e7f2857e4543592da2693e7e97477f186736c4a0a325bd9477bbd996819dc0ca4ce7f0ffe00e34dd8592675469bb7a92b1e78e7c9e4ace22343605fb3a48dd4f1597061168e565b6060828101510152610ad07f0180059910e776f202efcb1b96d72ab597e811caef2a9af5d8b42fc79949d9137f1a43d65fba7b7340f6cb120a31ad0a1d5a26e0a1151398d9a80d6930e623be2161168e565b606082015160800152610b227e7b755d547d62eaf1375f3efe8a62ef52ed1b40ef2ec0943ab9a1de7198f2747f28f96cb876dc97aada23aa73d202682e3f29a29126d5711df0747234660cd83d61168e565b606082015160a00152610b747edfc41dc088a145be5a6978121abea7dffaef90012b9d6f1b577e957a28dd247f2ef1b64e6b0afe751b5531869a17dd9d5c90d734880de7fed3d3ae74a01d989a61168e565b608082015152610bc47f1d69be00b5e7d9d2af9d10da25eda41333effe6b9435caefe07ddae096d30ddf7f162137b0ead7f1be6f448f36db186c5bee0e44f19a926e88b53f7760b64e9dbd61168e565b60a082015152610c147f179c8e2df764ec8a2a5f5dbd37ffdde057178b6c10ef04bbb3331a78439343317f1a71e27ade54b801c811bd10d93c2b9e6c80bfea3d808487cf375f50e065e89661168e565b60a082015160200152610c677f2fc48aa7bcba72e922843e8732398afe655368a3aedca1f204b0e1bd9ddbf9817f2f6adc4261e3dd2fc80affdb39de386de5c38aa0066a8560f76dff220341071a61168e565b60a082015160400152610cba7f2a096bb764588fb3f422291918e33c1d8d9f5a8ef6c9cf41d288a5ddea0cf26a7f1e2ab7435be44f4101b1af83f76d5b621f4ecdd9d673a4b019ffb41072413f9b61168e565b60a082015160600152610ccd600561165a565b60c082015152610cdd600761165a565b60c082015160200152610cf0600a61165a565b60c082015160026020020181905250610db160405180604001604052807f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c181526020017f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b081525060405180604001604052807f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe481526020017f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e558152506116ac565b60e082015290565b6000610dc3612f62565b6000610dd08286866116b4565b905080610de2576000925050506101cc565b610ded82868661198c565b95945050505050565b610dfe612eff565b62040000815260016020820152610e347f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b6040820152610e837f135a8971e309397099f1c5c0b9c2a141e83b888ff0504ba8c9a7c13b8c66873f7f0eed3feed06aa8e4d3493aefd4c6f9a6c337e20b7e2f20d22b08b3b4129f8efc61168e565b606082015152610ed37f0b97dc8947583759347e13c8f2abdccf1004e13f771fe9c46155af71d336de2e7f1d39ffdb681fca7ce01b775e9aaaf5d8b71d9b7602ac00c60bbde91dca816dec61168e565b606082015160200152610f267f04b4d20919f8c66794a986ad27a0e4e820fb7a1bf863048017a59b1f7b3030f67f2da162d6902e64de2d4f6178f090bf9db7fbb9199d1640d5eab9c0a26869524f61168e565b606082015160400152610f797f242d28e776c833130fb04fb097c1c166c4293018e64947c46086f1bea21847327f277463020cda47c42366610a37cde00ef3a32b44906e1adee02fcd66bbe44a7561168e565b6060828101510152610fcb7f24d289d00964c5501b4a32521df5685264fb490a4549e794f998f18f169f31957f14307765ce1383efab72009df36fd97d28b94c9c1fce57a64697e5633d8d4e0d61168e565b60608201516080015261101e7f0c3697df5aef9952def7b12d29447e9ae12fe6580f0e00399237bee51a5fa0e07f2b120b7d414a0843aa2e9e606bcec5ff8eb3c38d8b73479de42fc8901bb626e661168e565b606082015160a001526110717f0e09a50a8e0635250a3a200dab94a1a51de811b179f61df2d4683e59fd1774ee7f251732ea6c2951b7b54f2dbc349b14db2b63def8d132f86499d2e43edc21ad5161168e565b6080820151526110c17f1889e41a3cebf0b097ec6cef8849e66480c344c422ed9a2e4d63fe75155af0d07f0ed098f479a2f229cd47f645517737f512612915010cb576398cd4ec7c803baf61168e565b60a0820151526111117f141171280664b7aea2c65ddb87f28391cab60913a74f4255b3dd4295d162a02c7f033c1cc5f1e58a035eb5f3951e79cc90e9fccf3c82781c2553b1d49694a1899161168e565b60a0820151602001526111647f0fc9a25cc839ef11afab0a9f320cf2b7346054f566135611bb25b6cec46205b37f16ea53198b77ab1e469d166b36d89d9fd88b3c356958cdf377a534d73f47a9a361168e565b60a082015160400152610cba7f2040345b5f92cc70a9607cf5fc28e5be26f673852450488d4e65f70890649b457f2c0e0bf512b4aa690449b589513e2b34cbc5e748a4217947331e0350c73be31061168e565b6111bf612eff565b620400008152600160208201526111f57f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b60408201526112447f27ad08e12b6087f6fe0d7e1d8d8f14f53e92aaabf05e4f7d1051b0fbe3db046d7f11f1f49ccf9f433366c3dc71fe9efa794678b87cbb2b07deea0cfbb7093e536961168e565b6060820151526112947f1ee701b0be61332b7de5d4260ad352a3f50a8e51ac4a761f6ab5077c8dffab517f21451115294a50d06c5c442e9a61b04699fd8f296e70ef00e78a5908ef54144461168e565b6060820151602001526112e77f1eccd5e119cc4a7bc8d274e0d8f61a054ee38694796790dacd22a098642bf2bc7f10bb95ce678a633560f0a704001e4c148aff47b7aee0856bfec735fb13884e0261168e565b60608201516040015261133a7f013fa8820794811964f35f04adb7600a9a3c76c9960b9cbb162b8324e09a14f57f0c110889cdf3554c95c7876f3e9d64804b3f0a6effa2baaf8bcb4ca847e5ed1d61168e565b606082810151015261138c7f1d5d922608eb262a5b05dc872b81238a352ba3521a1e847b06606d0937c7a34c7f291cd60f7f242bd5e1075f99ed70583f40460758aa58c8cd418cb5b6929e8c1261168e565b6060820151608001526113df7f2bc438c9650f27fd6b4125e098c5d87f874cfd29efad4a3e4ecae04e23b050097f283af270ef1c1c897e85b844536745dbf4d744f2e0fe8dc113143b5209a60baa61168e565b606082015160a001526114327f16f50151d8dccdd5e06a29eee62a9f614d534c542640bee31e9e9a3f2b708a837f120854cacf85957ca9777576bda620a21312769ab9596c7c64dc74215683988261168e565b6080820151526114827f27d2cd3c7a778fed777f6410fca3a65521282818e187e901827b1e666281d38b7f1f5484c3976cadaea11704759c33ecfffe4900b696febcffb397ec15324c484a61168e565b60a0820151526114d27f26a13c2a6968f979cfc4ef24b965487c5f22f2dfc5e9008942fa32bbb72f7b3c7f2bbb803702a9e0c0d4e3a078e2ffa2c525165f940a551555efbdd8876cc3f06e61168e565b60a0820151602001526115257f17210a663b894d0d08db4ba0f2da65bf67b5e4c94317d03e0eb6077b11e849ef7f2c98fb45631bd244290296ce55afc885e0e3cc96b506037183338141e97fdf6161168e565b60a082015160400152610cba7f1ef739c21d81d82ecb30445c5c6e775597aed256ee615b84c71dff243c81dd9e7f072138b9876fc2f52d29b5cf35478fe4091f384c034fa59ab4b29deb69e9828161168e565b611580612fc3565b8215801561158c575081155b156115ad5760405180604001604052808481526020018381525090506101cc565b6000805160206139c883398151915283106115c757600080fd5b6000805160206139c883398151915282106115e157600080fd5b60006000805160206139c8833981519152838409905060006000805160206139c883398151915285860990506000805160206139c883398151915285820990506000805160206139c883398151915260038208905080821461164257600080fd5b50506040805180820190915292835250602082015290565b611662612fdd565b6000805160206139e8833981519152821061167c57600080fd5b50604080516020810190915290815290565b611696612fc3565b5060408051808201909152918252602082015290565b611696612ff0565b6020810151825151600091146116c957600080fd5b81602001516001146116da57600080fd5b6116e2613010565b6116ea611ecc565b905060005b836020015181101561172d576117258560000151828151811061170e57fe5b602002602001015183611ee890919063ffffffff16565b6001016116ef565b5060005b60048110156117675761175f8560200151826004811061174d57fe5b6020020151839063ffffffff611f5b16565b600101611731565b5061177181611f77565b602086015261177f81611f77565b60408087019190915284015161179c90829063ffffffff611f5b16565b6117a581611f77565b855260005b60048110156117ce576117c68560600151826004811061174d57fe5b6001016117aa565b506117d881611f77565b60a086015260408051600180825281830190925290816020015b6117fa612fdd565b8152602001906001900390816117f257505060c08601528251604084015160a087015161182b926000929091611fe8565b8560c0015160008151811061183c57fe5b602002602001018190525060006118548686866120c9565b90508061186657600092505050611985565b60005b600481101561189f576118978660800151826004811061188557fe5b6020020151849063ffffffff61232216565b600101611869565b5060005b60018110156118c7576118bf8660a00151826001811061188557fe5b6001016118a3565b5060005b60038110156118f0576118e8866101200151826003811061188557fe5b6001016118cb565b5060e085015161190790839063ffffffff61232216565b61010085015161191e90839063ffffffff61232216565b60c085015161193490839063ffffffff61232216565b61193d82611f77565b606087015261014085015161195990839063ffffffff611f5b16565b61016085015161197090839063ffffffff611f5b16565b61197982611f77565b60808701525060019150505b9392505050565b6000611996612fc3565b6119a1858585612330565b90506119ab612fdd565b835160a08701516119c19163ffffffff61274116565b90506119cb612fc3565b6119d36127cd565b90506119dd612fdd565b6119e7600161165a565b90506119f1612fc3565b6060880151611a079060005b60200201516127ee565b9050611a11612fdd565b611a1b600161165a565b905060015b6004811015611a7857611a39828763ffffffff61280a16565b611a5e828b606001518360048110611a4d57fe5b60200201519063ffffffff61282416565b9450611a70838663ffffffff61283716565b600101611a20565b5060608a0151611a8f90849063ffffffff61280a16565b611a9f828763ffffffff61283716565b60005b6004811015611aef5760608b0151611ac190859063ffffffff61280a16565b611ad5848b602001518360048110611a4d57fe5b9450611ae7838663ffffffff61283716565b600101611aa2565b5060005b6003811015611b405760608b0151611b1290859063ffffffff61280a16565b611b26848a60a001518360048110611a4d57fe5b9450611b38838663ffffffff61283716565b600101611af3565b5060608a0151611b5790849063ffffffff61280a16565b60608a0151611b6d90849063ffffffff61280a16565b611b7d818463ffffffff61284216565b60808a0151611b9390829063ffffffff61280a16565b6020890151611ba59082906003611a4d565b9350611bb7828563ffffffff61283716565b611bc1600161165a565b9250611bcb612fdd565b611bd88a60e00151612847565b9050611bf18b606001518561280a90919063ffffffff16565b6101008a0151611c0890839063ffffffff61284216565b611c18828563ffffffff61280a16565b611c28818363ffffffff61285616565b60005b6004811015611c975760608c0151611c4a90869063ffffffff61280a16565b611c6f8b608001518260048110611c5d57fe5b6020020151849063ffffffff61284216565b611c7f838663ffffffff61280a16565b611c8f828463ffffffff61285616565b600101611c2b565b5060005b6003811015611cf65760608c0151611cba90869063ffffffff61280a16565b611cce8b61012001518260038110611c5d57fe5b611cde838663ffffffff61280a16565b611cee828463ffffffff61285616565b600101611c9b565b5060608b0151611d0d90859063ffffffff61280a16565b60c08a0151611d2390839063ffffffff61284216565b611d33828563ffffffff61280a16565b60808b0151611d4990839063ffffffff61280a16565b611d59818363ffffffff61285616565b60608b0151611d6f90859063ffffffff61280a16565b60a08a015151611d80908390612842565b611d90828563ffffffff61280a16565b60808b0151611da690839063ffffffff61280a16565b611db6818363ffffffff61285616565b611dde611dd182611dc56127cd565b9063ffffffff61282416565b849063ffffffff61287016565b611de6612fc3565b5060a08b01516101408b01518491611e1491611e079163ffffffff61282416565b829063ffffffff61283716565b60a08c0151611e2a90849063ffffffff61284216565b60408a0151611e4090849063ffffffff61280a16565b60808c0151611e5690849063ffffffff61280a16565b6101608b0151611e7090611e07908563ffffffff61282416565b611e78612fc3565b60808d01516101608d0151611e929163ffffffff61282416565b9050611eac8c61014001518261283790919063ffffffff16565b611eb58161287b565b6104f282611ec16128b1565b838e60e00151612971565b611ed4613010565b600080825260208201819052604082015290565b8151602080840151604051611f069260009285929091879101613782565b60408051601f1981840301815291815281516020928301208552848201519051611f399260019285929091879101613782565b60408051601f1981840301815291905280516020918201209301929092525050565b611f69828260000151611ee8565b6101d2828260200151611ee8565b611f7f612fdd565b60006002836000015184602001518560400151604051602001611fa594939291906137ca565b60408051808303601f190181529181528151602092830120948101805160010163ffffffff169052805191820190526001600160fd1b0390931683525090919050565b611ff0612fdd565b838510611ffc57600080fd5b612004612fdd565b61200e600161165a565b9050612018612fdd565b612028858863ffffffff61274116565b905061203a848763ffffffff61274116565b925061204c838363ffffffff612a5716565b825161205757600080fd5b612067838263ffffffff61280a16565b61206f612fdd565b61207885612847565b905061208a818363ffffffff612a5716565b6120a36120968861165a565b829063ffffffff61280a16565b6120ac81612a75565b90506120be848263ffffffff61280a16565b505050949350505050565b60006120d3612fdd565b6120e583600001518660a00151612ab2565b80519091506120f357600080fd5b60e084015161210990829063ffffffff61280a16565b612111612fdd565b61211b600161165a565b9050612125612fdd565b612133866101000151612847565b905061213d612fdd565b612147600061165a565b905060005b8751518110156121bb576121808960c00151828151811061216957fe5b60200260200101518361284290919063ffffffff16565b6121a3612196896000015183815181106107c557fe5b839063ffffffff61280a16565b6121b3838363ffffffff61285616565b60010161214c565b5087516121cf90849063ffffffff61280a16565b6121d7612fdd565b6121e48860c00151612847565b905060005b600381101561226f576122068961012001518260038110611c5d57fe5b60208a015161221c90849063ffffffff61280a16565b60408a015161223290849063ffffffff61285616565b6122578960800151826004811061224557fe5b6020020151849063ffffffff61285616565b612267828463ffffffff61280a16565b6001016121e9565b50604089015161228690839063ffffffff61284216565b60808801516060015161229a908390612856565b6122aa818363ffffffff61280a16565b6122ba818563ffffffff61280a16565b6122ca838263ffffffff612a5716565b88516122dd90859063ffffffff61280a16565b6122f18960c0015160008151811061216957fe5b612301828563ffffffff61280a16565b612311838363ffffffff612a5716565b505051915190911495945050505050565b6101d2828260000151611ee8565b612338612fc3565b606082015160099061234b9060056119fd565b9150612355612fc3565b61235d6127cd565b9050612367612fdd565b612371600061165a565b905060005b60048110156123c1576123a78760800151826004811061239257fe5b602002015187606001518360068110611a4d57fe5b92506123b9858463ffffffff61283716565b600101612376565b506080860151516123d3908290612842565b6080860151602001516123e790829061280a565b60608501516123f99082906004611a4d565b915061240b848363ffffffff61283716565b60a086015151608086015161242291906000611a4d565b9150612434848363ffffffff61283716565b61243c612fdd565b6124498860a00151612847565b905061246288602001518261280a90919063ffffffff16565b608087015151612473908290612856565b604088015161248990829063ffffffff61285616565b60005b600381101561252a5760a08901516124ab90849063ffffffff61284216565b6124d08760c0015182600381106124be57fe5b6020020151849063ffffffff61280a16565b60208901516124e690849063ffffffff61280a16565b60408901516124fc90849063ffffffff61285616565b6125128860800151826001016004811061224557fe5b612522828463ffffffff61280a16565b60010161248c565b50875161253e90829063ffffffff61280a16565b6125528860c0015160008151811061216957fe5b875161256590839063ffffffff61280a16565b875161257890839063ffffffff61280a16565b612588818363ffffffff61285616565b612590612fdd565b60608901516125a5908663ffffffff61274116565b90506125be89608001518261280a90919063ffffffff16565b6125c6612fdd565b6125d0600161165a565b905060005b600381101561266d5760208b01516125f490869063ffffffff61284216565b61261a8a6101200151826003811061260857fe5b6020020151869063ffffffff61280a16565b60408b015161263090869063ffffffff61285616565b6126558a60800151826004811061264357fe5b6020020151869063ffffffff61285616565b612665828663ffffffff61280a16565b6001016125d5565b5060208a015161268490829063ffffffff61280a16565b60c089015161269a90829063ffffffff61280a16565b89516126ad90829063ffffffff61280a16565b60408901516126c2908463ffffffff61282416565b60a08901519095506126e8906126db9083906003611a4d565b869063ffffffff61287016565b6126f8878663ffffffff61283716565b60608a015161270e90889063ffffffff612ae616565b604089015161273490612727908463ffffffff61282416565b889063ffffffff61283716565b5050505050509392505050565b612749612fdd565b612751613030565b6040518060c00160405280602081526020016020815260200160208152602001856000015181526020018481526020016000805160206139e8833981519152815250905061279d61304e565b600060208260c08560055afa9050806127b557600080fd5b50604080516020810190915290518152949350505050565b6127d5612fc3565b5060408051808201909152600181526002602082015290565b6127f6612fc3565b815181526020918201519181019190915290565b6000805160206139e8833981519152815183510990915250565b61282c612fc3565b6101cc838383612aed565b6101d2828284612b2f565b519052565b61284f612fdd565b9051815290565b6000805160206139e8833981519152815183510890915250565b6101d2828284612bc7565b60208101516128955780511561289057600080fd5b6128ae565b6020810180516000805160206139c88339815191520390525b50565b6128b9612ff0565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b82527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60208381019190915281019190915290565b60408051600280825260608281019093526000929190816020015b612994612fc3565b81526020019060019003908161298c57505060408051600280825260608083019093529293509091602082015b6129c9612ff0565b8152602001906001900390816129c157905050905086826000815181106129ec57fe5b60200260200101819052508482600181518110612a0557fe5b60200260200101819052508581600081518110612a1e57fe5b60200260200101819052508381600181518110612a3757fe5b6020026020010181905250612a4c8282612c61565b979650505050505050565b805182516000805160206139e8833981519152918203900890915250565b612a7d612fdd565b8151612a8857600080fd5b6101cc827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff612741565b612aba612fdd565b612aca828463ffffffff61274116565b90506101cc612ad9600161165a565b829063ffffffff612a5716565b6101d28282845b612af561306c565b835181526020840151816001602002015282518160026020020152600060408360608460075afa905080612b2857600080fd5b5050505050565b8151158015612b4057506020820151155b15612b58578251815260208084015190820152612bc2565b8251158015612b6957506020830151155b15612b81578151815260208083015190820152612bc2565b612b8961308a565b8351815260208085015181830152835160408301528301518160035b6020020152600060408360808460065afa905080612b2857600080fd5b505050565b8151158015612bd857506020820151155b15612bf0578251815260208084015190820152612bc2565b8251158015612c0157506020830151155b15612c2957815181526020808301516000805160206139c88339815191520390820152612bc2565b612c3161308a565b8351815260208085015181830152835160408301528301516000805160206139c883398151915203816003612ba5565b60008151835114612c7157600080fd5b8251604080516006830280825260c084028201602001909252606090828015612ca4578160200160208202803883390190505b50905060005b83811015612e2957868181518110612cbe57fe5b602002602001015160000151828260060260000181518110612cdc57fe5b602002602001018181525050868181518110612cf457fe5b602002602001015160200151828260060260010181518110612d1257fe5b602002602001018181525050858181518110612d2a57fe5b602090810291909101015151518251839060026006850201908110612d4b57fe5b602002602001018181525050858181518110612d6357fe5b60209081029190910101515160016020020151828260060260030181518110612d8857fe5b602002602001018181525050858181518110612da057fe5b602002602001015160200151600060028110612db857fe5b6020020151828260060260040181518110612dcf57fe5b602002602001018181525050858181518110612de757fe5b602002602001015160200151600160028110612dff57fe5b6020020151828260060260050181518110612e1657fe5b6020908102919091010152600101612caa565b50612e3261304e565b6000602082602086026020860160085afa905080612e4f57600080fd5b505115159695505050505050565b60405180610180016040528060608152602001612e786130a8565b8152602001612e85612fc3565b8152602001612e926130a8565b8152602001612e9f6130d5565b8152602001612eac613102565b8152602001612eb9612fdd565b8152602001612ec6612fdd565b8152602001612ed3612fdd565b8152602001612ee061312f565b8152602001612eed612fc3565b8152602001612efa612fc3565b905290565b6040518061010001604052806000815260200160008152602001612f21612fdd565b8152602001612f2e61315c565b8152602001612f3b613189565b8152602001612f486130a8565b8152602001612f5561312f565b8152602001612efa612ff0565b6040518060e00160405280612f75612fdd565b8152602001612f82612fdd565b8152602001612f8f612fdd565b8152602001612f9c612fdd565b8152602001612fa9612fdd565b8152602001612fb6612fdd565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060200160405280600081525090565b60405180604001604052806130036131b6565b8152602001612efa6131b6565b604080516060810182526000808252602082018190529181019190915290565b6040518060c001604052806006906020820280388339509192915050565b60405180602001604052806001906020820280388339509192915050565b60405180606001604052806003906020820280388339509192915050565b60405180608001604052806004906020820280388339509192915050565b60405180608001604052806004905b6130bf612fc3565b8152602001906001900390816130b75790505090565b60405180608001604052806004905b6130ec612fdd565b8152602001906001900390816130e45790505090565b60405180602001604052806001905b613119612fdd565b8152602001906001900390816131115790505090565b60405180606001604052806003905b613146612fdd565b81526020019060019003908161313e5790505090565b6040518060c001604052806006905b613173612fc3565b81526020019060019003908161316b5790505090565b60405180602001604052806001905b6131a0612fc3565b8152602001906001900390816131985790505090565b60405180604001604052806002906020820280388339509192915050565b80356101cc81613986565b60008083601f8401126131f157600080fd5b5081356001600160401b0381111561320857600080fd5b60208301915083602082028301111561322057600080fd5b9250929050565b80356101cc8161399a565b80516101cc8161399a565b60008083601f84011261324f57600080fd5b5081356001600160401b0381111561326657600080fd5b60208301915083600182028301111561322057600080fd5b600082601f83011261328f57600080fd5b81356132a261329d82613857565b613831565b915080825260208301602083018583830111156132be57600080fd5b6132c98382846138e0565b50505092915050565b80356101cc816139a3565b80356101cc816139ac565b80356101cc816139b5565b80356101cc816139be565b60006020828403121561331057600080fd5b600061331c8484613232565b949350505050565b600080600080600080600060c0888a03121561333f57600080fd5b600061334b8a8a613227565b975050602061335c8a828b016132e8565b965050604061336d8a828b016131d4565b955050606061337e8a828b016132dd565b945050608061338f8a828b016132d2565b93505060a08801356001600160401b038111156133ab57600080fd5b6133b78a828b016131df565b925092505092959891949750929550565b60008060008060008060008060e0898b0312156133e457600080fd5b60006133f08b8b613227565b98505060206134018b828c016132f3565b97505060406134128b828c016132e8565b96505060606134238b828c016132e8565b95505060806134348b828c01613227565b94505060a06134458b828c016131d4565b93505060c08901356001600160401b0381111561346157600080fd5b61346d8b828c016131df565b92509250509295985092959890939650565b6000806020838503121561349257600080fd5b82356001600160401b038111156134a857600080fd5b6134b48582860161323d565b92509250509250929050565b6000806000806000806000806080898b0312156134dc57600080fd5b88356001600160401b038111156134f257600080fd5b6134fe8b828c0161323d565b985098505060208901356001600160401b0381111561351c57600080fd5b6135288b828c0161323d565b965096505060408901356001600160401b0381111561354657600080fd5b6135528b828c0161323d565b945094505060608901356001600160401b0381111561346157600080fd5b6000806040838503121561358357600080fd5b82356001600160401b0381111561359957600080fd5b6135a58582860161327e565b92505060208301356001600160401b038111156135c157600080fd5b6135cd8582860161327e565b9150509250929050565b6135e86135e382613890565b61391c565b82525050565b6135e88161389b565b6135e8613603826138a0565b6138a0565b60006136138261387e565b61361d8185613882565b935061362d8185602086016138ec565b6136368161395e565b9093019392505050565b600061364b8261387e565b613655818561388b565b93506136658185602086016138ec565b9290920192915050565b6135e861367b826138a3565b613927565b6135e861368c826138b8565b613932565b6135e861369d826138cb565b613948565b6135e86136ae826138d4565b613953565b60006136bf82886135f7565b6020820191506136cf8287613691565b6004820191506136df82866135d7565b6014820191506136ef8285613680565b6002820191506136ff828461366f565b5060100195945050505050565b600061371882896135f7565b60208201915061372882886136a2565b6008820191506137388287613691565b6004820191506137488286613691565b60048201915061375882856135f7565b60208201915061376882846135d7565b506014019695505050505050565b60006119858284613640565b600061378e8287613691565b60048201915061379e82866135f7565b6020820191506137ae82856135f7565b6020820191506137be82846135f7565b50602001949350505050565b60006137d68287613691565b6004820191506137e682866135f7565b6020820191506137f682856135f7565b6020820191506138068284613691565b50600401949350505050565b602081016101cc82846135ee565b602080825281016119858184613608565b6040518181016001600160401b038111828210171561384f57600080fd5b604052919050565b60006001600160401b0382111561386d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b919050565b60006101cc826138bf565b151590565b90565b6fffffffffffffffffffffffffffffffff1690565b61ffff1690565b6001600160a01b031690565b63ffffffff1690565b6001600160401b031690565b82818337506000910152565b60005b838110156139075781810151838201526020016138ef565b83811115613916576000848401525b50505050565b60006101cc8261393d565b60006101cc82613968565b60006101cc8261397a565b60006101cc82613980565b60006101cc82613974565b60006101cc8261396e565b601f01601f191690565b60801b90565b60c01b90565b60e01b90565b60f01b90565b60601b90565b61398f81613890565b81146128ae57600080fd5b61398f816138a0565b61398f816138a3565b61398f816138b8565b61398f816138cb565b61398f816138d456fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a365627a7a72315820d4b1b0c8b8faf3db02641cc60cf25dce191cd6a2f14fcb0d486f616f4f5deada6c6578706572696d656e74616cf564736f6c63430005100040

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.