Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 17377794 | 526 days ago | IN | 0 ETH | 0.13328009 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Verifier
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.13; // SPDX-License-Identifier: MIT import "./Plonk4VerifierWithAccessToDNext.sol"; import "../common/libraries/UncheckedMath.sol"; contract Verifier is Plonk4VerifierWithAccessToDNext { using UncheckedMath for uint256; function get_verification_key() public pure returns (VerificationKey memory vk) { vk.num_inputs = 1; vk.domain_size = 67108864; vk.omega = PairingsBn254.new_fr(0x1dba8b5bdd64ef6ce29a9039aca3c0e524395c43b9227b96c75090cc6cc7ec97); // coefficients vk.gate_setup_commitments[0] = PairingsBn254.new_g1( 0x14c289d746e37aa82ec428491881c4732766492a8bc2e8e3cca2000a40c0ea27, 0x2f617a7eb9808ad9843d1e080b7cfbf99d61bb1b02076c905f31adb12731bc41 ); vk.gate_setup_commitments[1] = PairingsBn254.new_g1( 0x210b5cc8e6a85d63b65b701b8fb5ad24ff9c41f923432de17fe4ebae04526a8c, 0x05c10ab17ea731b2b87fb890fa5b10bd3d6832917a616b807a9b640888ebc731 ); vk.gate_setup_commitments[2] = PairingsBn254.new_g1( 0x29d4d14adcfe67a2ac690d6369db6b75e82d8ab3124bc4fa1dd145f41ca6949c, 0x004f6cd229373f1c1f735ccf49aef6a5c32025bc36c3328596dd0db7d87bef67 ); vk.gate_setup_commitments[3] = PairingsBn254.new_g1( 0x06d15382e8cabae9f98374a9fbdadd424f48e24da7e4c65bf710fd7d7d59a05a, 0x22e438ad5c51673879ce17073a3d2d29327a97dc3ce61c4f88540e00087695f6 ); vk.gate_setup_commitments[4] = PairingsBn254.new_g1( 0x274a668dfc485cf192d0086f214146d9e02b3040a5a586df344c53c16a87882b, 0x15f5bb7ad01f162b70fc77c8ea456d67d15a6ce98acbbfd521222810f8ec0a66 ); vk.gate_setup_commitments[5] = PairingsBn254.new_g1( 0x0ba53bf4fb0446927857e33978d02abf45948fc68f4091394ae0827a22cf1e47, 0x0720d818751ce5b3f11c716e925f60df4679ea90bed516499bdec066f5ff108f ); vk.gate_setup_commitments[6] = PairingsBn254.new_g1( 0x2e986ba2ea495e5ec6af532980b1dc567f1430bfa82f8de07c12fc097c0e0483, 0x1555d189f6164e82d78de1b8313c2e923e616b3c8ed0e350c3b61c94516d0b58 ); vk.gate_setup_commitments[7] = PairingsBn254.new_g1( 0x0925959592604ca73c917f9b2e029aa2563c318ddcc5ca29c11badb7b880127b, 0x2b4a430fcb2fa7d6d67d6c358e01cf0524c7df7e1e56442f65b39bc1a1052367 ); // gate selectors vk.gate_selectors_commitments[0] = PairingsBn254.new_g1( 0x28f2a0a95af79ba67e9dd1986bd3190199f661b710a693fc82fb395c126edcbd, 0x0db75db5de5192d1ba1c24710fc00da16fa8029ac7fe82d855674dcd6d090e05 ); vk.gate_selectors_commitments[1] = PairingsBn254.new_g1( 0x143471a174dfcb2d9cb5ae621e519387bcc93c9dcfc011160b2f5c5f88e32cbe, 0x2a0194c0224c3d964223a96c4c99e015719bc879125aa0df3f0715d154e71a31 ); // permutation vk.permutation_commitments[0] = PairingsBn254.new_g1( 0x1423fa82e00ba22c280181afb12c56eea541933eeb5ec39119b0365b6beab4b9, 0x0efdcd3423a38f5e2ecf8c7e4fd46f13189f8fed392ad9d8d393e8ba568b06e4 ); vk.permutation_commitments[1] = PairingsBn254.new_g1( 0x0e9b5b12c1090d62224e64aa1696c009aa59a9c3eec458e781fae773e1f4eca5, 0x1fe3df508c7e9750eb37d9cae5e7437ad11a21fa36530ff821b407b165a79a55 ); vk.permutation_commitments[2] = PairingsBn254.new_g1( 0x25d1a714bd1e258f196e38d6b2826153382c2d04b870d0b7ec250296005129ae, 0x0883a121b41ca7beaa9de97ecf4417e62aa2eeb9434f24ddacbfed57cbf016a8 ); vk.permutation_commitments[3] = PairingsBn254.new_g1( 0x2f3ede68e854a6b3b14589851cf077a606e2aeb3205c43cc579b7abae39d8f58, 0x178ccd4b1f78fd79ee248e376b6fc8297d5450900d1e15e8c03e3ed2c171ac8c ); // lookup table commitments vk.lookup_selector_commitment = PairingsBn254.new_g1( 0x1f814e2d87c332e964eeef94ec695eef9d2caaac58b682a43da5107693b06f30, 0x196d56fb01907e66af9303886fd95328d398e5b2b72906882a9d12c1718e2ee2 ); vk.lookup_tables_commitments[0] = PairingsBn254.new_g1( 0x0ebe0de4a2f39df3b903da484c1641ffdffb77ff87ce4f9508c548659eb22d3c, 0x12a3209440242d5662729558f1017ed9dcc08fe49a99554dd45f5f15da5e4e0b ); vk.lookup_tables_commitments[1] = PairingsBn254.new_g1( 0x1b7d54f8065ca63bed0bfbb9280a1011b886d07e0c0a26a66ecc96af68c53bf9, 0x2c51121fff5b8f58c302f03c74e0cb176ae5a1d1730dec4696eb9cce3fe284ca ); vk.lookup_tables_commitments[2] = PairingsBn254.new_g1( 0x0138733c5faa9db6d4b8df9748081e38405999e511fb22d40f77cf3aef293c44, 0x269bee1c1ac28053238f7fe789f1ea2e481742d6d16ae78ed81e87c254af0765 ); vk.lookup_tables_commitments[3] = PairingsBn254.new_g1( 0x1b1be7279d59445065a95f01f16686adfa798ec4f1e6845ffcec9b837e88372e, 0x057c90cb96d8259238ed86b05f629efd55f472a721efeeb56926e979433e6c0e ); vk.lookup_table_type_commitment = PairingsBn254.new_g1( 0x2f85df2d6249ccbcc11b91727333cc800459de6ee274f29c657c8d56f6f01563, 0x088e1df178c47116a69c3c8f6d0c5feb530e2a72493694a623b1cceb7d44a76c ); // non residues vk.non_residues[0] = PairingsBn254.new_fr(0x0000000000000000000000000000000000000000000000000000000000000005); vk.non_residues[1] = PairingsBn254.new_fr(0x0000000000000000000000000000000000000000000000000000000000000007); vk.non_residues[2] = PairingsBn254.new_fr(0x000000000000000000000000000000000000000000000000000000000000000a); // g2 elements vk.g2_elements[0] = PairingsBn254.new_g2( [ 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed ], [ 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa ] ); vk.g2_elements[1] = PairingsBn254.new_g2( [ 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1, 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0 ], [ 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4, 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55 ] ); } function deserialize_proof(uint256[] calldata public_inputs, uint256[] calldata serialized_proof) internal pure returns (Proof memory proof) { require(serialized_proof.length == 44); proof.input_values = new uint256[](public_inputs.length); for (uint256 i = 0; i < public_inputs.length; i = i.uncheckedInc()) { proof.input_values[i] = public_inputs[i]; } uint256 j; for (uint256 i = 0; i < STATE_WIDTH; i = i.uncheckedInc()) { proof.state_polys_commitments[i] = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); } proof.copy_permutation_grand_product_commitment = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); proof.lookup_s_poly_commitment = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); proof.lookup_grand_product_commitment = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); for (uint256 i = 0; i < proof.quotient_poly_parts_commitments.length; i = i.uncheckedInc()) { proof.quotient_poly_parts_commitments[i] = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); } for (uint256 i = 0; i < proof.state_polys_openings_at_z.length; i = i.uncheckedInc()) { proof.state_polys_openings_at_z[i] = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); } for (uint256 i = 0; i < proof.state_polys_openings_at_z_omega.length; i = i.uncheckedInc()) { proof.state_polys_openings_at_z_omega[i] = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); } for (uint256 i = 0; i < proof.gate_selectors_openings_at_z.length; i = i.uncheckedInc()) { proof.gate_selectors_openings_at_z[i] = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); } for (uint256 i = 0; i < proof.copy_permutation_polys_openings_at_z.length; i = i.uncheckedInc()) { proof.copy_permutation_polys_openings_at_z[i] = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); } proof.copy_permutation_grand_product_opening_at_z_omega = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_s_poly_opening_at_z_omega = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_grand_product_opening_at_z_omega = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_t_poly_opening_at_z = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_t_poly_opening_at_z_omega = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_selector_poly_opening_at_z = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.lookup_table_type_poly_opening_at_z = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.quotient_poly_opening_at_z = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.linearization_poly_opening_at_z = PairingsBn254.new_fr(serialized_proof[j]); j = j.uncheckedInc(); proof.opening_proof_at_z = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); j = j.uncheckedAdd(2); proof.opening_proof_at_z_omega = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j.uncheckedInc()] ); } function verify_serialized_proof(uint256[] calldata public_inputs, uint256[] calldata serialized_proof) public view returns (bool) { VerificationKey memory vk = get_verification_key(); require(vk.num_inputs == public_inputs.length); Proof memory proof = deserialize_proof(public_inputs, serialized_proof); return verify(proof, vk); } }
pragma solidity ^0.8.13; // SPDX-License-Identifier: MIT library UncheckedMath { function uncheckedInc(uint256 _number) internal pure returns (uint256) { unchecked { return _number + 1; } } function uncheckedAdd(uint256 _lhs, uint256 _rhs) internal pure returns (uint256) { unchecked { return _lhs + _rhs; } } }
pragma solidity ^0.8.13; // SPDX-License-Identifier: MIT import "./libraries/PairingsBn254.sol"; import "./libraries/TranscriptLib.sol"; import "../common/libraries/UncheckedMath.sol"; uint256 constant STATE_WIDTH = 4; uint256 constant NUM_G2_ELS = 2; struct VerificationKey { uint256 domain_size; uint256 num_inputs; PairingsBn254.Fr omega; PairingsBn254.G1Point[2] gate_selectors_commitments; PairingsBn254.G1Point[8] gate_setup_commitments; PairingsBn254.G1Point[STATE_WIDTH] permutation_commitments; PairingsBn254.G1Point lookup_selector_commitment; PairingsBn254.G1Point[4] lookup_tables_commitments; PairingsBn254.G1Point lookup_table_type_commitment; PairingsBn254.Fr[STATE_WIDTH - 1] non_residues; PairingsBn254.G2Point[NUM_G2_ELS] g2_elements; } contract Plonk4VerifierWithAccessToDNext { using PairingsBn254 for PairingsBn254.G1Point; using PairingsBn254 for PairingsBn254.G2Point; using PairingsBn254 for PairingsBn254.Fr; using TranscriptLib for TranscriptLib.Transcript; using UncheckedMath for uint256; struct Proof { uint256[] input_values; // commitments PairingsBn254.G1Point[STATE_WIDTH] state_polys_commitments; PairingsBn254.G1Point copy_permutation_grand_product_commitment; PairingsBn254.G1Point[STATE_WIDTH] quotient_poly_parts_commitments; // openings PairingsBn254.Fr[STATE_WIDTH] state_polys_openings_at_z; PairingsBn254.Fr[1] state_polys_openings_at_z_omega; PairingsBn254.Fr[1] gate_selectors_openings_at_z; PairingsBn254.Fr[STATE_WIDTH - 1] copy_permutation_polys_openings_at_z; PairingsBn254.Fr copy_permutation_grand_product_opening_at_z_omega; PairingsBn254.Fr quotient_poly_opening_at_z; PairingsBn254.Fr linearization_poly_opening_at_z; // lookup commitments PairingsBn254.G1Point lookup_s_poly_commitment; PairingsBn254.G1Point lookup_grand_product_commitment; // lookup openings PairingsBn254.Fr lookup_s_poly_opening_at_z_omega; PairingsBn254.Fr lookup_grand_product_opening_at_z_omega; PairingsBn254.Fr lookup_t_poly_opening_at_z; PairingsBn254.Fr lookup_t_poly_opening_at_z_omega; PairingsBn254.Fr lookup_selector_poly_opening_at_z; PairingsBn254.Fr lookup_table_type_poly_opening_at_z; PairingsBn254.G1Point opening_proof_at_z; PairingsBn254.G1Point opening_proof_at_z_omega; } struct PartialVerifierState { PairingsBn254.Fr zero; PairingsBn254.Fr alpha; PairingsBn254.Fr beta; PairingsBn254.Fr gamma; PairingsBn254.Fr[9] alpha_values; PairingsBn254.Fr eta; PairingsBn254.Fr beta_lookup; PairingsBn254.Fr gamma_lookup; PairingsBn254.Fr beta_plus_one; PairingsBn254.Fr beta_gamma; PairingsBn254.Fr v; PairingsBn254.Fr u; PairingsBn254.Fr z; PairingsBn254.Fr z_omega; PairingsBn254.Fr z_minus_last_omega; PairingsBn254.Fr l_0_at_z; PairingsBn254.Fr l_n_minus_one_at_z; PairingsBn254.Fr t; PairingsBn254.G1Point tp; } function evaluate_l0_at_point(uint256 domain_size, PairingsBn254.Fr memory at) internal view returns (PairingsBn254.Fr memory num) { PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); PairingsBn254.Fr memory size_fe = PairingsBn254.new_fr(domain_size); PairingsBn254.Fr memory den = at.copy(); den.sub_assign(one); den.mul_assign(size_fe); den = den.inverse(); num = at.pow(domain_size); num.sub_assign(one); num.mul_assign(den); } 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) { // (omega^i / N) / (X - omega^i) * (X^N - 1) 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 initialize_transcript(Proof memory proof, VerificationKey memory vk) internal pure returns (PartialVerifierState memory state) { TranscriptLib.Transcript memory transcript = TranscriptLib.new_transcript(); for (uint256 i = 0; i < vk.num_inputs; i = i.uncheckedInc()) { transcript.update_with_u256(proof.input_values[i]); } for (uint256 i = 0; i < STATE_WIDTH; i = i.uncheckedInc()) { transcript.update_with_g1(proof.state_polys_commitments[i]); } state.eta = transcript.get_challenge(); transcript.update_with_g1(proof.lookup_s_poly_commitment); state.beta = transcript.get_challenge(); state.gamma = transcript.get_challenge(); transcript.update_with_g1(proof.copy_permutation_grand_product_commitment); state.beta_lookup = transcript.get_challenge(); state.gamma_lookup = transcript.get_challenge(); transcript.update_with_g1(proof.lookup_grand_product_commitment); state.alpha = transcript.get_challenge(); for (uint256 i = 0; i < proof.quotient_poly_parts_commitments.length; i = i.uncheckedInc()) { transcript.update_with_g1(proof.quotient_poly_parts_commitments[i]); } state.z = transcript.get_challenge(); transcript.update_with_fr(proof.quotient_poly_opening_at_z); for (uint256 i = 0; i < proof.state_polys_openings_at_z.length; i = i.uncheckedInc()) { transcript.update_with_fr(proof.state_polys_openings_at_z[i]); } for (uint256 i = 0; i < proof.state_polys_openings_at_z_omega.length; i = i.uncheckedInc()) { transcript.update_with_fr(proof.state_polys_openings_at_z_omega[i]); } for (uint256 i = 0; i < proof.gate_selectors_openings_at_z.length; i = i.uncheckedInc()) { transcript.update_with_fr(proof.gate_selectors_openings_at_z[i]); } for (uint256 i = 0; i < proof.copy_permutation_polys_openings_at_z.length; i = i.uncheckedInc()) { transcript.update_with_fr(proof.copy_permutation_polys_openings_at_z[i]); } state.z_omega = state.z.copy(); state.z_omega.mul_assign(vk.omega); transcript.update_with_fr(proof.copy_permutation_grand_product_opening_at_z_omega); transcript.update_with_fr(proof.lookup_t_poly_opening_at_z); transcript.update_with_fr(proof.lookup_selector_poly_opening_at_z); transcript.update_with_fr(proof.lookup_table_type_poly_opening_at_z); transcript.update_with_fr(proof.lookup_s_poly_opening_at_z_omega); transcript.update_with_fr(proof.lookup_grand_product_opening_at_z_omega); transcript.update_with_fr(proof.lookup_t_poly_opening_at_z_omega); transcript.update_with_fr(proof.linearization_poly_opening_at_z); state.v = transcript.get_challenge(); transcript.update_with_g1(proof.opening_proof_at_z); transcript.update_with_g1(proof.opening_proof_at_z_omega); state.u = transcript.get_challenge(); } // compute some powers of challenge alpha([alpha^1, .. alpha^8]) function compute_powers_of_alpha(PartialVerifierState memory state) public pure { require(state.alpha.value != 0); state.alpha_values[0] = PairingsBn254.new_fr(1); state.alpha_values[1] = state.alpha.copy(); PairingsBn254.Fr memory current_alpha = state.alpha.copy(); for (uint256 i = 2; i < state.alpha_values.length; i = i.uncheckedInc()) { current_alpha.mul_assign(state.alpha); state.alpha_values[i] = current_alpha.copy(); } } function verify(Proof memory proof, VerificationKey memory vk) internal view returns (bool) { // we initialize all challenges beforehand, we can draw each challenge in its own place PartialVerifierState memory state = initialize_transcript(proof, vk); if (verify_quotient_evaluation(vk, proof, state) == false) { return false; } require(proof.state_polys_openings_at_z_omega.length == 1); PairingsBn254.G1Point memory quotient_result = proof.quotient_poly_parts_commitments[0].copy_g1(); { // block scope PairingsBn254.Fr memory z_in_domain_size = state.z.pow(vk.domain_size); PairingsBn254.Fr memory current_z = z_in_domain_size.copy(); PairingsBn254.G1Point memory tp; // start from i =1 for (uint256 i = 1; i < proof.quotient_poly_parts_commitments.length; i = i.uncheckedInc()) { tp = proof.quotient_poly_parts_commitments[i].copy_g1(); tp.point_mul_assign(current_z); quotient_result.point_add_assign(tp); current_z.mul_assign(z_in_domain_size); } } Queries memory queries = prepare_queries(vk, proof, state); queries.commitments_at_z[0] = quotient_result; queries.values_at_z[0] = proof.quotient_poly_opening_at_z; queries.commitments_at_z[1] = aggregated_linearization_commitment(vk, proof, state); queries.values_at_z[1] = proof.linearization_poly_opening_at_z; require(queries.commitments_at_z.length == queries.values_at_z.length); PairingsBn254.G1Point memory aggregated_commitment_at_z = queries.commitments_at_z[0]; PairingsBn254.Fr memory aggregated_opening_at_z = queries.values_at_z[0]; PairingsBn254.Fr memory aggregation_challenge = PairingsBn254.new_fr(1); PairingsBn254.G1Point memory scaled; for (uint256 i = 1; i < queries.commitments_at_z.length; i = i.uncheckedInc()) { aggregation_challenge.mul_assign(state.v); scaled = queries.commitments_at_z[i].point_mul(aggregation_challenge); aggregated_commitment_at_z.point_add_assign(scaled); state.t = queries.values_at_z[i]; state.t.mul_assign(aggregation_challenge); aggregated_opening_at_z.add_assign(state.t); } aggregation_challenge.mul_assign(state.v); PairingsBn254.G1Point memory aggregated_commitment_at_z_omega = queries.commitments_at_z_omega[0].point_mul( aggregation_challenge ); PairingsBn254.Fr memory aggregated_opening_at_z_omega = queries.values_at_z_omega[0]; aggregated_opening_at_z_omega.mul_assign(aggregation_challenge); for (uint256 i = 1; i < queries.commitments_at_z_omega.length; i = i.uncheckedInc()) { aggregation_challenge.mul_assign(state.v); scaled = queries.commitments_at_z_omega[i].point_mul(aggregation_challenge); aggregated_commitment_at_z_omega.point_add_assign(scaled); state.t = queries.values_at_z_omega[i]; state.t.mul_assign(aggregation_challenge); aggregated_opening_at_z_omega.add_assign(state.t); } return final_pairing( vk.g2_elements, proof, state, aggregated_commitment_at_z, aggregated_commitment_at_z_omega, aggregated_opening_at_z, aggregated_opening_at_z_omega ); } function verify_quotient_evaluation( VerificationKey memory vk, Proof memory proof, PartialVerifierState memory state ) internal view returns (bool) { uint256[] memory lagrange_poly_numbers = new uint256[](vk.num_inputs); for (uint256 i = 0; i < lagrange_poly_numbers.length; i = i.uncheckedInc()) { lagrange_poly_numbers[i] = i; } require(vk.num_inputs > 0); PairingsBn254.Fr memory inputs_term = PairingsBn254.new_fr(0); for (uint256 i = 0; i < vk.num_inputs; i = i.uncheckedInc()) { state.t = evaluate_lagrange_poly_out_of_domain(i, vk.domain_size, vk.omega, state.z); state.t.mul_assign(PairingsBn254.new_fr(proof.input_values[i])); inputs_term.add_assign(state.t); } inputs_term.mul_assign(proof.gate_selectors_openings_at_z[0]); PairingsBn254.Fr memory result = proof.linearization_poly_opening_at_z.copy(); result.add_assign(inputs_term); // compute powers of alpha compute_powers_of_alpha(state); PairingsBn254.Fr memory factor = state.alpha_values[4].copy(); factor.mul_assign(proof.copy_permutation_grand_product_opening_at_z_omega); // - alpha_0 * (a + perm(z) * beta + gamma)*()*(d + gamma) * z(z*omega) require(proof.copy_permutation_polys_openings_at_z.length == STATE_WIDTH - 1); PairingsBn254.Fr memory t; // TMP; for (uint256 i = 0; i < proof.copy_permutation_polys_openings_at_z.length; i = i.uncheckedInc()) { t = proof.copy_permutation_polys_openings_at_z[i].copy(); t.mul_assign(state.beta); t.add_assign(proof.state_polys_openings_at_z[i]); t.add_assign(state.gamma); factor.mul_assign(t); } t = proof.state_polys_openings_at_z[3].copy(); t.add_assign(state.gamma); factor.mul_assign(t); result.sub_assign(factor); // - L_0(z) * alpha_1 PairingsBn254.Fr memory l_0_at_z = evaluate_l0_at_point(vk.domain_size, state.z); l_0_at_z.mul_assign(state.alpha_values[4 + 1]); result.sub_assign(l_0_at_z); PairingsBn254.Fr memory lookup_quotient_contrib = lookup_quotient_contribution(vk, proof, state); result.add_assign(lookup_quotient_contrib); PairingsBn254.Fr memory lhs = proof.quotient_poly_opening_at_z.copy(); lhs.mul_assign(evaluate_vanishing(vk.domain_size, state.z)); return lhs.value == result.value; } function lookup_quotient_contribution( VerificationKey memory vk, Proof memory proof, PartialVerifierState memory state ) internal view returns (PairingsBn254.Fr memory result) { PairingsBn254.Fr memory t; PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); state.beta_plus_one = state.beta_lookup.copy(); state.beta_plus_one.add_assign(one); state.beta_gamma = state.beta_plus_one.copy(); state.beta_gamma.mul_assign(state.gamma_lookup); // (s'*beta + gamma)*(zw')*alpha t = proof.lookup_s_poly_opening_at_z_omega.copy(); t.mul_assign(state.beta_lookup); t.add_assign(state.beta_gamma); t.mul_assign(proof.lookup_grand_product_opening_at_z_omega); t.mul_assign(state.alpha_values[6]); // (z - omega^{n-1}) for this part PairingsBn254.Fr memory last_omega = vk.omega.pow(vk.domain_size - 1); state.z_minus_last_omega = state.z.copy(); state.z_minus_last_omega.sub_assign(last_omega); t.mul_assign(state.z_minus_last_omega); result.add_assign(t); // - alpha_1 * L_{0}(z) state.l_0_at_z = evaluate_lagrange_poly_out_of_domain(0, vk.domain_size, vk.omega, state.z); t = state.l_0_at_z.copy(); t.mul_assign(state.alpha_values[6 + 1]); result.sub_assign(t); // - alpha_2 * beta_gamma_powered L_{n-1}(z) PairingsBn254.Fr memory beta_gamma_powered = state.beta_gamma.pow(vk.domain_size - 1); state.l_n_minus_one_at_z = evaluate_lagrange_poly_out_of_domain( vk.domain_size - 1, vk.domain_size, vk.omega, state.z ); t = state.l_n_minus_one_at_z.copy(); t.mul_assign(beta_gamma_powered); t.mul_assign(state.alpha_values[6 + 2]); result.sub_assign(t); } function aggregated_linearization_commitment( VerificationKey memory vk, Proof memory proof, PartialVerifierState memory state ) internal view returns (PairingsBn254.G1Point memory result) { // qMain*(Q_a * A + Q_b * B + Q_c * C + Q_d * D + Q_m * A*B + Q_const + Q_dNext * D_next) result = PairingsBn254.new_g1(0, 0); // Q_a * A PairingsBn254.G1Point memory scaled = vk.gate_setup_commitments[0].point_mul( proof.state_polys_openings_at_z[0] ); result.point_add_assign(scaled); // Q_b * B scaled = vk.gate_setup_commitments[1].point_mul(proof.state_polys_openings_at_z[1]); result.point_add_assign(scaled); // Q_c * C scaled = vk.gate_setup_commitments[2].point_mul(proof.state_polys_openings_at_z[2]); result.point_add_assign(scaled); // Q_d * D scaled = vk.gate_setup_commitments[3].point_mul(proof.state_polys_openings_at_z[3]); result.point_add_assign(scaled); // Q_m* A*B or Q_ab*A*B PairingsBn254.Fr memory t = proof.state_polys_openings_at_z[0].copy(); t.mul_assign(proof.state_polys_openings_at_z[1]); scaled = vk.gate_setup_commitments[4].point_mul(t); result.point_add_assign(scaled); // Q_AC* A*C t = proof.state_polys_openings_at_z[0].copy(); t.mul_assign(proof.state_polys_openings_at_z[2]); scaled = vk.gate_setup_commitments[5].point_mul(t); result.point_add_assign(scaled); // Q_const result.point_add_assign(vk.gate_setup_commitments[6]); // Q_dNext * D_next scaled = vk.gate_setup_commitments[7].point_mul(proof.state_polys_openings_at_z_omega[0]); result.point_add_assign(scaled); result.point_mul_assign(proof.gate_selectors_openings_at_z[0]); PairingsBn254.G1Point memory rescue_custom_gate_linearization_contrib = rescue_custom_gate_linearization_contribution( vk, proof, state ); result.point_add_assign(rescue_custom_gate_linearization_contrib); require(vk.non_residues.length == STATE_WIDTH - 1); PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); PairingsBn254.Fr memory factor = state.alpha_values[4].copy(); for (uint256 i = 0; i < proof.state_polys_openings_at_z.length; ) { t = state.z.copy(); if (i == 0) { t.mul_assign(one); } else { t.mul_assign(vk.non_residues[i - 1]); } t.mul_assign(state.beta); t.add_assign(state.gamma); t.add_assign(proof.state_polys_openings_at_z[i]); factor.mul_assign(t); unchecked { ++i; } } scaled = proof.copy_permutation_grand_product_commitment.point_mul(factor); result.point_add_assign(scaled); // - (a(z) + beta*perm_a + gamma)*()*()*z(z*omega) * beta * perm_d(X) factor = state.alpha_values[4].copy(); factor.mul_assign(state.beta); factor.mul_assign(proof.copy_permutation_grand_product_opening_at_z_omega); for (uint256 i = 0; i < STATE_WIDTH - 1; i = i.uncheckedInc()) { t = proof.copy_permutation_polys_openings_at_z[i].copy(); t.mul_assign(state.beta); t.add_assign(state.gamma); t.add_assign(proof.state_polys_openings_at_z[i]); factor.mul_assign(t); } scaled = vk.permutation_commitments[3].point_mul(factor); result.point_sub_assign(scaled); // + L_0(z) * Z(x) state.l_0_at_z = evaluate_lagrange_poly_out_of_domain(0, vk.domain_size, vk.omega, state.z); require(state.l_0_at_z.value != 0); factor = state.l_0_at_z.copy(); factor.mul_assign(state.alpha_values[4 + 1]); scaled = proof.copy_permutation_grand_product_commitment.point_mul(factor); result.point_add_assign(scaled); PairingsBn254.G1Point memory lookup_linearization_contrib = lookup_linearization_contribution(proof, state); result.point_add_assign(lookup_linearization_contrib); } function rescue_custom_gate_linearization_contribution( VerificationKey memory vk, Proof memory proof, PartialVerifierState memory state ) public view returns (PairingsBn254.G1Point memory result) { PairingsBn254.Fr memory t; PairingsBn254.Fr memory intermediate_result; // a^2 - b = 0 t = proof.state_polys_openings_at_z[0].copy(); t.mul_assign(t); t.sub_assign(proof.state_polys_openings_at_z[1]); // t.mul_assign(challenge1); t.mul_assign(state.alpha_values[1]); intermediate_result.add_assign(t); // b^2 - c = 0 t = proof.state_polys_openings_at_z[1].copy(); t.mul_assign(t); t.sub_assign(proof.state_polys_openings_at_z[2]); t.mul_assign(state.alpha_values[1 + 1]); intermediate_result.add_assign(t); // c*a - d = 0; t = proof.state_polys_openings_at_z[2].copy(); t.mul_assign(proof.state_polys_openings_at_z[0]); t.sub_assign(proof.state_polys_openings_at_z[3]); t.mul_assign(state.alpha_values[1 + 2]); intermediate_result.add_assign(t); result = vk.gate_selectors_commitments[1].point_mul(intermediate_result); } function lookup_linearization_contribution(Proof memory proof, PartialVerifierState memory state) internal view returns (PairingsBn254.G1Point memory result) { PairingsBn254.Fr memory zero = PairingsBn254.new_fr(0); PairingsBn254.Fr memory t; PairingsBn254.Fr memory factor; // s(x) from the Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) factor = proof.lookup_grand_product_opening_at_z_omega.copy(); factor.mul_assign(state.alpha_values[6]); factor.mul_assign(state.z_minus_last_omega); PairingsBn254.G1Point memory scaled = proof.lookup_s_poly_commitment.point_mul(factor); result.point_add_assign(scaled); // Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) // + alpha_1 * Z(x) * L_{0}(z) + alpha_2 * Z(x) * L_{n-1}(z) // accumulate coefficient factor = proof.lookup_t_poly_opening_at_z_omega.copy(); factor.mul_assign(state.beta_lookup); factor.add_assign(proof.lookup_t_poly_opening_at_z); factor.add_assign(state.beta_gamma); // (\gamma + f(x)) PairingsBn254.Fr memory f_reconstructed; PairingsBn254.Fr memory current = PairingsBn254.new_fr(1); PairingsBn254.Fr memory tmp0; for (uint256 i = 0; i < STATE_WIDTH - 1; i = i.uncheckedInc()) { tmp0 = proof.state_polys_openings_at_z[i].copy(); tmp0.mul_assign(current); f_reconstructed.add_assign(tmp0); current.mul_assign(state.eta); } // add type of table t = proof.lookup_table_type_poly_opening_at_z.copy(); t.mul_assign(current); f_reconstructed.add_assign(t); f_reconstructed.mul_assign(proof.lookup_selector_poly_opening_at_z); f_reconstructed.add_assign(state.gamma_lookup); // end of (\gamma + f(x)) part factor.mul_assign(f_reconstructed); factor.mul_assign(state.beta_plus_one); t = zero.copy(); t.sub_assign(factor); factor = t; factor.mul_assign(state.alpha_values[6]); // Multiply by (z - omega^{n-1}) factor.mul_assign(state.z_minus_last_omega); // L_{0}(z) in front of Z(x) t = state.l_0_at_z.copy(); t.mul_assign(state.alpha_values[6 + 1]); factor.add_assign(t); // L_{n-1}(z) in front of Z(x) t = state.l_n_minus_one_at_z.copy(); t.mul_assign(state.alpha_values[6 + 2]); factor.add_assign(t); scaled = proof.lookup_grand_product_commitment.point_mul(factor); result.point_add_assign(scaled); } struct Queries { PairingsBn254.G1Point[13] commitments_at_z; PairingsBn254.Fr[13] values_at_z; PairingsBn254.G1Point[6] commitments_at_z_omega; PairingsBn254.Fr[6] values_at_z_omega; } function prepare_queries( VerificationKey memory vk, Proof memory proof, PartialVerifierState memory state ) public view returns (Queries memory queries) { // we set first two items in calee side so start idx from 2 uint256 idx = 2; for (uint256 i = 0; i < STATE_WIDTH; i = i.uncheckedInc()) { queries.commitments_at_z[idx] = proof.state_polys_commitments[i]; queries.values_at_z[idx] = proof.state_polys_openings_at_z[i]; idx = idx.uncheckedInc(); } require(proof.gate_selectors_openings_at_z.length == 1); queries.commitments_at_z[idx] = vk.gate_selectors_commitments[0]; queries.values_at_z[idx] = proof.gate_selectors_openings_at_z[0]; idx = idx.uncheckedInc(); for (uint256 i = 0; i < STATE_WIDTH - 1; i = i.uncheckedInc()) { queries.commitments_at_z[idx] = vk.permutation_commitments[i]; queries.values_at_z[idx] = proof.copy_permutation_polys_openings_at_z[i]; idx = idx.uncheckedInc(); } queries.commitments_at_z_omega[0] = proof.copy_permutation_grand_product_commitment; queries.commitments_at_z_omega[1] = proof.state_polys_commitments[STATE_WIDTH - 1]; queries.values_at_z_omega[0] = proof.copy_permutation_grand_product_opening_at_z_omega; queries.values_at_z_omega[1] = proof.state_polys_openings_at_z_omega[0]; PairingsBn254.G1Point memory lookup_t_poly_commitment_aggregated = vk.lookup_tables_commitments[0]; PairingsBn254.Fr memory current_eta = state.eta.copy(); for (uint256 i = 1; i < vk.lookup_tables_commitments.length; i = i.uncheckedInc()) { state.tp = vk.lookup_tables_commitments[i].point_mul(current_eta); lookup_t_poly_commitment_aggregated.point_add_assign(state.tp); current_eta.mul_assign(state.eta); } queries.commitments_at_z[idx] = lookup_t_poly_commitment_aggregated; queries.values_at_z[idx] = proof.lookup_t_poly_opening_at_z; idx = idx.uncheckedInc(); queries.commitments_at_z[idx] = vk.lookup_selector_commitment; queries.values_at_z[idx] = proof.lookup_selector_poly_opening_at_z; idx = idx.uncheckedInc(); queries.commitments_at_z[idx] = vk.lookup_table_type_commitment; queries.values_at_z[idx] = proof.lookup_table_type_poly_opening_at_z; queries.commitments_at_z_omega[2] = proof.lookup_s_poly_commitment; queries.values_at_z_omega[2] = proof.lookup_s_poly_opening_at_z_omega; queries.commitments_at_z_omega[3] = proof.lookup_grand_product_commitment; queries.values_at_z_omega[3] = proof.lookup_grand_product_opening_at_z_omega; queries.commitments_at_z_omega[4] = lookup_t_poly_commitment_aggregated; queries.values_at_z_omega[4] = proof.lookup_t_poly_opening_at_z_omega; } function final_pairing( // VerificationKey memory vk, PairingsBn254.G2Point[NUM_G2_ELS] memory g2_elements, Proof memory proof, PartialVerifierState memory state, PairingsBn254.G1Point memory aggregated_commitment_at_z, PairingsBn254.G1Point memory aggregated_commitment_at_z_omega, PairingsBn254.Fr memory aggregated_opening_at_z, PairingsBn254.Fr memory aggregated_opening_at_z_omega ) internal view returns (bool) { // q(x) = f(x) - f(z) / (x - z) // q(x) * (x-z) = f(x) - f(z) // f(x) PairingsBn254.G1Point memory pair_with_generator = aggregated_commitment_at_z.copy_g1(); aggregated_commitment_at_z_omega.point_mul_assign(state.u); pair_with_generator.point_add_assign(aggregated_commitment_at_z_omega); // - f(z)*g PairingsBn254.Fr memory aggregated_value = aggregated_opening_at_z_omega.copy(); aggregated_value.mul_assign(state.u); aggregated_value.add_assign(aggregated_opening_at_z); PairingsBn254.G1Point memory tp = PairingsBn254.P1().point_mul(aggregated_value); pair_with_generator.point_sub_assign(tp); // +z * q(x) tp = proof.opening_proof_at_z.point_mul(state.z); PairingsBn254.Fr memory t = state.z_omega.copy(); t.mul_assign(state.u); PairingsBn254.G1Point memory t1 = proof.opening_proof_at_z_omega.point_mul(t); tp.point_add_assign(t1); pair_with_generator.point_add_assign(tp); // rhs PairingsBn254.G1Point memory pair_with_x = proof.opening_proof_at_z_omega.point_mul(state.u); pair_with_x.point_add_assign(proof.opening_proof_at_z); pair_with_x.negate(); // Pairing precompile expects points to be in a `i*x[1] + x[0]` form instead of `x[0] + i*x[1]` // so we handle it in code generation step PairingsBn254.G2Point memory first_g2 = g2_elements[0]; PairingsBn254.G2Point memory second_g2 = g2_elements[1]; return PairingsBn254.pairingProd2(pair_with_generator, first_g2, pair_with_x, second_g2); } }
pragma solidity ^0.8.13; // SPDX-License-Identifier: MIT import "./PairingsBn254.sol"; library TranscriptLib { // 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}); } }
pragma solidity ^0.8.13; // SPDX-License-Identifier: MIT 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 { uint256[2] X; uint256[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) { 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, "x axis isn't valid"); require(y < q_mod, "y axis isn't valid"); // 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, "is not on curve"); 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; 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) { // https://eips.ethereum.org/EIPS/eip-197 // Elliptic curve points are encoded as a Jacobian pair (X, Y) where the point at infinity is encoded as (0, 0) if (p.X == 0 && p.Y == 1) { p.Y = 0; } 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 { uint256[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); uint256 elements = p1.length; uint256 inputSize = elements * 6; uint256[] memory input = new uint256[](inputSize); for (uint256 i = 0; i < elements; ) { 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]; unchecked { ++i; } } uint256[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); } }
{ "optimizer": { "enabled": true, "runs": 9999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"zero","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"alpha","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[9]","name":"alpha_values","type":"tuple[9]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"eta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_plus_one","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"v","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"u","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_minus_last_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_0_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_n_minus_one_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"t","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"tp","type":"tuple"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.PartialVerifierState","name":"state","type":"tuple"}],"name":"compute_powers_of_alpha","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"get_verification_key","outputs":[{"components":[{"internalType":"uint256","name":"domain_size","type":"uint256"},{"internalType":"uint256","name":"num_inputs","type":"uint256"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[2]","name":"gate_selectors_commitments","type":"tuple[2]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[8]","name":"gate_setup_commitments","type":"tuple[8]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"permutation_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_selector_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"lookup_tables_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_table_type_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[3]","name":"non_residues","type":"tuple[3]"},{"components":[{"internalType":"uint256[2]","name":"X","type":"uint256[2]"},{"internalType":"uint256[2]","name":"Y","type":"uint256[2]"}],"internalType":"struct PairingsBn254.G2Point[2]","name":"g2_elements","type":"tuple[2]"}],"internalType":"struct VerificationKey","name":"vk","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"domain_size","type":"uint256"},{"internalType":"uint256","name":"num_inputs","type":"uint256"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[2]","name":"gate_selectors_commitments","type":"tuple[2]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[8]","name":"gate_setup_commitments","type":"tuple[8]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"permutation_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_selector_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"lookup_tables_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_table_type_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[3]","name":"non_residues","type":"tuple[3]"},{"components":[{"internalType":"uint256[2]","name":"X","type":"uint256[2]"},{"internalType":"uint256[2]","name":"Y","type":"uint256[2]"}],"internalType":"struct PairingsBn254.G2Point[2]","name":"g2_elements","type":"tuple[2]"}],"internalType":"struct VerificationKey","name":"vk","type":"tuple"},{"components":[{"internalType":"uint256[]","name":"input_values","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"state_polys_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"copy_permutation_grand_product_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"quotient_poly_parts_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[4]","name":"state_polys_openings_at_z","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[1]","name":"state_polys_openings_at_z_omega","type":"tuple[1]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[1]","name":"gate_selectors_openings_at_z","type":"tuple[1]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[3]","name":"copy_permutation_polys_openings_at_z","type":"tuple[3]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"copy_permutation_grand_product_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"quotient_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"linearization_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_s_poly_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_grand_product_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_s_poly_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_grand_product_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_t_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_t_poly_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_selector_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_table_type_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"opening_proof_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"opening_proof_at_z_omega","type":"tuple"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.Proof","name":"proof","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"zero","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"alpha","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[9]","name":"alpha_values","type":"tuple[9]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"eta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_plus_one","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"v","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"u","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_minus_last_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_0_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_n_minus_one_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"t","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"tp","type":"tuple"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.PartialVerifierState","name":"state","type":"tuple"}],"name":"prepare_queries","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[13]","name":"commitments_at_z","type":"tuple[13]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[13]","name":"values_at_z","type":"tuple[13]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[6]","name":"commitments_at_z_omega","type":"tuple[6]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[6]","name":"values_at_z_omega","type":"tuple[6]"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.Queries","name":"queries","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"domain_size","type":"uint256"},{"internalType":"uint256","name":"num_inputs","type":"uint256"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[2]","name":"gate_selectors_commitments","type":"tuple[2]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[8]","name":"gate_setup_commitments","type":"tuple[8]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"permutation_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_selector_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"lookup_tables_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_table_type_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[3]","name":"non_residues","type":"tuple[3]"},{"components":[{"internalType":"uint256[2]","name":"X","type":"uint256[2]"},{"internalType":"uint256[2]","name":"Y","type":"uint256[2]"}],"internalType":"struct PairingsBn254.G2Point[2]","name":"g2_elements","type":"tuple[2]"}],"internalType":"struct VerificationKey","name":"vk","type":"tuple"},{"components":[{"internalType":"uint256[]","name":"input_values","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"state_polys_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"copy_permutation_grand_product_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point[4]","name":"quotient_poly_parts_commitments","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[4]","name":"state_polys_openings_at_z","type":"tuple[4]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[1]","name":"state_polys_openings_at_z_omega","type":"tuple[1]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[1]","name":"gate_selectors_openings_at_z","type":"tuple[1]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[3]","name":"copy_permutation_polys_openings_at_z","type":"tuple[3]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"copy_permutation_grand_product_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"quotient_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"linearization_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_s_poly_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"lookup_grand_product_commitment","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_s_poly_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_grand_product_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_t_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_t_poly_opening_at_z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_selector_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"lookup_table_type_poly_opening_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"opening_proof_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"opening_proof_at_z_omega","type":"tuple"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.Proof","name":"proof","type":"tuple"},{"components":[{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"zero","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"alpha","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr[9]","name":"alpha_values","type":"tuple[9]"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"eta","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"gamma_lookup","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_plus_one","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"beta_gamma","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"v","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"u","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"z_minus_last_omega","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_0_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"l_n_minus_one_at_z","type":"tuple"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct PairingsBn254.Fr","name":"t","type":"tuple"},{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"tp","type":"tuple"}],"internalType":"struct Plonk4VerifierWithAccessToDNext.PartialVerifierState","name":"state","type":"tuple"}],"name":"rescue_custom_gate_linearization_contribution","outputs":[{"components":[{"internalType":"uint256","name":"X","type":"uint256"},{"internalType":"uint256","name":"Y","type":"uint256"}],"internalType":"struct PairingsBn254.G1Point","name":"result","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"public_inputs","type":"uint256[]"},{"internalType":"uint256[]","name":"serialized_proof","type":"uint256[]"}],"name":"verify_serialized_proof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506155d380620000216000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c8063bd5794e211610050578063bd5794e2146100b4578063c2ef6041146100c9578063fec4e96e146100e957600080fd5b8063330deb9f1461006c5780633ec236cb14610094575b600080fd5b61007f61007a36600461471c565b6100fe565b60405190151581526020015b60405180910390f35b6100a76100a236600461507a565b610141565b60405161008b91906151a5565b6100bc610296565b60405161008b91906152f4565b6100dc6100d736600461507a565b610af5565b60405161008b9190615427565b6100fc6100f73660046154c1565b610e59565b005b600080610109610296565b6020810151909150851461011c57600080fd5b600061012a87878787610f07565b90506101368183611360565b979650505050505050565b6040805180820190915260008082526020820152604080516020810190915260008152604080516020810190915260008152608085015161019a9060005b60200201516040805160208101909152600081529051815290565b91506101a68280611645565b60808501516101be9060015b60200201518390611671565b60808401516101d69060015b60200201518390611645565b6101e081836116c7565b60808501516101f090600161017f565b91506101fc8280611645565b608085015161020c9060026101b2565b608084015161021c9060026101ca565b61022681836116c7565b608085015161023690600261017f565b60808601519092506102499060006101ca565b60808501516102599060036101b2565b60808401516102699060036101ca565b61027381836116c7565b606086015161028c90829060015b6020020151906116f3565b9695505050505050565b61029e613fa8565b60016020820152630400000081526102d57f1dba8b5bdd64ef6ce29a9039aca3c0e524395c43b9227b96c75090cc6cc7ec97611732565b60408201526103247f14c289d746e37aa82ec428491881c4732766492a8bc2e8e3cca2000a40c0ea277f2f617a7eb9808ad9843d1e080b7cfbf99d61bb1b02076c905f31adb12731bc4161177f565b6080820151526103747f210b5cc8e6a85d63b65b701b8fb5ad24ff9c41f923432de17fe4ebae04526a8c7f05c10ab17ea731b2b87fb890fa5b10bd3d6832917a616b807a9b640888ebc73161177f565b6080820151602001526103c67f29d4d14adcfe67a2ac690d6369db6b75e82d8ab3124bc4fa1dd145f41ca6949c7e4f6cd229373f1c1f735ccf49aef6a5c32025bc36c3328596dd0db7d87bef6761177f565b6080820151604001526104197f06d15382e8cabae9f98374a9fbdadd424f48e24da7e4c65bf710fd7d7d59a05a7f22e438ad5c51673879ce17073a3d2d29327a97dc3ce61c4f88540e00087695f661177f565b60808201516060015261046c7f274a668dfc485cf192d0086f214146d9e02b3040a5a586df344c53c16a87882b7f15f5bb7ad01f162b70fc77c8ea456d67d15a6ce98acbbfd521222810f8ec0a6661177f565b60808281015101526104be7f0ba53bf4fb0446927857e33978d02abf45948fc68f4091394ae0827a22cf1e477f0720d818751ce5b3f11c716e925f60df4679ea90bed516499bdec066f5ff108f61177f565b608082015160a001526105117f2e986ba2ea495e5ec6af532980b1dc567f1430bfa82f8de07c12fc097c0e04837f1555d189f6164e82d78de1b8313c2e923e616b3c8ed0e350c3b61c94516d0b5861177f565b608082015160c001526105647f0925959592604ca73c917f9b2e029aa2563c318ddcc5ca29c11badb7b880127b7f2b4a430fcb2fa7d6d67d6c358e01cf0524c7df7e1e56442f65b39bc1a105236761177f565b608082015160e001526105b77f28f2a0a95af79ba67e9dd1986bd3190199f661b710a693fc82fb395c126edcbd7f0db75db5de5192d1ba1c24710fc00da16fa8029ac7fe82d855674dcd6d090e0561177f565b6060820151526106077f143471a174dfcb2d9cb5ae621e519387bcc93c9dcfc011160b2f5c5f88e32cbe7f2a0194c0224c3d964223a96c4c99e015719bc879125aa0df3f0715d154e71a3161177f565b60608201516020015261065a7f1423fa82e00ba22c280181afb12c56eea541933eeb5ec39119b0365b6beab4b97f0efdcd3423a38f5e2ecf8c7e4fd46f13189f8fed392ad9d8d393e8ba568b06e461177f565b60a0820151526106aa7f0e9b5b12c1090d62224e64aa1696c009aa59a9c3eec458e781fae773e1f4eca57f1fe3df508c7e9750eb37d9cae5e7437ad11a21fa36530ff821b407b165a79a5561177f565b60a0820151602001526106fd7f25d1a714bd1e258f196e38d6b2826153382c2d04b870d0b7ec250296005129ae7f0883a121b41ca7beaa9de97ecf4417e62aa2eeb9434f24ddacbfed57cbf016a861177f565b60a0820151604001526107507f2f3ede68e854a6b3b14589851cf077a606e2aeb3205c43cc579b7abae39d8f587f178ccd4b1f78fd79ee248e376b6fc8297d5450900d1e15e8c03e3ed2c171ac8c61177f565b60a0820151606001526107a37f1f814e2d87c332e964eeef94ec695eef9d2caaac58b682a43da5107693b06f307f196d56fb01907e66af9303886fd95328d398e5b2b72906882a9d12c1718e2ee261177f565b60c08201526107f27f0ebe0de4a2f39df3b903da484c1641ffdffb77ff87ce4f9508c548659eb22d3c7f12a3209440242d5662729558f1017ed9dcc08fe49a99554dd45f5f15da5e4e0b61177f565b60e0820151526108427f1b7d54f8065ca63bed0bfbb9280a1011b886d07e0c0a26a66ecc96af68c53bf97f2c51121fff5b8f58c302f03c74e0cb176ae5a1d1730dec4696eb9cce3fe284ca61177f565b60e0820151602001526108957f0138733c5faa9db6d4b8df9748081e38405999e511fb22d40f77cf3aef293c447f269bee1c1ac28053238f7fe789f1ea2e481742d6d16ae78ed81e87c254af076561177f565b60e0820151604001526108e87f1b1be7279d59445065a95f01f16686adfa798ec4f1e6845ffcec9b837e88372e7f057c90cb96d8259238ed86b05f629efd55f472a721efeeb56926e979433e6c0e61177f565b60e08201516060015261093b7f2f85df2d6249ccbcc11b91727333cc800459de6ee274f29c657c8d56f6f015637f088e1df178c47116a69c3c8f6d0c5feb530e2a72493694a623b1cceb7d44a76c61177f565b61010082015261094b6005611732565b6101208201515261095c6007611732565b61012082015160200152610970600a611732565b61012082015160026020020181905250610a3260405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81525060405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152506117aa565b610140820151526040805180820182527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c181527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b060208281019190915282518084019093527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe483527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e5590830152610ae8916117aa565b6101408201516020015290565b610afd61406f565b600260005b6004811015610b805784602001518160048110610b2157610b216154e5565b6020020151835183600d8110610b3957610b396154e5565b602002015260808501518160048110610b5457610b546154e5565b6020020151836020015183600d8110610b6f57610b6f6154e5565b602002015260019182019101610b02565b50606085015151825182600d8110610b9a57610b9a6154e5565b602002015260c084015160006020020151826020015182600d8110610bc157610bc16154e5565b602002015260010160005b610bd860016004615543565b811015610c54578560a001518160048110610bf557610bf56154e5565b6020020151835183600d8110610c0d57610c0d6154e5565b602002015260e08501518160038110610c2857610c286154e5565b6020020151836020015183600d8110610c4357610c436154e5565b602002015260019182019101610bcc565b5060408481015190830151526020840151610c7160016004615543565b60048110610c8157610c816154e5565b6020908102919091015160408401518201526101008501516060840180519190915260a0808701515191519092015260e08601515190840151600090610cd7906040805160208101909152600081529051815290565b905060015b6004811015610d2a57610cff828960e001518360048110610281576102816154e5565b6102408701819052610d129084906117b2565b60a0860151610d22908390611645565b600101610cdc565b508351829084600d8110610d4057610d406154e5565b6020020181905250856101e00151846020015184600d8110610d6457610d646154e5565b602002015260c087015184516001949094019384600d8110610d8857610d886154e5565b6020020181905250856102200151846020015184600d8110610dac57610dac6154e5565b602002015261010087015184516001949094019384600d8110610dd157610dd16154e5565b6020020181905250856102400151846020015184600d8110610df557610df56154e5565b602002015250610160850151604084810180518201929092526101a0870151606080870180519093019190915261018088015183518201526101c0880151825190910152905160809081019290925261020090950151945101939093529392505050565b602081015151600003610e6b57600080fd5b610e756001611732565b608082018051919091526020808301805160408051808501825260008082529251815294518401949094529051835192830190935281529051815260025b6009811015610f02576020830151610ecc908390611645565b6040805160208101909152600081528251815283608001518260098110610ef557610ef56154e5565b6020020152600101610eb3565b505050565b610f0f6140a9565b602c8214610f1c57600080fd5b8367ffffffffffffffff811115610f3557610f35614788565b604051908082528060200260200182016040528015610f5e578160200160208202803683370190505b50815260005b84811015610fae57858582818110610f7e57610f7e6154e5565b9050602002013582600001518281518110610f9b57610f9b6154e5565b6020908102919091010152600101610f64565b506000805b600481101561102857610fff858584818110610fd157610fd16154e5565b905060200201358686610fe48660010190565b818110610ff357610ff36154e5565b905060200201356117c1565b83602001518260048110611015576110156154e5565b6020020152600282019150600101610fb3565b5061105184848381811061103e5761103e6154e5565b905060200201358585610fe48560010190565b604083015260020161106e84848381811061103e5761103e6154e5565b61016083015260020161108c84848381811061103e5761103e6154e5565b61018083015260020160005b60048110156110df576110b6858584818110610fd157610fd16154e5565b836060015182600481106110cc576110cc6154e5565b6020020152600282019150600101611098565b5060005b60048110156111345761110d858584818110611101576111016154e5565b90506020020135611732565b83608001518260048110611123576111236154e5565b6020020152600191820191016110e3565b5060005b600181101561117d57611156858584818110611101576111016154e5565b8360a00151826001811061116c5761116c6154e5565b602002015260019182019101611138565b5060005b60018110156111c65761119f858584818110611101576111016154e5565b8360c0015182600181106111b5576111b56154e5565b602002015260019182019101611181565b5060005b600381101561120f576111e8858584818110611101576111016154e5565b8360e0015182600381106111fe576111fe6154e5565b6020020152600191820191016111ca565b50611225848483818110611101576111016154e5565b610100830152600101611243848483818110611101576111016154e5565b6101a0830152600101611261848483818110611101576111016154e5565b6101c083015260010161127f848483818110611101576111016154e5565b6101e083015260010161129d848483818110611101576111016154e5565b6102008301526001016112bb848483818110611101576111016154e5565b6102208301526001016112d9848483818110611101576111016154e5565b6102408301526001016112f7848483818110611101576111016154e5565b610120830152600101611315848483818110611101576111016154e5565b61014083015260010161133384848381811061103e5761103e6154e5565b61026083015260020161135184848381811061103e5761103e6154e5565b61028083015250949350505050565b60008061136d8484611a37565b905061137a8385836127a8565b151560000361138d57600091505061163f565b60608401516000906113c690825b6020020151604080518082019091526000808252602080830191825283518352929092015190915290565b84516101808401519192506000916113dd91612ab3565b604080516020808201835260008083528451835283518085019094528084529083015291925060015b6004811015611450576114288960600151826004811061139b5761139b6154e5565b91506114348284612b44565b61143e85836117b2565b6114488385611645565b600101611406565b505050506000611461858785610af5565b8051839052610120870151602082015152905061147f858785612b4f565b815160209081019190915261014087015181830180519092015281515190515160006114ab6001611732565b90506114ca604051806040016040528060008152602001600081525090565b60015b600d811015611553576101408801516114e7908490611645565b61150183876000015183600d8110610281576102816154e5565b915061150d85836117b2565b856020015181600d8110611523576115236154e5565b6020020151610220890181905261153a9084611645565b61022088015161154b9085906116c7565b6001016114cd565b50610140870151611565908390611645565b6000611582838760400151600060068110610281576102816154e5565b6060870151519091506115958185611645565b60015b600681101561161e576101408a01516115b2908690611645565b6115cc8589604001518360068110610281576102816154e5565b93506115d883856117b2565b876060015181600681106115ee576115ee6154e5565b60200201516102208b018190526116059086611645565b6102208a01516116169083906116c7565b600101611598565b506116338b61014001518d8b89868a87612fa1565b99505050505050505050505b92915050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001815183510990915250565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181516116be907f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001615543565b83510890915250565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001815183510890915250565b6040805180820190915260008082526020820152825115801561171a575082602001516001145b1561172757600060208401525b61163f83838361313c565b6040805160208101909152600081527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001821061176d57600080fd5b50604080516020810190915290815290565b60408051808201909152600080825260208201525b5060408051808201909152918252602082015290565b6117946142b7565b6117bd82828461317e565b5050565b6040805180820190915260008082526020820152821580156117e1575081155b1561180257604051806040016040528084815260200183815250905061163f565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478310611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f7820617869732069736e27742076616c6964000000000000000000000000000060448201526064015b60405180910390fd5b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f7920617869732069736e27742076616c696400000000000000000000000000006044820152606401611887565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47838409905060007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785860990507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785820990507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47600382089050808214611a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6973206e6f74206f6e20637572766500000000000000000000000000000000006044820152606401611887565b50506040805180820190915292835250602082015290565b611a3f6142d7565b60408051606081018252600080825260208201819052918101829052905b8360200151811015611aa157611a9985600001518281518110611a8257611a826154e5565b60200260200101518361320e90919063ffffffff16565b600101611a5d565b5060005b6004811015611beb57611be385602001518260048110611ac757611ac76154e5565b602002015183908051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b0181529284018552825192880192909220909a528451835180880198909852998701989098529185019790975283850195909552855180840390940184529190930190935280519101209052565b600101611aa5565b50611bf5816132f1565b60a08301526101608401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b01815292840185528251928801929092208b528551845180890199909952908801999099529286019790975284860191909152805180850390950185529290940190915281519101209052611d1b816132f1565b6040830152611d29816132f1565b6060830152604084810151805183516020808601805186516000818501819052602480830187905260448084019490945260648084018990528a518085038201815260849485018c528051908801208c5285518b517c0100000000000000000000000000000000000000000000000000000000818a018190528185019a909a5280870191909152808201999099528a51808a03820181529884018b52885198870198909820808652988601518b518b51808901949094528383018190528386019a909a528289018190528a518084038a0181529284018b528251928701929092208b5284518a5180880198909852908701989098529185019690965283850152855180840390940184529190930190935280519101209052611e4a816132f1565b60c0830152611e58816132f1565b60e08301526101808401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b01815292840185528251928801929092208b528551845180890199909952908801999099529286019790975284860191909152805180850390950185529290940190915281519101209052611f7e816132f1565b602083015260005b6004811015611fb057611fa885606001518260048110611ac757611ac76154e5565b600101611f86565b50611fba816132f1565b610180830152610120840151518151602080840180516040805160008186015260248082018790526044808301949094526064808301899052835180840382018152608493840185528051908801208a52855184517c0100000000000000000000000000000000000000000000000000000000818a015292830198909852938101969096528583019690965280518086039092018252939094019092528251920191909120905260005b60048110156121325761212a85608001518260048110612086576120866154e5565b6020908102919091015151845185830180516040805160008188015260248082018690526044808301949094526064808301889052835180840382018152608493840185528051908a01208c52855184517c0100000000000000000000000000000000000000000000000000000000818c01529283019790975293810195909552848301959095528051808503909201825292909301909152815191909201209052565b600101612064565b5060005b6001811015612160576121588560a001518260018110612086576120866154e5565b600101612136565b5060005b600181101561218e576121868560c001518260018110612086576120866154e5565b600101612164565b5060005b60038110156121bc576121b48560e001518260038110612086576120866154e5565b600101612192565b506101808201516040805160208101825260008152915182526101a084018290528401516121ea9190611645565b61010084015151815160208084018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208b52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b038201815299840185528951998801999099208087526101e08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102208e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102408e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101a08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101c08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102008e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101408e0151518b518651808b019590955284840181905284880192909252838b0181905285518085038c01815293850186528351938901939093208b5286518551808a019a909a5291890152938701939093528587019290925280518086039096018652930190925282519201919091209052612599816132f1565b6101408301526102608401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a018590528084018290528088019c909c528b8b018290528551808d038c0181529b850186528b519b89019b909b208c5286518551808a018b90528084019c909c528b8701528a8a01528351808b038a01815299830184528951998701999099208086526102808e015180518c518651808b01869052808e0182905280890194909452838c0182905286518085038d01815293860187528351938a01939093208d5287518651808b018c9052808e019490945283880152828b015284518083038b0181529184018552815191880191909120808752908701518b518551808a0194909452838c0181905283870192909252828a0181905284518084038b01815292840185528251928801929092208b52855184518089019990995299880152928601979097528486019190915280518085039095018552929094019091528151910120905261279b816132f1565b6101608301525092915050565b600080846020015167ffffffffffffffff8111156127c8576127c8614788565b6040519080825280602002602001820160405280156127f1578160200160208202803683370190505b50905060005b81518110156128265780828281518110612813576128136154e5565b60209081029190910101526001016127f7565b50600085602001511161283857600080fd5b60006128446000611732565b905060005b86602001518110156128c25761286e81886000015189604001518861018001516133e1565b610220860152855180516128a99161289d9184908110612890576128906154e5565b6020026020010151611732565b61022087015190611645565b6102208501516128ba9083906116c7565b600101612849565b5060c08501516128db9060005b60200201518290611645565b610140850151604080516020810190915260008152905181526128fe81836116c7565b61290785610e59565b608085015160009061291a90600461017f565b90506129348761010001518261164590919063ffffffff16565b61294060016004615543565b60031461294c57600080fd5b60408051602081019091526000815260005b60038110156129e0576129808960e00151826003811061017f5761017f6154e5565b915061299988604001518361164590919063ffffffff16565b6129be896080015182600481106129b2576129b26154e5565b602002015183906116c7565b60608801516129ce9083906116c7565b6129d88383611645565b60010161295e565b5060808801516129f190600361017f565b9050612a0a8760600151826116c790919063ffffffff16565b612a148282611645565b612a1e8383611671565b6000612a338a6000015189610180015161348f565b6080890151909150612a469060056128cf565b612a508482611671565b6000612a5d8b8b8b613515565b9050612a6985826116c7565b6101208a0151604080516020810190915260008152905181528b516101808b0151612a9e91612a9791613765565b8290611645565b945194519094149a9950505050505050505050565b604080516020808201835260008252825160c0810184528181528082018290529283015283516060830152608082018390527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000160a083015290612b1461448b565b600060208260c08560055afa905080612b2c57600080fd5b50604080516020810190915290518152949350505050565b6117bd82828461313c565b6040805180820190915260008082526020820152612b6e60008061177f565b90506000612b9d8460800151600060048110612b8c57612b8c6154e5565b602002015160808701516000610281565b9050612ba982826117b2565b6080840151612bc5906001602002015160808701516001610281565b9050612bd182826117b2565b6080840151612bed906002602002015160808701516002610281565b9050612bf982826117b2565b6080840151612c15906003602002015160808701516003610281565b9050612c2182826117b2565b6080840151600090612c33908261017f565b6080860151909150612c469060016128cf565b6080860151612c589082906004610281565b9150612c6483836117b2565b6080850151612c7490600061017f565b6080860151909150612c879060026128cf565b6080860151612c999082906005610281565b9150612ca583836117b2565b608086015160c00151612cb99084906117b2565b60a0850151516080870151612cd091906007610281565b9150612cdc83836117b2565b60c085015151612ced908490612b44565b6000612cfa878787610141565b9050612d0684826117b2565b612d1260016004615543565b600314612d1e57600080fd5b6000612d2a6001611732565b90506000612d48876080015160046009811061017f5761017f6154e5565b905060005b6004811015612e105761018088015160408051602081019091526000815290518152945080600003612d8857612d838584611645565b612db9565b6101208a0151612db990612d9d600184615543565b60038110612dad57612dad6154e5565b60200201518690611645565b6040880151612dc9908690611645565b6060880151612dd99086906116c7565b612dfe89608001518260048110612df257612df26154e5565b602002015186906116c7565b612e088286611645565b600101612d4d565b506040880151612e2090826116f3565b9450612e2c86866117b2565b6080870151612e3c90600461017f565b9050612e5587604001518261164590919063ffffffff16565b610100880151612e66908290611645565b60005b612e7560016004615543565b811015612ee957612e958960e00151826003811061017f5761017f6154e5565b9450612eae88604001518661164590919063ffffffff16565b6060880151612ebe9086906116c7565b612ed789608001518260048110612df257612df26154e5565b612ee18286611645565b600101612e69565b5060a0890151612efc9082906003610281565b9450612f088686613794565b612f2260008a600001518b604001518a61018001516133e1565b6101e0880181905251600003612f3757600080fd5b506101e0860151604080516020810190915260008152905181526080870151612f619060056128cf565b6040880151612f7090826116f3565b9450612f7c86866117b2565b6000612f88898961379f565b9050612f9487826117b2565b5050505050509392505050565b60408051808201909152600080825260208083018281528751845290870151905290612fdb87610160015186612b4490919063ffffffff16565b612fe581866117b2565b60408051602081019091526000815283518152610160880151613009908290611645565b61301381866116c7565b600061304b82613045604080518082018252600080825260209182015281518083019092526001825260029082015290565b906116f3565b90506130578382613794565b6101808901516102608b015161306c916116f3565b9050600061308f8a6101a001516040805160208101909152600081529051815290565b90506130a98a61016001518261164590919063ffffffff16565b6102808b01516000906130bc90836116f3565b90506130c883826117b2565b6130d285846117b2565b60006130f18c61016001518e61028001516116f390919063ffffffff16565b905061310b8d6102600151826117b290919063ffffffff16565b61311481613a6d565b8d5160208f015161312788838584613abf565b98505050505050505050979650505050505050565b6131446144a9565b835181526020840151816001602002015282518160026020020152600060408360608460075afa90508061317757600080fd5b5050505050565b815115801561318f57506020820151155b156131a7578251815260209283015192019190915250565b82511580156131b857506020830151155b156131cd578151815260209182015191015250565b6131d56144c7565b8351815260208085015181830152835160408301528301518160035b6020020152600060408360808460065afa90508061317757600080fd5b815160208084015160405160009281019290925260248201839052604482015260648101839052608401604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152918152815160209283012085528482015190517c01000000000000000000000000000000000000000000000000000000009281019290925260248201839052604482015260648101839052608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020918201209301929092525050565b604080516020810190915260008152815160208084015160408086015190517c0200000000000000000000000000000000000000000000000000000000938101939093526024830193909352604482015260e09190911b7fffffffff000000000000000000000000000000000000000000000000000000001660648201526000906068016040516020818303038152906040528051906020012090506001836040018181516133a09190615556565b63ffffffff1690525060408051602081019091527f1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91909116815292915050565b6040805160208101909152600081528385106133fc57600080fd5b60006134086001611732565b905060006134168588612ab3565b90506134228487612ab3565b925061342e8383611671565b825160000361343c57600080fd5b6134468382611645565b604080516020810190915260008152845181526134638183611671565b61346f612a9788611732565b61347881613bbf565b90506134848482611645565b505050949350505050565b60408051602081019091526000815260006134aa6001611732565b905060006134b785611732565b604080516020810190915260008152855181529091506134d78184611671565b6134e18183611645565b6134ea81613bbf565b90506134f68587612ab3565b93506135028484611671565b61350c8482611645565b50505092915050565b604080516020810190915260008152604080516020810190915260008152600061353f6001611732565b905061355f8460c001516040805160208101909152600081529051815290565b610100850181905261357190826116c7565b61010084015160408051602081019091526000815290518152610120850181905260e08501516135a19190611645565b6101a08501516040805160208101909152600081529051815291506135d38460c001518361164590919063ffffffff16565b6101208401516135e49083906116c7565b6101c08501516135f5908390611645565b60808401516136059060066101ca565b60006136266001886000015161361b9190615543565b604089015190612ab3565b90506136478561018001516040805160208101909152600081529051815290565b6101c086018190526136599082611671565b6101c085015161366a908490611645565b61367484846116c7565b61368e6000886000015189604001518861018001516133e1565b6101e0860181905260408051602081019091526000815290518152608086015160e001519093506136c0908490611645565b6136ca8484611671565b60006136ec600189600001516136e09190615543565b61012088015190612ab3565b9050613714600189600001516137029190615543565b895160408b01516101808a01516133e1565b610200870181905260408051602081019091526000815290518152935061373b8482611645565b60808601516101000151613750908590611645565b61375a8585611671565b505050509392505050565b60408051602081019091526000815261377e8284612ab3565b905061163f61378d6001611732565b8290611671565b6117bd828284613c10565b604080518082019091526000808252602082015260006137bf6000611732565b90506137d76040518060200160405280600081525090565b60408051602080820183526000918290526101c0880151835191820190935290815290518152608085015161380d9060066128cf565b6101c085015161381e908290611645565b61016086015160009061383190836116f3565b905061383d85826117b2565b61020087015160408051602081019091526000815290518152915061386f8660c001518361164590919063ffffffff16565b6101e08701516138809083906116c7565b6101208601516138919083906116c7565b60408051602081019091526000815260006138ac6001611732565b90506138c46040518060200160405280600081525090565b60005b6138d360016004615543565b811015613921576138f38b60800151826004811061017f5761017f6154e5565b91506138ff8284611645565b61390984836116c7565b60a08a0151613919908490611645565b6001016138c7565b506102408a01516040805160208101909152600081529051815295506139478683611645565b61395183876116c7565b6102208a0151613962908490611645565b60e08901516139729084906116c7565b61397c8584611645565b61010089015161398d908690611645565b6040805160208101909152600081528751815295506139ac8686611671565b60808901518695506139bf906006612dad565b6101c08901516139d0908690611645565b6101e08901516040805160208101909152600081529051815260808a0151909650613a049060075b60200201518790611645565b613a0e85876116c7565b6102008901516040805160208101909152600081529051815260808a0151909650613a3a9060086139f8565b613a4485876116c7565b6101808a0151613a5490866116f3565b9350613a6088856117b2565b5050505050505092915050565b8060200151600003613a8857805115613a8557600080fd5b50565b6020810151613ab7907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b602090910152565b60408051600280825260608201909252600091829190816020015b6040805180820190915260008082526020820152815260200190600190039081613ada5750506040805160028082526060820190925291925060009190602082015b613b246142b7565b815260200190600190039081613b1c5790505090508682600081518110613b4d57613b4d6154e5565b60200260200101819052508482600181518110613b6c57613b6c6154e5565b60200260200101819052508581600081518110613b8b57613b8b6154e5565b60200260200101819052508381600181518110613baa57613baa6154e5565b60200260200101819052506101368282613cde565b6040805160208101909152600081528151600003613bdc57600080fd5b61163f82613c0b60027f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001615543565b612ab3565b8151158015613c2157506020820151155b15613c39578251815260209283015192019190915250565b8251158015613c4a57506020830151155b15613c8c57815181526020820151613c82907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b6020909101525050565b613c946144c7565b835181526020808501518183015283516040830152830151613cd6907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b8160036131f1565b60008151835114613cee57600080fd5b82516000613cfd826006615573565b905060008167ffffffffffffffff811115613d1a57613d1a614788565b604051908082528060200260200182016040528015613d43578160200160208202803683370190505b50905060005b83811015613f7457868181518110613d6357613d636154e5565b60200260200101516000015182826006613d7d9190615573565b613d8890600061558a565b81518110613d9857613d986154e5565b602002602001018181525050868181518110613db657613db66154e5565b60200260200101516020015182826006613dd09190615573565b613ddb90600161558a565b81518110613deb57613deb6154e5565b602002602001018181525050858181518110613e0957613e096154e5565b6020908102919091010151515182613e22836006615573565b613e2d90600261558a565b81518110613e3d57613e3d6154e5565b602002602001018181525050858181518110613e5b57613e5b6154e5565b60209081029190910181015151015182613e76836006615573565b613e8190600361558a565b81518110613e9157613e916154e5565b602002602001018181525050858181518110613eaf57613eaf6154e5565b602002602001015160200151600060028110613ecd57613ecd6154e5565b602002015182613ede836006615573565b613ee990600461558a565b81518110613ef957613ef96154e5565b602002602001018181525050858181518110613f1757613f176154e5565b602002602001015160200151600160028110613f3557613f356154e5565b602002015182613f46836006615573565b613f5190600561558a565b81518110613f6157613f616154e5565b6020908102919091010152600101613d49565b50613f7d61448b565b6000602082602086026020860160085afa905080613f9a57600080fd5b505115159695505050505050565b6040518061016001604052806000815260200160008152602001613fd86040518060200160405280600081525090565b8152602001613fe56144e5565b8152602001613ff261451e565b8152602001613fff61454a565b8152602001614021604051806040016040528060008152602001600081525090565b815260200161402e61454a565b8152602001614050604051806040016040528060008152602001600081525090565b815260200161405d614573565b815260200161406a6145a7565b905290565b60405180608001604052806140826145d4565b815260200161408f614600565b815260200161409c614623565b815260200161406a61464d565b604051806102a00160405280606081526020016140c461454a565b81526020016140e6604051806040016040528060008152602001600081525090565b81526020016140f361454a565b815260200161410061466e565b8152604080518082018252600060208083018281528352808501929092528251808401845291820190815281529082015260600161413c614573565b81526020016141576040518060200160405280600081525090565b81526020016141726040518060200160405280600081525090565b815260200161418d6040518060200160405280600081525090565b81526020016141af604051806040016040528060008152602001600081525090565b81526020016141d1604051806040016040528060008152602001600081525090565b81526020016141ec6040518060200160405280600081525090565b81526020016142076040518060200160405280600081525090565b81526020016142226040518060200160405280600081525090565b815260200161423d6040518060200160405280600081525090565b81526020016142586040518060200160405280600081525090565b81526020016142736040518060200160405280600081525090565b8152602001614295604051806040016040528060008152602001600081525090565b815260200161406a604051806040016040528060008152602001600081525090565b60405180604001604052806142ca61468f565b815260200161406a61468f565b604080516102808101825260006102608201818152825282516020808201855282825280840191909152835180820185528281528385015283519081019093528252906060820190815260200161432c6146ad565b81526020016143476040518060200160405280600081525090565b81526020016143626040518060200160405280600081525090565b815260200161437d6040518060200160405280600081525090565b81526020016143986040518060200160405280600081525090565b81526020016143b36040518060200160405280600081525090565b81526020016143ce6040518060200160405280600081525090565b81526020016143e96040518060200160405280600081525090565b81526020016144046040518060200160405280600081525090565b815260200161441f6040518060200160405280600081525090565b815260200161443a6040518060200160405280600081525090565b81526020016144556040518060200160405280600081525090565b81526020016144706040518060200160405280600081525090565b81526020016142956040518060200160405280600081525090565b60405180602001604052806001906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b60405180604001604052806002905b60408051808201909152600080825260208201528152602001906001900390816144f45790505090565b6040805161014081019091526000610100820181815261012083019190915281526007602082016144f4565b6040805160c0810190915260006080820181815260a083019190915281526003602082016144f4565b60405180606001604052806003905b6040805160208101909152600081528152602001906001900390816145825790505090565b60405180604001604052806002905b6145be6142b7565b8152602001906001900390816145b65790505090565b604080516101e0810190915260006101a082018181526101c08301919091528152600c602082016144f4565b604080516101c0810190915260006101a082019081528152600c60208201614582565b604080516101008101909152600060c0820181815260e083019190915281526005602082016144f4565b6040805160e08101909152600060c082019081528152600560208201614582565b6040805160a081019091526000608082019081528152600360208201614582565b60405180604001604052806002906020820280368337509192915050565b604080516101408101909152600061012082019081528152600860208201614582565b60008083601f8401126146e257600080fd5b50813567ffffffffffffffff8111156146fa57600080fd5b6020830191508360208260051b850101111561471557600080fd5b9250929050565b6000806000806040858703121561473257600080fd5b843567ffffffffffffffff8082111561474a57600080fd5b614756888389016146d0565b9096509450602087013591508082111561476f57600080fd5b5061477c878288016146d0565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156147da576147da614788565b60405290565b6040516102a0810167ffffffffffffffff811182821017156147da576147da614788565b604051610260810167ffffffffffffffff811182821017156147da576147da614788565b604051610160810167ffffffffffffffff811182821017156147da576147da614788565b6040516080810167ffffffffffffffff811182821017156147da576147da614788565b60006020828403121561488157600080fd5b6040516020810181811067ffffffffffffffff821117156148a4576148a4614788565b6040529135825250919050565b6000604082840312156148c357600080fd5b6148cb6147b7565b9050813581526020820135602082015292915050565b600082601f8301126148f257600080fd5b6148fa6147b7565b80608084018581111561490c57600080fd5b845b818110156149305761492087826148b1565b845260209093019260400161490e565b509095945050505050565b600082601f83011261494c57600080fd5b60408051610100810181811067ffffffffffffffff8211171561497157614971614788565b82528061020085018681111561498657600080fd5b855b818110156149a95761499a88826148b1565b83526020909201918401614988565b50919695505050505050565b600082601f8301126149c657600080fd5b6149ce61484c565b806101008401858111156149e157600080fd5b845b81811015614930576149f587826148b1565b84526020909301926040016149e3565b600082601f830112614a1657600080fd5b6040516060810181811067ffffffffffffffff82111715614a3957614a39614788565b604052806060840185811115614a4e57600080fd5b845b81811015614a7057614a62878261486f565b835260209283019201614a50565b509195945050505050565b600082601f830112614a8c57600080fd5b614a946147b7565b806040840185811115614aa657600080fd5b845b81811015614930578035845260209384019301614aa8565b600082601f830112614ad157600080fd5b614ad96147b7565b80610100840185811115614aec57600080fd5b845b818110156149305760808188031215614b075760008081fd5b614b0f6147b7565b614b198883614a7b565b8152614b288860408401614a7b565b6020828101919091529085529390930192608001614aee565b600082601f830112614b5257600080fd5b8135602067ffffffffffffffff80831115614b6f57614b6f614788565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715614bb257614bb2614788565b604052938452858101830193838101925087851115614bd057600080fd5b83870191505b8482101561013657813583529183019190830190614bd6565b600082601f830112614c0057600080fd5b614c0861484c565b806080840185811115614c1a57600080fd5b845b8181101561493057614c2e878261486f565b845260209384019301614c1c565b600082601f830112614c4d57600080fd5b604051602080820182811067ffffffffffffffff82111715614c7157614c71614788565b6040528184820186811115614c8557600080fd5b855b81811015614ca657614c99888261486f565b8352918301918301614c87565b50929695505050505050565b60006105a08284031215614cc557600080fd5b614ccd6147e0565b9050813567ffffffffffffffff811115614ce657600080fd5b614cf284828501614b41565b825250614d0283602084016149b5565b6020820152610120614d16848285016148b1565b6040830152610160614d2a858286016149b5565b6060840152610260614d3e86828701614bef565b6080850152614d51866102e08701614c3c565b60a0850152614d64866103008701614c3c565b60c0850152614d77866103208701614a05565b60e0850152614d8a86610380870161486f565b610100850152614d9e866103a0870161486f565b83850152614db0866103c0870161486f565b610140850152614dc4866103e087016148b1565b82850152614dd68661042087016148b1565b610180850152614dea86610460870161486f565b6101a0850152614dfe86610480870161486f565b6101c0850152614e12866104a0870161486f565b6101e0850152614e26866104c0870161486f565b610200850152614e3a866104e0870161486f565b610220850152614e4e86610500870161486f565b610240850152614e628661052087016148b1565b81850152505050614e778361056084016148b1565b61028082015292915050565b600082601f830112614e9457600080fd5b60405161012080820182811067ffffffffffffffff82111715614eb957614eb9614788565b60405283018185821115614ecc57600080fd5b845b82811015614a7057614ee0878261486f565b825260209182019101614ece565b60006103808284031215614f0157600080fd5b614f09614804565b9050614f15838361486f565b8152614f24836020840161486f565b6020820152614f36836040840161486f565b6040820152614f48836060840161486f565b6060820152614f5a8360808401614e83565b60808201526101a0614f6e8482850161486f565b60a08301526101c0614f828582860161486f565b60c08401526101e0614f968682870161486f565b60e0850152610200614faa8782880161486f565b610100860152610220614fbf8882890161486f565b610120870152610240614fd489828a0161486f565b610140880152614fe8896102608a0161486f565b610160880152614ffc896102808a0161486f565b610180880152615010896102a08a0161486f565b86880152615022896102c08a0161486f565b85880152615034896102e08a0161486f565b84880152615046896103008a0161486f565b83880152615058896103208a0161486f565b8288015261506a896103408a016148b1565b8188015250505050505092915050565b6000806000838503610a6081121561509157600080fd5b6106c0808212156150a157600080fd5b6150a9614828565b915085358252602086013560208301526150c6876040880161486f565b60408301526150d887606088016148e1565b60608301526150ea8760e0880161493b565b60808301526150fd876102e088016149b5565b60a0830152615110876103e088016148b1565b60c08301526151238761042088016149b5565b60e08301526151368761052088016148b1565b61010083015261514a876105608801614a05565b61012083015261515e876105c08801614ac0565b61014083015290935084013567ffffffffffffffff81111561517f57600080fd5b61518b86828701614cb2565b92505061519c856106e08601614eee565b90509250925092565b81518152602080830151908201526040810161163f565b8060005b60028110156151f4576151de84835180518252602090810151910152565b60409390930192602091909101906001016151c0565b50505050565b8060005b60088110156151f45761521c84835180518252602090810151910152565b60409390930192602091909101906001016151fe565b8060005b60048110156151f45761525484835180518252602090810151910152565b6040939093019260209190910190600101615236565b8060005b60038110156151f45781515184526020938401939091019060010161526e565b8060005b60028110156151f4578151845260209384019390910190600101615292565b8060005b60028110156151f45781516152cb85825161528e565b602090810151906152df604087018361528e565b608095909501949290920191506001016152b5565b60006106c0820190508251825260208301516020830152604083015161531d6040840182519052565b50606083015161533060608401826151bc565b50608083015161534360e08401826151fa565b5060a08301516153576102e0840182615232565b5060c083015180516103e08401526020015161040083015260e0830151615382610420840182615232565b506101008301518051610520840152602001516105408301526101208301516153af61056084018261526a565b506101408301516153c46105c08401826152b1565b5092915050565b8060005b60068110156151f4576153ed84835180518252602090810151910152565b60409390930192602091909101906001016153cf565b8060005b60068110156151f457815151845260209384019390910190600101615407565b81516107208201908260005b600d8110156154675761545182845180518252602090810151910152565b6020929092019160409190910190600101615433565b505050602080840151610340840160005b600d8110156154965782515182529183019190830190600101615478565b5050505060408301516154ad6104e08401826153cb565b5060608301516153c4610660840182615403565b600061038082840312156154d457600080fd5b6154de8383614eee565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561163f5761163f615514565b63ffffffff8181168382160190808211156153c4576153c4615514565b808202811582820484141761163f5761163f615514565b8082018082111561163f5761163f61551456fea2646970667358221220d2f17e9a0c25b77d7be3c1b56c33d3a035f0c73e0cf8dea1efb788c1f63f7bb364736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063bd5794e211610050578063bd5794e2146100b4578063c2ef6041146100c9578063fec4e96e146100e957600080fd5b8063330deb9f1461006c5780633ec236cb14610094575b600080fd5b61007f61007a36600461471c565b6100fe565b60405190151581526020015b60405180910390f35b6100a76100a236600461507a565b610141565b60405161008b91906151a5565b6100bc610296565b60405161008b91906152f4565b6100dc6100d736600461507a565b610af5565b60405161008b9190615427565b6100fc6100f73660046154c1565b610e59565b005b600080610109610296565b6020810151909150851461011c57600080fd5b600061012a87878787610f07565b90506101368183611360565b979650505050505050565b6040805180820190915260008082526020820152604080516020810190915260008152604080516020810190915260008152608085015161019a9060005b60200201516040805160208101909152600081529051815290565b91506101a68280611645565b60808501516101be9060015b60200201518390611671565b60808401516101d69060015b60200201518390611645565b6101e081836116c7565b60808501516101f090600161017f565b91506101fc8280611645565b608085015161020c9060026101b2565b608084015161021c9060026101ca565b61022681836116c7565b608085015161023690600261017f565b60808601519092506102499060006101ca565b60808501516102599060036101b2565b60808401516102699060036101ca565b61027381836116c7565b606086015161028c90829060015b6020020151906116f3565b9695505050505050565b61029e613fa8565b60016020820152630400000081526102d57f1dba8b5bdd64ef6ce29a9039aca3c0e524395c43b9227b96c75090cc6cc7ec97611732565b60408201526103247f14c289d746e37aa82ec428491881c4732766492a8bc2e8e3cca2000a40c0ea277f2f617a7eb9808ad9843d1e080b7cfbf99d61bb1b02076c905f31adb12731bc4161177f565b6080820151526103747f210b5cc8e6a85d63b65b701b8fb5ad24ff9c41f923432de17fe4ebae04526a8c7f05c10ab17ea731b2b87fb890fa5b10bd3d6832917a616b807a9b640888ebc73161177f565b6080820151602001526103c67f29d4d14adcfe67a2ac690d6369db6b75e82d8ab3124bc4fa1dd145f41ca6949c7e4f6cd229373f1c1f735ccf49aef6a5c32025bc36c3328596dd0db7d87bef6761177f565b6080820151604001526104197f06d15382e8cabae9f98374a9fbdadd424f48e24da7e4c65bf710fd7d7d59a05a7f22e438ad5c51673879ce17073a3d2d29327a97dc3ce61c4f88540e00087695f661177f565b60808201516060015261046c7f274a668dfc485cf192d0086f214146d9e02b3040a5a586df344c53c16a87882b7f15f5bb7ad01f162b70fc77c8ea456d67d15a6ce98acbbfd521222810f8ec0a6661177f565b60808281015101526104be7f0ba53bf4fb0446927857e33978d02abf45948fc68f4091394ae0827a22cf1e477f0720d818751ce5b3f11c716e925f60df4679ea90bed516499bdec066f5ff108f61177f565b608082015160a001526105117f2e986ba2ea495e5ec6af532980b1dc567f1430bfa82f8de07c12fc097c0e04837f1555d189f6164e82d78de1b8313c2e923e616b3c8ed0e350c3b61c94516d0b5861177f565b608082015160c001526105647f0925959592604ca73c917f9b2e029aa2563c318ddcc5ca29c11badb7b880127b7f2b4a430fcb2fa7d6d67d6c358e01cf0524c7df7e1e56442f65b39bc1a105236761177f565b608082015160e001526105b77f28f2a0a95af79ba67e9dd1986bd3190199f661b710a693fc82fb395c126edcbd7f0db75db5de5192d1ba1c24710fc00da16fa8029ac7fe82d855674dcd6d090e0561177f565b6060820151526106077f143471a174dfcb2d9cb5ae621e519387bcc93c9dcfc011160b2f5c5f88e32cbe7f2a0194c0224c3d964223a96c4c99e015719bc879125aa0df3f0715d154e71a3161177f565b60608201516020015261065a7f1423fa82e00ba22c280181afb12c56eea541933eeb5ec39119b0365b6beab4b97f0efdcd3423a38f5e2ecf8c7e4fd46f13189f8fed392ad9d8d393e8ba568b06e461177f565b60a0820151526106aa7f0e9b5b12c1090d62224e64aa1696c009aa59a9c3eec458e781fae773e1f4eca57f1fe3df508c7e9750eb37d9cae5e7437ad11a21fa36530ff821b407b165a79a5561177f565b60a0820151602001526106fd7f25d1a714bd1e258f196e38d6b2826153382c2d04b870d0b7ec250296005129ae7f0883a121b41ca7beaa9de97ecf4417e62aa2eeb9434f24ddacbfed57cbf016a861177f565b60a0820151604001526107507f2f3ede68e854a6b3b14589851cf077a606e2aeb3205c43cc579b7abae39d8f587f178ccd4b1f78fd79ee248e376b6fc8297d5450900d1e15e8c03e3ed2c171ac8c61177f565b60a0820151606001526107a37f1f814e2d87c332e964eeef94ec695eef9d2caaac58b682a43da5107693b06f307f196d56fb01907e66af9303886fd95328d398e5b2b72906882a9d12c1718e2ee261177f565b60c08201526107f27f0ebe0de4a2f39df3b903da484c1641ffdffb77ff87ce4f9508c548659eb22d3c7f12a3209440242d5662729558f1017ed9dcc08fe49a99554dd45f5f15da5e4e0b61177f565b60e0820151526108427f1b7d54f8065ca63bed0bfbb9280a1011b886d07e0c0a26a66ecc96af68c53bf97f2c51121fff5b8f58c302f03c74e0cb176ae5a1d1730dec4696eb9cce3fe284ca61177f565b60e0820151602001526108957f0138733c5faa9db6d4b8df9748081e38405999e511fb22d40f77cf3aef293c447f269bee1c1ac28053238f7fe789f1ea2e481742d6d16ae78ed81e87c254af076561177f565b60e0820151604001526108e87f1b1be7279d59445065a95f01f16686adfa798ec4f1e6845ffcec9b837e88372e7f057c90cb96d8259238ed86b05f629efd55f472a721efeeb56926e979433e6c0e61177f565b60e08201516060015261093b7f2f85df2d6249ccbcc11b91727333cc800459de6ee274f29c657c8d56f6f015637f088e1df178c47116a69c3c8f6d0c5feb530e2a72493694a623b1cceb7d44a76c61177f565b61010082015261094b6005611732565b6101208201515261095c6007611732565b61012082015160200152610970600a611732565b61012082015160026020020181905250610a3260405180604001604052807f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81525060405180604001604052807f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b81526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa8152506117aa565b610140820151526040805180820182527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c181527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b060208281019190915282518084019093527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe483527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e5590830152610ae8916117aa565b6101408201516020015290565b610afd61406f565b600260005b6004811015610b805784602001518160048110610b2157610b216154e5565b6020020151835183600d8110610b3957610b396154e5565b602002015260808501518160048110610b5457610b546154e5565b6020020151836020015183600d8110610b6f57610b6f6154e5565b602002015260019182019101610b02565b50606085015151825182600d8110610b9a57610b9a6154e5565b602002015260c084015160006020020151826020015182600d8110610bc157610bc16154e5565b602002015260010160005b610bd860016004615543565b811015610c54578560a001518160048110610bf557610bf56154e5565b6020020151835183600d8110610c0d57610c0d6154e5565b602002015260e08501518160038110610c2857610c286154e5565b6020020151836020015183600d8110610c4357610c436154e5565b602002015260019182019101610bcc565b5060408481015190830151526020840151610c7160016004615543565b60048110610c8157610c816154e5565b6020908102919091015160408401518201526101008501516060840180519190915260a0808701515191519092015260e08601515190840151600090610cd7906040805160208101909152600081529051815290565b905060015b6004811015610d2a57610cff828960e001518360048110610281576102816154e5565b6102408701819052610d129084906117b2565b60a0860151610d22908390611645565b600101610cdc565b508351829084600d8110610d4057610d406154e5565b6020020181905250856101e00151846020015184600d8110610d6457610d646154e5565b602002015260c087015184516001949094019384600d8110610d8857610d886154e5565b6020020181905250856102200151846020015184600d8110610dac57610dac6154e5565b602002015261010087015184516001949094019384600d8110610dd157610dd16154e5565b6020020181905250856102400151846020015184600d8110610df557610df56154e5565b602002015250610160850151604084810180518201929092526101a0870151606080870180519093019190915261018088015183518201526101c0880151825190910152905160809081019290925261020090950151945101939093529392505050565b602081015151600003610e6b57600080fd5b610e756001611732565b608082018051919091526020808301805160408051808501825260008082529251815294518401949094529051835192830190935281529051815260025b6009811015610f02576020830151610ecc908390611645565b6040805160208101909152600081528251815283608001518260098110610ef557610ef56154e5565b6020020152600101610eb3565b505050565b610f0f6140a9565b602c8214610f1c57600080fd5b8367ffffffffffffffff811115610f3557610f35614788565b604051908082528060200260200182016040528015610f5e578160200160208202803683370190505b50815260005b84811015610fae57858582818110610f7e57610f7e6154e5565b9050602002013582600001518281518110610f9b57610f9b6154e5565b6020908102919091010152600101610f64565b506000805b600481101561102857610fff858584818110610fd157610fd16154e5565b905060200201358686610fe48660010190565b818110610ff357610ff36154e5565b905060200201356117c1565b83602001518260048110611015576110156154e5565b6020020152600282019150600101610fb3565b5061105184848381811061103e5761103e6154e5565b905060200201358585610fe48560010190565b604083015260020161106e84848381811061103e5761103e6154e5565b61016083015260020161108c84848381811061103e5761103e6154e5565b61018083015260020160005b60048110156110df576110b6858584818110610fd157610fd16154e5565b836060015182600481106110cc576110cc6154e5565b6020020152600282019150600101611098565b5060005b60048110156111345761110d858584818110611101576111016154e5565b90506020020135611732565b83608001518260048110611123576111236154e5565b6020020152600191820191016110e3565b5060005b600181101561117d57611156858584818110611101576111016154e5565b8360a00151826001811061116c5761116c6154e5565b602002015260019182019101611138565b5060005b60018110156111c65761119f858584818110611101576111016154e5565b8360c0015182600181106111b5576111b56154e5565b602002015260019182019101611181565b5060005b600381101561120f576111e8858584818110611101576111016154e5565b8360e0015182600381106111fe576111fe6154e5565b6020020152600191820191016111ca565b50611225848483818110611101576111016154e5565b610100830152600101611243848483818110611101576111016154e5565b6101a0830152600101611261848483818110611101576111016154e5565b6101c083015260010161127f848483818110611101576111016154e5565b6101e083015260010161129d848483818110611101576111016154e5565b6102008301526001016112bb848483818110611101576111016154e5565b6102208301526001016112d9848483818110611101576111016154e5565b6102408301526001016112f7848483818110611101576111016154e5565b610120830152600101611315848483818110611101576111016154e5565b61014083015260010161133384848381811061103e5761103e6154e5565b61026083015260020161135184848381811061103e5761103e6154e5565b61028083015250949350505050565b60008061136d8484611a37565b905061137a8385836127a8565b151560000361138d57600091505061163f565b60608401516000906113c690825b6020020151604080518082019091526000808252602080830191825283518352929092015190915290565b84516101808401519192506000916113dd91612ab3565b604080516020808201835260008083528451835283518085019094528084529083015291925060015b6004811015611450576114288960600151826004811061139b5761139b6154e5565b91506114348284612b44565b61143e85836117b2565b6114488385611645565b600101611406565b505050506000611461858785610af5565b8051839052610120870151602082015152905061147f858785612b4f565b815160209081019190915261014087015181830180519092015281515190515160006114ab6001611732565b90506114ca604051806040016040528060008152602001600081525090565b60015b600d811015611553576101408801516114e7908490611645565b61150183876000015183600d8110610281576102816154e5565b915061150d85836117b2565b856020015181600d8110611523576115236154e5565b6020020151610220890181905261153a9084611645565b61022088015161154b9085906116c7565b6001016114cd565b50610140870151611565908390611645565b6000611582838760400151600060068110610281576102816154e5565b6060870151519091506115958185611645565b60015b600681101561161e576101408a01516115b2908690611645565b6115cc8589604001518360068110610281576102816154e5565b93506115d883856117b2565b876060015181600681106115ee576115ee6154e5565b60200201516102208b018190526116059086611645565b6102208a01516116169083906116c7565b600101611598565b506116338b61014001518d8b89868a87612fa1565b99505050505050505050505b92915050565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001815183510990915250565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181516116be907f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001615543565b83510890915250565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001815183510890915250565b6040805180820190915260008082526020820152825115801561171a575082602001516001145b1561172757600060208401525b61163f83838361313c565b6040805160208101909152600081527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001821061176d57600080fd5b50604080516020810190915290815290565b60408051808201909152600080825260208201525b5060408051808201909152918252602082015290565b6117946142b7565b6117bd82828461317e565b5050565b6040805180820190915260008082526020820152821580156117e1575081155b1561180257604051806040016040528084815260200183815250905061163f565b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478310611890576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f7820617869732069736e27742076616c6964000000000000000000000000000060448201526064015b60405180910390fd5b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd478210611919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f7920617869732069736e27742076616c696400000000000000000000000000006044820152606401611887565b60007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47838409905060007f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785860990507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4785820990507f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47600382089050808214611a1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6973206e6f74206f6e20637572766500000000000000000000000000000000006044820152606401611887565b50506040805180820190915292835250602082015290565b611a3f6142d7565b60408051606081018252600080825260208201819052918101829052905b8360200151811015611aa157611a9985600001518281518110611a8257611a826154e5565b60200260200101518361320e90919063ffffffff16565b600101611a5d565b5060005b6004811015611beb57611be385602001518260048110611ac757611ac76154e5565b602002015183908051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b0181529284018552825192880192909220909a528451835180880198909852998701989098529185019790975283850195909552855180840390940184529190930190935280519101209052565b600101611aa5565b50611bf5816132f1565b60a08301526101608401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b01815292840185528251928801929092208b528551845180890199909952908801999099529286019790975284860191909152805180850390950185529290940190915281519101209052611d1b816132f1565b6040830152611d29816132f1565b6060830152604084810151805183516020808601805186516000818501819052602480830187905260448084019490945260648084018990528a518085038201815260849485018c528051908801208c5285518b517c0100000000000000000000000000000000000000000000000000000000818a018190528185019a909a5280870191909152808201999099528a51808a03820181529884018b52885198870198909820808652988601518b518b51808901949094528383018190528386019a909a528289018190528a518084038a0181529284018b528251928701929092208b5284518a5180880198909852908701989098529185019690965283850152855180840390940184529190930190935280519101209052611e4a816132f1565b60c0830152611e58816132f1565b60e08301526101808401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a01949094528383018190528387019b909b52828a0181905284518084038b01815292840185528251928801929092208b528551845180890199909952908801999099529286019790975284860191909152805180850390950185529290940190915281519101209052611f7e816132f1565b602083015260005b6004811015611fb057611fa885606001518260048110611ac757611ac76154e5565b600101611f86565b50611fba816132f1565b610180830152610120840151518151602080840180516040805160008186015260248082018790526044808301949094526064808301899052835180840382018152608493840185528051908801208a52855184517c0100000000000000000000000000000000000000000000000000000000818a015292830198909852938101969096528583019690965280518086039092018252939094019092528251920191909120905260005b60048110156121325761212a85608001518260048110612086576120866154e5565b6020908102919091015151845185830180516040805160008188015260248082018690526044808301949094526064808301889052835180840382018152608493840185528051908a01208c52855184517c0100000000000000000000000000000000000000000000000000000000818c01529283019790975293810195909552848301959095528051808503909201825292909301909152815191909201209052565b600101612064565b5060005b6001811015612160576121588560a001518260018110612086576120866154e5565b600101612136565b5060005b600181101561218e576121868560c001518260018110612086576120866154e5565b600101612164565b5060005b60038110156121bc576121b48560e001518260038110612086576120866154e5565b600101612192565b506101808201516040805160208101825260008152915182526101a084018290528401516121ea9190611645565b61010084015151815160208084018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208b52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b038201815299840185528951998801999099208087526101e08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102208e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102408e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101a08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101c08e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526102008e0151518b518651808b0186905280850182905280890193909352828c0182905286518084038d01815292860187528251928a01929092208c5287518651808b018c90528085019390935282880152818b015284518082038b01815290840185528051908801208087526101408e0151518b518651808b019590955284840181905284880192909252838b0181905285518085038c01815293850186528351938901939093208b5286518551808a019a909a5291890152938701939093528587019290925280518086039096018652930190925282519201919091209052612599816132f1565b6101408301526102608401518051825160208085018051604080516000818601819052602480830188905260448084019590955260648084018a9052845180850382018152608494850186528051908901208c52865185517c0100000000000000000000000000000000000000000000000000000000818b018190528185019b909b52808801919091528082019a909a528451808b03820181529984018552895199880199909920808752998701518b518551808a018590528084018290528088019c909c528b8b018290528551808d038c0181529b850186528b519b89019b909b208c5286518551808a018b90528084019c909c528b8701528a8a01528351808b038a01815299830184528951998701999099208086526102808e015180518c518651808b01869052808e0182905280890194909452838c0182905286518085038d01815293860187528351938a01939093208d5287518651808b018c9052808e019490945283880152828b015284518083038b0181529184018552815191880191909120808752908701518b518551808a0194909452838c0181905283870192909252828a0181905284518084038b01815292840185528251928801929092208b52855184518089019990995299880152928601979097528486019190915280518085039095018552929094019091528151910120905261279b816132f1565b6101608301525092915050565b600080846020015167ffffffffffffffff8111156127c8576127c8614788565b6040519080825280602002602001820160405280156127f1578160200160208202803683370190505b50905060005b81518110156128265780828281518110612813576128136154e5565b60209081029190910101526001016127f7565b50600085602001511161283857600080fd5b60006128446000611732565b905060005b86602001518110156128c25761286e81886000015189604001518861018001516133e1565b610220860152855180516128a99161289d9184908110612890576128906154e5565b6020026020010151611732565b61022087015190611645565b6102208501516128ba9083906116c7565b600101612849565b5060c08501516128db9060005b60200201518290611645565b610140850151604080516020810190915260008152905181526128fe81836116c7565b61290785610e59565b608085015160009061291a90600461017f565b90506129348761010001518261164590919063ffffffff16565b61294060016004615543565b60031461294c57600080fd5b60408051602081019091526000815260005b60038110156129e0576129808960e00151826003811061017f5761017f6154e5565b915061299988604001518361164590919063ffffffff16565b6129be896080015182600481106129b2576129b26154e5565b602002015183906116c7565b60608801516129ce9083906116c7565b6129d88383611645565b60010161295e565b5060808801516129f190600361017f565b9050612a0a8760600151826116c790919063ffffffff16565b612a148282611645565b612a1e8383611671565b6000612a338a6000015189610180015161348f565b6080890151909150612a469060056128cf565b612a508482611671565b6000612a5d8b8b8b613515565b9050612a6985826116c7565b6101208a0151604080516020810190915260008152905181528b516101808b0151612a9e91612a9791613765565b8290611645565b945194519094149a9950505050505050505050565b604080516020808201835260008252825160c0810184528181528082018290529283015283516060830152608082018390527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000160a083015290612b1461448b565b600060208260c08560055afa905080612b2c57600080fd5b50604080516020810190915290518152949350505050565b6117bd82828461313c565b6040805180820190915260008082526020820152612b6e60008061177f565b90506000612b9d8460800151600060048110612b8c57612b8c6154e5565b602002015160808701516000610281565b9050612ba982826117b2565b6080840151612bc5906001602002015160808701516001610281565b9050612bd182826117b2565b6080840151612bed906002602002015160808701516002610281565b9050612bf982826117b2565b6080840151612c15906003602002015160808701516003610281565b9050612c2182826117b2565b6080840151600090612c33908261017f565b6080860151909150612c469060016128cf565b6080860151612c589082906004610281565b9150612c6483836117b2565b6080850151612c7490600061017f565b6080860151909150612c879060026128cf565b6080860151612c999082906005610281565b9150612ca583836117b2565b608086015160c00151612cb99084906117b2565b60a0850151516080870151612cd091906007610281565b9150612cdc83836117b2565b60c085015151612ced908490612b44565b6000612cfa878787610141565b9050612d0684826117b2565b612d1260016004615543565b600314612d1e57600080fd5b6000612d2a6001611732565b90506000612d48876080015160046009811061017f5761017f6154e5565b905060005b6004811015612e105761018088015160408051602081019091526000815290518152945080600003612d8857612d838584611645565b612db9565b6101208a0151612db990612d9d600184615543565b60038110612dad57612dad6154e5565b60200201518690611645565b6040880151612dc9908690611645565b6060880151612dd99086906116c7565b612dfe89608001518260048110612df257612df26154e5565b602002015186906116c7565b612e088286611645565b600101612d4d565b506040880151612e2090826116f3565b9450612e2c86866117b2565b6080870151612e3c90600461017f565b9050612e5587604001518261164590919063ffffffff16565b610100880151612e66908290611645565b60005b612e7560016004615543565b811015612ee957612e958960e00151826003811061017f5761017f6154e5565b9450612eae88604001518661164590919063ffffffff16565b6060880151612ebe9086906116c7565b612ed789608001518260048110612df257612df26154e5565b612ee18286611645565b600101612e69565b5060a0890151612efc9082906003610281565b9450612f088686613794565b612f2260008a600001518b604001518a61018001516133e1565b6101e0880181905251600003612f3757600080fd5b506101e0860151604080516020810190915260008152905181526080870151612f619060056128cf565b6040880151612f7090826116f3565b9450612f7c86866117b2565b6000612f88898961379f565b9050612f9487826117b2565b5050505050509392505050565b60408051808201909152600080825260208083018281528751845290870151905290612fdb87610160015186612b4490919063ffffffff16565b612fe581866117b2565b60408051602081019091526000815283518152610160880151613009908290611645565b61301381866116c7565b600061304b82613045604080518082018252600080825260209182015281518083019092526001825260029082015290565b906116f3565b90506130578382613794565b6101808901516102608b015161306c916116f3565b9050600061308f8a6101a001516040805160208101909152600081529051815290565b90506130a98a61016001518261164590919063ffffffff16565b6102808b01516000906130bc90836116f3565b90506130c883826117b2565b6130d285846117b2565b60006130f18c61016001518e61028001516116f390919063ffffffff16565b905061310b8d6102600151826117b290919063ffffffff16565b61311481613a6d565b8d5160208f015161312788838584613abf565b98505050505050505050979650505050505050565b6131446144a9565b835181526020840151816001602002015282518160026020020152600060408360608460075afa90508061317757600080fd5b5050505050565b815115801561318f57506020820151155b156131a7578251815260209283015192019190915250565b82511580156131b857506020830151155b156131cd578151815260209182015191015250565b6131d56144c7565b8351815260208085015181830152835160408301528301518160035b6020020152600060408360808460065afa90508061317757600080fd5b815160208084015160405160009281019290925260248201839052604482015260648101839052608401604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152918152815160209283012085528482015190517c01000000000000000000000000000000000000000000000000000000009281019290925260248201839052604482015260648101839052608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020918201209301929092525050565b604080516020810190915260008152815160208084015160408086015190517c0200000000000000000000000000000000000000000000000000000000938101939093526024830193909352604482015260e09190911b7fffffffff000000000000000000000000000000000000000000000000000000001660648201526000906068016040516020818303038152906040528051906020012090506001836040018181516133a09190615556565b63ffffffff1690525060408051602081019091527f1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91909116815292915050565b6040805160208101909152600081528385106133fc57600080fd5b60006134086001611732565b905060006134168588612ab3565b90506134228487612ab3565b925061342e8383611671565b825160000361343c57600080fd5b6134468382611645565b604080516020810190915260008152845181526134638183611671565b61346f612a9788611732565b61347881613bbf565b90506134848482611645565b505050949350505050565b60408051602081019091526000815260006134aa6001611732565b905060006134b785611732565b604080516020810190915260008152855181529091506134d78184611671565b6134e18183611645565b6134ea81613bbf565b90506134f68587612ab3565b93506135028484611671565b61350c8482611645565b50505092915050565b604080516020810190915260008152604080516020810190915260008152600061353f6001611732565b905061355f8460c001516040805160208101909152600081529051815290565b610100850181905261357190826116c7565b61010084015160408051602081019091526000815290518152610120850181905260e08501516135a19190611645565b6101a08501516040805160208101909152600081529051815291506135d38460c001518361164590919063ffffffff16565b6101208401516135e49083906116c7565b6101c08501516135f5908390611645565b60808401516136059060066101ca565b60006136266001886000015161361b9190615543565b604089015190612ab3565b90506136478561018001516040805160208101909152600081529051815290565b6101c086018190526136599082611671565b6101c085015161366a908490611645565b61367484846116c7565b61368e6000886000015189604001518861018001516133e1565b6101e0860181905260408051602081019091526000815290518152608086015160e001519093506136c0908490611645565b6136ca8484611671565b60006136ec600189600001516136e09190615543565b61012088015190612ab3565b9050613714600189600001516137029190615543565b895160408b01516101808a01516133e1565b610200870181905260408051602081019091526000815290518152935061373b8482611645565b60808601516101000151613750908590611645565b61375a8585611671565b505050509392505050565b60408051602081019091526000815261377e8284612ab3565b905061163f61378d6001611732565b8290611671565b6117bd828284613c10565b604080518082019091526000808252602082015260006137bf6000611732565b90506137d76040518060200160405280600081525090565b60408051602080820183526000918290526101c0880151835191820190935290815290518152608085015161380d9060066128cf565b6101c085015161381e908290611645565b61016086015160009061383190836116f3565b905061383d85826117b2565b61020087015160408051602081019091526000815290518152915061386f8660c001518361164590919063ffffffff16565b6101e08701516138809083906116c7565b6101208601516138919083906116c7565b60408051602081019091526000815260006138ac6001611732565b90506138c46040518060200160405280600081525090565b60005b6138d360016004615543565b811015613921576138f38b60800151826004811061017f5761017f6154e5565b91506138ff8284611645565b61390984836116c7565b60a08a0151613919908490611645565b6001016138c7565b506102408a01516040805160208101909152600081529051815295506139478683611645565b61395183876116c7565b6102208a0151613962908490611645565b60e08901516139729084906116c7565b61397c8584611645565b61010089015161398d908690611645565b6040805160208101909152600081528751815295506139ac8686611671565b60808901518695506139bf906006612dad565b6101c08901516139d0908690611645565b6101e08901516040805160208101909152600081529051815260808a0151909650613a049060075b60200201518790611645565b613a0e85876116c7565b6102008901516040805160208101909152600081529051815260808a0151909650613a3a9060086139f8565b613a4485876116c7565b6101808a0151613a5490866116f3565b9350613a6088856117b2565b5050505050505092915050565b8060200151600003613a8857805115613a8557600080fd5b50565b6020810151613ab7907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b602090910152565b60408051600280825260608201909252600091829190816020015b6040805180820190915260008082526020820152815260200190600190039081613ada5750506040805160028082526060820190925291925060009190602082015b613b246142b7565b815260200190600190039081613b1c5790505090508682600081518110613b4d57613b4d6154e5565b60200260200101819052508482600181518110613b6c57613b6c6154e5565b60200260200101819052508581600081518110613b8b57613b8b6154e5565b60200260200101819052508381600181518110613baa57613baa6154e5565b60200260200101819052506101368282613cde565b6040805160208101909152600081528151600003613bdc57600080fd5b61163f82613c0b60027f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001615543565b612ab3565b8151158015613c2157506020820151155b15613c39578251815260209283015192019190915250565b8251158015613c4a57506020830151155b15613c8c57815181526020820151613c82907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b6020909101525050565b613c946144c7565b835181526020808501518183015283516040830152830151613cd6907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47615543565b8160036131f1565b60008151835114613cee57600080fd5b82516000613cfd826006615573565b905060008167ffffffffffffffff811115613d1a57613d1a614788565b604051908082528060200260200182016040528015613d43578160200160208202803683370190505b50905060005b83811015613f7457868181518110613d6357613d636154e5565b60200260200101516000015182826006613d7d9190615573565b613d8890600061558a565b81518110613d9857613d986154e5565b602002602001018181525050868181518110613db657613db66154e5565b60200260200101516020015182826006613dd09190615573565b613ddb90600161558a565b81518110613deb57613deb6154e5565b602002602001018181525050858181518110613e0957613e096154e5565b6020908102919091010151515182613e22836006615573565b613e2d90600261558a565b81518110613e3d57613e3d6154e5565b602002602001018181525050858181518110613e5b57613e5b6154e5565b60209081029190910181015151015182613e76836006615573565b613e8190600361558a565b81518110613e9157613e916154e5565b602002602001018181525050858181518110613eaf57613eaf6154e5565b602002602001015160200151600060028110613ecd57613ecd6154e5565b602002015182613ede836006615573565b613ee990600461558a565b81518110613ef957613ef96154e5565b602002602001018181525050858181518110613f1757613f176154e5565b602002602001015160200151600160028110613f3557613f356154e5565b602002015182613f46836006615573565b613f5190600561558a565b81518110613f6157613f616154e5565b6020908102919091010152600101613d49565b50613f7d61448b565b6000602082602086026020860160085afa905080613f9a57600080fd5b505115159695505050505050565b6040518061016001604052806000815260200160008152602001613fd86040518060200160405280600081525090565b8152602001613fe56144e5565b8152602001613ff261451e565b8152602001613fff61454a565b8152602001614021604051806040016040528060008152602001600081525090565b815260200161402e61454a565b8152602001614050604051806040016040528060008152602001600081525090565b815260200161405d614573565b815260200161406a6145a7565b905290565b60405180608001604052806140826145d4565b815260200161408f614600565b815260200161409c614623565b815260200161406a61464d565b604051806102a00160405280606081526020016140c461454a565b81526020016140e6604051806040016040528060008152602001600081525090565b81526020016140f361454a565b815260200161410061466e565b8152604080518082018252600060208083018281528352808501929092528251808401845291820190815281529082015260600161413c614573565b81526020016141576040518060200160405280600081525090565b81526020016141726040518060200160405280600081525090565b815260200161418d6040518060200160405280600081525090565b81526020016141af604051806040016040528060008152602001600081525090565b81526020016141d1604051806040016040528060008152602001600081525090565b81526020016141ec6040518060200160405280600081525090565b81526020016142076040518060200160405280600081525090565b81526020016142226040518060200160405280600081525090565b815260200161423d6040518060200160405280600081525090565b81526020016142586040518060200160405280600081525090565b81526020016142736040518060200160405280600081525090565b8152602001614295604051806040016040528060008152602001600081525090565b815260200161406a604051806040016040528060008152602001600081525090565b60405180604001604052806142ca61468f565b815260200161406a61468f565b604080516102808101825260006102608201818152825282516020808201855282825280840191909152835180820185528281528385015283519081019093528252906060820190815260200161432c6146ad565b81526020016143476040518060200160405280600081525090565b81526020016143626040518060200160405280600081525090565b815260200161437d6040518060200160405280600081525090565b81526020016143986040518060200160405280600081525090565b81526020016143b36040518060200160405280600081525090565b81526020016143ce6040518060200160405280600081525090565b81526020016143e96040518060200160405280600081525090565b81526020016144046040518060200160405280600081525090565b815260200161441f6040518060200160405280600081525090565b815260200161443a6040518060200160405280600081525090565b81526020016144556040518060200160405280600081525090565b81526020016144706040518060200160405280600081525090565b81526020016142956040518060200160405280600081525090565b60405180602001604052806001906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b60405180608001604052806004906020820280368337509192915050565b60405180604001604052806002905b60408051808201909152600080825260208201528152602001906001900390816144f45790505090565b6040805161014081019091526000610100820181815261012083019190915281526007602082016144f4565b6040805160c0810190915260006080820181815260a083019190915281526003602082016144f4565b60405180606001604052806003905b6040805160208101909152600081528152602001906001900390816145825790505090565b60405180604001604052806002905b6145be6142b7565b8152602001906001900390816145b65790505090565b604080516101e0810190915260006101a082018181526101c08301919091528152600c602082016144f4565b604080516101c0810190915260006101a082019081528152600c60208201614582565b604080516101008101909152600060c0820181815260e083019190915281526005602082016144f4565b6040805160e08101909152600060c082019081528152600560208201614582565b6040805160a081019091526000608082019081528152600360208201614582565b60405180604001604052806002906020820280368337509192915050565b604080516101408101909152600061012082019081528152600860208201614582565b60008083601f8401126146e257600080fd5b50813567ffffffffffffffff8111156146fa57600080fd5b6020830191508360208260051b850101111561471557600080fd5b9250929050565b6000806000806040858703121561473257600080fd5b843567ffffffffffffffff8082111561474a57600080fd5b614756888389016146d0565b9096509450602087013591508082111561476f57600080fd5b5061477c878288016146d0565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156147da576147da614788565b60405290565b6040516102a0810167ffffffffffffffff811182821017156147da576147da614788565b604051610260810167ffffffffffffffff811182821017156147da576147da614788565b604051610160810167ffffffffffffffff811182821017156147da576147da614788565b6040516080810167ffffffffffffffff811182821017156147da576147da614788565b60006020828403121561488157600080fd5b6040516020810181811067ffffffffffffffff821117156148a4576148a4614788565b6040529135825250919050565b6000604082840312156148c357600080fd5b6148cb6147b7565b9050813581526020820135602082015292915050565b600082601f8301126148f257600080fd5b6148fa6147b7565b80608084018581111561490c57600080fd5b845b818110156149305761492087826148b1565b845260209093019260400161490e565b509095945050505050565b600082601f83011261494c57600080fd5b60408051610100810181811067ffffffffffffffff8211171561497157614971614788565b82528061020085018681111561498657600080fd5b855b818110156149a95761499a88826148b1565b83526020909201918401614988565b50919695505050505050565b600082601f8301126149c657600080fd5b6149ce61484c565b806101008401858111156149e157600080fd5b845b81811015614930576149f587826148b1565b84526020909301926040016149e3565b600082601f830112614a1657600080fd5b6040516060810181811067ffffffffffffffff82111715614a3957614a39614788565b604052806060840185811115614a4e57600080fd5b845b81811015614a7057614a62878261486f565b835260209283019201614a50565b509195945050505050565b600082601f830112614a8c57600080fd5b614a946147b7565b806040840185811115614aa657600080fd5b845b81811015614930578035845260209384019301614aa8565b600082601f830112614ad157600080fd5b614ad96147b7565b80610100840185811115614aec57600080fd5b845b818110156149305760808188031215614b075760008081fd5b614b0f6147b7565b614b198883614a7b565b8152614b288860408401614a7b565b6020828101919091529085529390930192608001614aee565b600082601f830112614b5257600080fd5b8135602067ffffffffffffffff80831115614b6f57614b6f614788565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715614bb257614bb2614788565b604052938452858101830193838101925087851115614bd057600080fd5b83870191505b8482101561013657813583529183019190830190614bd6565b600082601f830112614c0057600080fd5b614c0861484c565b806080840185811115614c1a57600080fd5b845b8181101561493057614c2e878261486f565b845260209384019301614c1c565b600082601f830112614c4d57600080fd5b604051602080820182811067ffffffffffffffff82111715614c7157614c71614788565b6040528184820186811115614c8557600080fd5b855b81811015614ca657614c99888261486f565b8352918301918301614c87565b50929695505050505050565b60006105a08284031215614cc557600080fd5b614ccd6147e0565b9050813567ffffffffffffffff811115614ce657600080fd5b614cf284828501614b41565b825250614d0283602084016149b5565b6020820152610120614d16848285016148b1565b6040830152610160614d2a858286016149b5565b6060840152610260614d3e86828701614bef565b6080850152614d51866102e08701614c3c565b60a0850152614d64866103008701614c3c565b60c0850152614d77866103208701614a05565b60e0850152614d8a86610380870161486f565b610100850152614d9e866103a0870161486f565b83850152614db0866103c0870161486f565b610140850152614dc4866103e087016148b1565b82850152614dd68661042087016148b1565b610180850152614dea86610460870161486f565b6101a0850152614dfe86610480870161486f565b6101c0850152614e12866104a0870161486f565b6101e0850152614e26866104c0870161486f565b610200850152614e3a866104e0870161486f565b610220850152614e4e86610500870161486f565b610240850152614e628661052087016148b1565b81850152505050614e778361056084016148b1565b61028082015292915050565b600082601f830112614e9457600080fd5b60405161012080820182811067ffffffffffffffff82111715614eb957614eb9614788565b60405283018185821115614ecc57600080fd5b845b82811015614a7057614ee0878261486f565b825260209182019101614ece565b60006103808284031215614f0157600080fd5b614f09614804565b9050614f15838361486f565b8152614f24836020840161486f565b6020820152614f36836040840161486f565b6040820152614f48836060840161486f565b6060820152614f5a8360808401614e83565b60808201526101a0614f6e8482850161486f565b60a08301526101c0614f828582860161486f565b60c08401526101e0614f968682870161486f565b60e0850152610200614faa8782880161486f565b610100860152610220614fbf8882890161486f565b610120870152610240614fd489828a0161486f565b610140880152614fe8896102608a0161486f565b610160880152614ffc896102808a0161486f565b610180880152615010896102a08a0161486f565b86880152615022896102c08a0161486f565b85880152615034896102e08a0161486f565b84880152615046896103008a0161486f565b83880152615058896103208a0161486f565b8288015261506a896103408a016148b1565b8188015250505050505092915050565b6000806000838503610a6081121561509157600080fd5b6106c0808212156150a157600080fd5b6150a9614828565b915085358252602086013560208301526150c6876040880161486f565b60408301526150d887606088016148e1565b60608301526150ea8760e0880161493b565b60808301526150fd876102e088016149b5565b60a0830152615110876103e088016148b1565b60c08301526151238761042088016149b5565b60e08301526151368761052088016148b1565b61010083015261514a876105608801614a05565b61012083015261515e876105c08801614ac0565b61014083015290935084013567ffffffffffffffff81111561517f57600080fd5b61518b86828701614cb2565b92505061519c856106e08601614eee565b90509250925092565b81518152602080830151908201526040810161163f565b8060005b60028110156151f4576151de84835180518252602090810151910152565b60409390930192602091909101906001016151c0565b50505050565b8060005b60088110156151f45761521c84835180518252602090810151910152565b60409390930192602091909101906001016151fe565b8060005b60048110156151f45761525484835180518252602090810151910152565b6040939093019260209190910190600101615236565b8060005b60038110156151f45781515184526020938401939091019060010161526e565b8060005b60028110156151f4578151845260209384019390910190600101615292565b8060005b60028110156151f45781516152cb85825161528e565b602090810151906152df604087018361528e565b608095909501949290920191506001016152b5565b60006106c0820190508251825260208301516020830152604083015161531d6040840182519052565b50606083015161533060608401826151bc565b50608083015161534360e08401826151fa565b5060a08301516153576102e0840182615232565b5060c083015180516103e08401526020015161040083015260e0830151615382610420840182615232565b506101008301518051610520840152602001516105408301526101208301516153af61056084018261526a565b506101408301516153c46105c08401826152b1565b5092915050565b8060005b60068110156151f4576153ed84835180518252602090810151910152565b60409390930192602091909101906001016153cf565b8060005b60068110156151f457815151845260209384019390910190600101615407565b81516107208201908260005b600d8110156154675761545182845180518252602090810151910152565b6020929092019160409190910190600101615433565b505050602080840151610340840160005b600d8110156154965782515182529183019190830190600101615478565b5050505060408301516154ad6104e08401826153cb565b5060608301516153c4610660840182615403565b600061038082840312156154d457600080fd5b6154de8383614eee565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561163f5761163f615514565b63ffffffff8181168382160190808211156153c4576153c4615514565b808202811582820484141761163f5761163f615514565b8082018082111561163f5761163f61551456fea2646970667358221220d2f17e9a0c25b77d7be3c1b56c33d3a035f0c73e0cf8dea1efb788c1f63f7bb364736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
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.