diff --git a/package-lock.json b/package-lock.json index 54ef9c9..37f35c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,10 @@ "node": ">=12" } }, + "node_modules/@distributedlab/spv-gateway-examples": { + "resolved": "src/examples", + "link": true + }, "node_modules/@distributedlab/v1-spv-gateway": { "resolved": "src/v1-contracts", "link": true @@ -9498,6 +9502,52 @@ "typescript": "^5.7.3" } }, + "src/examples": { + "name": "@distributedlab/spv-gateway-examples", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "5.2.0", + "@openzeppelin/contracts-upgradeable": "5.2.0", + "@solarity/solidity-lib": "3.2.0", + "solady": "0.1.23" + }, + "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.8", + "@nomicfoundation/hardhat-ethers": "^3.0.8", + "@nomicfoundation/hardhat-network-helpers": "^1.0.12", + "@nomicfoundation/hardhat-verify": "^2.0.13", + "@openzeppelin/merkle-tree": "^1.0.8", + "@solarity/hardhat-gobind": "^1.2.2", + "@solarity/hardhat-markup": "^1.0.10", + "@solarity/hardhat-migrate": "^3.1.0", + "@typechain/ethers-v6": "^0.5.1", + "@typechain/hardhat": "^9.1.0", + "@types/chai": "^4.3.20", + "@types/fs-extra": "^11.0.4", + "@types/mocha": "^10.0.10", + "@types/node": "^22.13.2", + "axios": "^1.9.0", + "chai": "^4.5.0", + "dotenv": "^16.4.7", + "ethers": "^6.13.5", + "fs-extra": "^11.3.0", + "hardhat": "^2.22.18", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-gas-reporter": "^2.2.2", + "husky": "^9.1.7", + "mocha": "^11.1.0", + "prettier": "^3.5.0", + "prettier-plugin-solidity": "^1.4.2", + "solhint": "^6.0.0", + "solhint-plugin-prettier": "^0.1.0", + "solidity-coverage": "^0.8.14", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typechain": "^8.3.2", + "typescript": "^5.7.3" + } + }, "src/v1-contracts": { "name": "@distributedlab/v1-spv-gateway", "version": "0.1.0", diff --git a/src/examples/.env.example b/src/examples/.env.example new file mode 100644 index 0000000..447b6cf --- /dev/null +++ b/src/examples/.env.example @@ -0,0 +1,12 @@ +# Deployer private key +PRIVATE_KEY=YOUR PRIVATE KEY + +# RPC Endpoints +INFURA_KEY=INFURA PROJECT ID + +# Additional keys +ETHERSCAN_KEY=ETHERSCAN API KEY +BSCSCAN_KEY=BSCSCAN API KEY +POLYGONSCAN_KEY=POLYGONSCAN API KEY +AVALANCHE_KEY=AVALANCHE API KEY +COINMARKETCAP_KEY=COINMARKETCAP API KEY diff --git a/src/examples/.gitignore b/src/examples/.gitignore new file mode 100644 index 0000000..a2a7104 --- /dev/null +++ b/src/examples/.gitignore @@ -0,0 +1,16 @@ +node_modules +.env +.DS_Store + +# Hardhat files +cache +artifacts +coverage.json +coverage +abi + +# Typechain generated files +generated-types + +# Hardhat migrate +.storage.json diff --git a/src/examples/.prettierignore b/src/examples/.prettierignore new file mode 100644 index 0000000..ec864a6 --- /dev/null +++ b/src/examples/.prettierignore @@ -0,0 +1,16 @@ +node_modules +.env +.DS_Store +package-lock.json + +# Hardhat files +cache +artifacts +coverage.json +coverage + +# Typechain generated files +generated-types + +# Hardhat migrate +.storage.json diff --git a/src/examples/.solcover.ts b/src/examples/.solcover.ts new file mode 100644 index 0000000..73410fb --- /dev/null +++ b/src/examples/.solcover.ts @@ -0,0 +1,4 @@ +module.exports = { + skipFiles: ["mock/", "interfaces/"], + configureYulOptimizer: true, +}; diff --git a/src/examples/.solhint.json b/src/examples/.solhint.json new file mode 100644 index 0000000..72ee597 --- /dev/null +++ b/src/examples/.solhint.json @@ -0,0 +1,17 @@ +{ + "extends": "solhint:recommended", + "plugins": ["prettier"], + "rules": { + "reentrancy": "error", + "prettier/prettier": "warn", + "modifier-name-mixedcase": "off", + "func-name-mixedcase": "off", + "no-empty-blocks": "warn", + "func-visibility": ["warn", { "ignoreConstructors": true }], + "max-states-count": "warn", + "not-rely-on-time": "off", + "var-name-mixedcase": "off", + "compiler-version": "off", + "use-natspec": "off" + } +} diff --git a/src/examples/.solhintignore b/src/examples/.solhintignore new file mode 100644 index 0000000..72ea452 --- /dev/null +++ b/src/examples/.solhintignore @@ -0,0 +1,2 @@ +./contracts/verifiers +# ./contracts/mock diff --git a/src/examples/LICENSE b/src/examples/LICENSE new file mode 100644 index 0000000..5c70f39 --- /dev/null +++ b/src/examples/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Distributed Lab + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/examples/README.md b/src/examples/README.md new file mode 100644 index 0000000..6a55b04 --- /dev/null +++ b/src/examples/README.md @@ -0,0 +1,49 @@ +# SPV Gateway Examples + +This directory contains example integrations with the SPV Gateway V2 contract, demonstrating how to leverage SPV (Simple Payment Verification) proofs for Bitcoin blockchain verification on Ethereum. + +## Overview + +The examples showcase practical use cases that utilize the SPV Gateway V2 contract to verify Bitcoin transactions and blocks on-chain. These contracts demonstrate key patterns and best practices for integrating SPV verification into Ethereum-based applications. + +## Examples + +### 1. BTC Whitelist + +A contract that manages a whitelist of Ethereum addresses based on Bitcoin transactions. Any user can join the whitelist by providing an SPV proof of a Bitcoin transaction containing at least one output with a value exceeding the contract's configured minimum threshold. + +**Key Features:** +- Whitelisting based on Bitcoin transaction verification +- Configurable minimum transaction amount +- Confirmation count requirements for security +- Paginated retrieval of whitelisted accounts + +**How it works:** +1. A user submits a Bitcoin transaction alongside an SPV proof +2. The contract verifies the transaction was included in the Bitcoin blockchain +3. If the transaction meets the whitelist rules (minimum amount), the user's Ethereum address is added to the whitelist +4. The contract enforces a minimum confirmation count before considering a transaction valid + +## Getting Started + +### Installation + +```bash +npm install +``` + +### Compiling + +```bash +npm run compile +``` + +### Testing + +```bash +npm run test +``` + +## Contract Architecture + +Each example contract integrates with `ISPVGatewayV2`, which provides the core functionality for verifying Bitcoin blockchain proofs. The examples implement specific business logic on top of this base verification layer. diff --git a/src/examples/contracts/BTCWhitelist.sol b/src/examples/contracts/BTCWhitelist.sol new file mode 100644 index 0000000..73ef905 --- /dev/null +++ b/src/examples/contracts/BTCWhitelist.sol @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import {TxParser} from "@solarity/solidity-lib/libs/bitcoin/TxParser.sol"; +import {Paginator} from "@solarity/solidity-lib/libs/arrays/Paginator.sol"; + +import {ISPVGatewayV2} from "./interfaces/ISPVGatewayV2.sol"; +import {IBTCWhitelist} from "./interfaces/IBTCWhitelist.sol"; + +contract BTCWhitelist is IBTCWhitelist, Ownable { + using EnumerableSet for EnumerableSet.AddressSet; + using Paginator for EnumerableSet.AddressSet; + using TxParser for bytes; + + ISPVGatewayV2 public immutable spvGatewayV2; + + uint256 internal _whitelistMinAmount; + uint256 internal _minConfirmationsCount; + + EnumerableSet.AddressSet internal _whitelist; + + modifier onlyWhitelistedAccount() { + _onlyWhitelistedAccount(msg.sender); + _; + } + + constructor( + address spvGatewayV2Addr_, + uint256 whitelistMinAmount_, + uint256 minConfirmationsCount_ + ) Ownable(msg.sender) { + spvGatewayV2 = ISPVGatewayV2(spvGatewayV2Addr_); + + _updateWhitelistMinAmount(whitelistMinAmount_); + _updateMinConfirmationsCount(minConfirmationsCount_); + } + + /// @inheritdoc IBTCWhitelist + function updateWhitelistMinAmount(uint256 whitelistMinAmount_) external onlyOwner { + _updateWhitelistMinAmount(whitelistMinAmount_); + } + + /// @inheritdoc IBTCWhitelist + function updateMinConfirmationsCount(uint256 minConfirmationsCount_) external onlyOwner { + _updateMinConfirmationsCount(minConfirmationsCount_); + } + + /// @inheritdoc IBTCWhitelist + function enterToWhitelist(bytes calldata txData_, bytes calldata txInclusionProof_) external { + require(!isAccountWhitelisted(msg.sender), AccountIsAlreadyWhitelisted(msg.sender)); + + bytes32 txId_ = txData_.calculateTxId(); + + _checkTxInclusionProof(txId_, txInclusionProof_); + + (TxParser.Transaction memory tx_, ) = txData_.parseTransaction(); + + require(_verifyWhitelistEntryRules(tx_), WhitelistEntryRulesAreNotMatched()); + + _whitelistAccount(msg.sender); + } + + /// @inheritdoc IBTCWhitelist + function getWhitelistMinAmount() external view returns (uint256) { + return _whitelistMinAmount; + } + + /// @inheritdoc IBTCWhitelist + function getMinConfirmationsCount() external view returns (uint256) { + return _minConfirmationsCount; + } + + /// @inheritdoc IBTCWhitelist + function getWhitelistedAccountsCount() external view returns (uint256) { + return _whitelist.length(); + } + + /// @inheritdoc IBTCWhitelist + function getAllWhitelistedAccounts() external view returns (address[] memory) { + return _whitelist.values(); + } + + /// @inheritdoc IBTCWhitelist + function getWhitelistedAccountsPart( + uint256 offset_, + uint256 limit_ + ) external view returns (address[] memory) { + return _whitelist.part(offset_, limit_); + } + + /// @inheritdoc IBTCWhitelist + function isAccountWhitelisted(address account_) public view virtual returns (bool) { + return _whitelist.contains(account_); + } + + function _updateWhitelistMinAmount(uint256 whitelistMinAmount_) internal { + _whitelistMinAmount = whitelistMinAmount_; + + emit WhitelistMinAmountUpdated(whitelistMinAmount_); + } + + function _updateMinConfirmationsCount(uint256 minConfirmationsCount_) internal { + _minConfirmationsCount = minConfirmationsCount_; + + emit MinConfirmationsCountUpdated(minConfirmationsCount_); + } + + function _whitelistAccount(address account_) internal virtual { + _whitelist.add(account_); + + emit AccountWhitelisted(account_); + } + + function _verifyWhitelistEntryRules( + TxParser.Transaction memory tx_ + ) internal view virtual returns (bool) { + TxParser.TransactionOutput[] memory outputs_ = tx_.outputs; + + for (uint256 i = 0; i < outputs_.length; i++) { + if (outputs_[i].value >= _whitelistMinAmount) { + return true; + } + } + + return false; + } + + function _checkTxInclusionProof( + bytes32 txId_, + bytes calldata txInclusionProof_ + ) internal view virtual { + ( + bytes memory blockHeaderRaw_, + uint256 txIndex_, + bytes32[] memory merkleProof_, + ISPVGatewayV2.HistoryBlockInclusionProofData memory blockProofData_ + ) = abi.decode( + txInclusionProof_, + (bytes, uint256, bytes32[], ISPVGatewayV2.HistoryBlockInclusionProofData) + ); + + require( + spvGatewayV2.checkTxInclusion( + merkleProof_, + blockHeaderRaw_, + txId_, + txIndex_, + blockProofData_ + ), + TxNotIncluded() + ); + _checkBlockConfirmations(uint64(blockProofData_.blockHeight)); + } + + function _checkBlockConfirmations(uint64 blockHeight_) internal view virtual { + uint64 currentMainchainHeight_ = spvGatewayV2.getMainchainHeight(); + + require( + blockHeight_ + _minConfirmationsCount <= currentMainchainHeight_, + MinConfirmationsCountNotReached(blockHeight_, currentMainchainHeight_) + ); + } + + function _onlyWhitelistedAccount(address account_) internal view { + require(isAccountWhitelisted(account_), NotAWhitelistedAccount(account_)); + } +} diff --git a/src/examples/contracts/interfaces/IBTCWhitelist.sol b/src/examples/contracts/interfaces/IBTCWhitelist.sol new file mode 100644 index 0000000..3491097 --- /dev/null +++ b/src/examples/contracts/interfaces/IBTCWhitelist.sol @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +/** + * @title IBTCWhitelist + * @notice Interface for the BTC Whitelist contract, which manages whitelisting of addresses on the Ethereum side using SPV proofs. + */ +interface IBTCWhitelist { + /** + * @notice Error thrown when an account is not whitelisted. + * @param account The address that is not whitelisted. + */ + error NotAWhitelistedAccount(address account); + /** + * @notice Error thrown when an account is already whitelisted. + * @param account The address that is already whitelisted. + */ + error AccountIsAlreadyWhitelisted(address account); + /** + * @notice Error thrown when the block has not reached the required number of confirmations. + * @param blockHeight The height of the block being verified. + * @param mainchainHeight The current height of the mainchain. + */ + error MinConfirmationsCountNotReached(uint64 blockHeight, uint64 mainchainHeight); + /** + * @notice Error thrown when the SPV proof is invalid. + */ + error InvalidSPVProof(); + /** + * @notice Error thrown when the transaction is not included in the proof. + */ + error TxNotIncluded(); + /** + * @notice Error thrown when the whitelist entry rules are not matched. + */ + error WhitelistEntryRulesAreNotMatched(); + + /** + * @notice Emitted when the whitelist minimum amount is updated. + * @param newMinAmount The new minimum amount required for whitelisting. + */ + event WhitelistMinAmountUpdated(uint256 newMinAmount); + /** + * @notice Emitted when the minimum confirmations count is updated. + * @param newMinConfirmationsCount The new minimum confirmations count required. + */ + event MinConfirmationsCountUpdated(uint256 newMinConfirmationsCount); + /** + * @notice Emitted when an account is successfully whitelisted. + * @param account The address that was whitelisted. + */ + event AccountWhitelisted(address account); + + /** + * @notice Updates the minimum amount required for whitelisting. + * @param whitelistMinAmount_ The new minimum amount in satoshis. + */ + function updateWhitelistMinAmount(uint256 whitelistMinAmount_) external; + + /** + * @notice Updates the minimum number of confirmations required for whitelisting. + * @param minConfirmationsCount_ The new minimum confirmations count. + */ + function updateMinConfirmationsCount(uint256 minConfirmationsCount_) external; + + /** + * @notice Enters a `msg.sender` address to the whitelist using an SPV proof and transaction inclusion proof. + * @param txData_ The raw transaction data. + * @param txInclusionProof_ The proof data for transaction inclusion in the mainchain. + */ + function enterToWhitelist(bytes calldata txData_, bytes calldata txInclusionProof_) external; + + /** + * @notice Returns the minimum amount required for whitelisting. + * @return The minimum whitelist amount in satoshis. + */ + function getWhitelistMinAmount() external view returns (uint256); + + /** + * @notice Returns the minimum number of confirmations required for whitelisting. + * @return The minimum confirmations count. + */ + function getMinConfirmationsCount() external view returns (uint256); + + /** + * @notice Returns the total number of whitelisted accounts. + * @return The count of whitelisted accounts. + */ + function getWhitelistedAccountsCount() external view returns (uint256); + + /** + * @notice Returns all whitelisted accounts. + * @return An array of all whitelisted addresses. + */ + function getAllWhitelistedAccounts() external view returns (address[] memory); + + /** + * @notice Returns a paginated list of whitelisted accounts. + * @param offset_ The starting index for pagination. + * @param limit_ The maximum number of accounts to return. + * @return An array of whitelisted addresses in the specified range. + */ + function getWhitelistedAccountsPart( + uint256 offset_, + uint256 limit_ + ) external view returns (address[] memory); + + /** + * @notice Checks if an account is whitelisted. + * @param account_ The address to check. + * @return True if the account is whitelisted, false otherwise. + */ + function isAccountWhitelisted(address account_) external view returns (bool); +} diff --git a/src/examples/contracts/interfaces/ISPVGatewayV2.sol b/src/examples/contracts/interfaces/ISPVGatewayV2.sol new file mode 100644 index 0000000..75d698b --- /dev/null +++ b/src/examples/contracts/interfaces/ISPVGatewayV2.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.28; + +/** + * @title ISPVGatewayV2 + * @notice Interface for the SPV Gateway V2 contract, which manages Bitcoin mainchain block and transaction inclusion proofs, + * SPV token rewards, and mainchain state updates. + */ +interface ISPVGatewayV2 { + /** + * @notice Data structure for block inclusion proof in history. + * @param level1MerkleProof Merkle proof for the first level of the blocks tree. + * @param level2MerkleProof Merkle proof for the second level of the blocks tree. + * @param blockHash Hash of the block being proved. + * @param blockHeight Height of the block in the Bitcoin blockchain. + */ + struct HistoryBlockInclusionProofData { + bytes32[] level1MerkleProof; + bytes32[] level2MerkleProof; + bytes32 blockHash; + uint256 blockHeight; + } + + /** + * @notice Returns the root of the blocks tree. + * @return The blocks tree root. + */ + function getBlocksTreeRoot() external view returns (bytes32); + + /** + * @notice Returns the current height of the mainchain. + * @return The mainchain height. + */ + function getMainchainHeight() external view returns (uint64); + + /** + * @notice Checks if a transaction is included in a block using the provided Merkle proof and block inclusion proof data. + * @param merkleProof_ The merkle proof for the transaction inclusion. + * @param blockHeaderRaw_ The raw block header data. + * @param txId_ The transaction ID to check for inclusion. + * @param txIndex_ The index of the transaction in the block. + * @param blockInclusionProofData_ The proof data for block inclusion in the mainchain. + * @return True if the transaction is included, false otherwise. + */ + function checkTxInclusion( + bytes32[] calldata merkleProof_, + bytes calldata blockHeaderRaw_, + bytes32 txId_, + uint256 txIndex_, + HistoryBlockInclusionProofData calldata blockInclusionProofData_ + ) external view returns (bool); + + /** + * @notice Checks if a block is included in the mainchain using the provided proof data. + * @param inclusionProofData_ The proof data for block inclusion in the mainchain. + * @return True if the block is included, false otherwise. + */ + function checkBlockInclusion( + HistoryBlockInclusionProofData calldata inclusionProofData_ + ) external view returns (bool); +} diff --git a/src/examples/hardhat.config.ts b/src/examples/hardhat.config.ts new file mode 100644 index 0000000..743911b --- /dev/null +++ b/src/examples/hardhat.config.ts @@ -0,0 +1,103 @@ +import "@nomicfoundation/hardhat-verify"; +import "@nomicfoundation/hardhat-ethers"; +import "@nomicfoundation/hardhat-chai-matchers"; + +import "@solarity/hardhat-migrate"; +import "@solarity/hardhat-gobind"; +import "@solarity/hardhat-markup"; + +import "@typechain/hardhat"; + +import "hardhat-contract-sizer"; +import "hardhat-gas-reporter"; + +import "solidity-coverage"; + +import "tsconfig-paths/register"; + +import { HardhatUserConfig } from "hardhat/config"; + +import * as dotenv from "dotenv"; +dotenv.config(); + +function privateKey() { + return process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : []; +} + +const config: HardhatUserConfig = { + networks: { + hardhat: { + initialDate: "1970-01-01T00:00:00Z", + }, + localhost: { + url: "http://127.0.0.1:8545", + gasMultiplier: 1.2, + }, + sepolia: { + url: `https://sepolia.infura.io/v3/${process.env.INFURA_KEY}`, + accounts: privateKey(), + gasMultiplier: 1.2, + }, + bscTest: { + url: `https://data-seed-prebsc-1-s1.binance.org:8545`, + accounts: privateKey(), + gasMultiplier: 1.2, + }, + ethereum: { + url: `https://mainnet.infura.io/v3/${process.env.INFURA_KEY}`, + accounts: privateKey(), + gasMultiplier: 1.2, + }, + base: { + url: `https://base-mainnet.infura.io/v3/${process.env.INFURA_KEY}`, + accounts: privateKey(), + gasMultiplier: 1.2, + }, + }, + solidity: { + version: "0.8.28", + settings: { + metadata: { + bytecodeHash: "none", + }, + optimizer: { + enabled: true, + runs: 1000000, + }, + evmVersion: "london", + }, + }, + etherscan: { + apiKey: `${process.env.ETHERSCAN_KEY}`, + }, + migrate: { + paths: { + pathToMigrations: "./deploy/", + }, + }, + mocha: { + timeout: 1000000, + }, + contractSizer: { + alphaSort: false, + disambiguatePaths: false, + runOnCompile: true, + strict: false, + }, + gasReporter: { + currency: "USD", + gasPrice: 50, + enabled: true, + coinmarketcap: `${process.env.COINMARKETCAP_KEY}`, + reportPureAndViewMethods: true, + }, + typechain: { + externalArtifacts: ["test/fixed-artifacts/**/*.json"], + outDir: "generated-types/ethers", + target: "ethers-v6", + alwaysGenerateOverloads: true, + discriminateTypes: true, + }, +}; + +export default config; diff --git a/src/examples/package.json b/src/examples/package.json new file mode 100644 index 0000000..07973a5 --- /dev/null +++ b/src/examples/package.json @@ -0,0 +1,78 @@ +{ + "name": "@distributedlab/spv-gateway-examples", + "version": "0.1.0", + "license": "MIT", + "author": "Distributed Lab", + "description": "SPV Gateway Examples", + "keywords": [ + "solidity", + "smart-contracts", + "bitcoin", + "spv-gateway" + ], + "files": [ + "**/*.sol", + "!mock/**/*" + ], + "scripts": { + "prepare": "husky", + "compile": "npx hardhat compile", + "coverage": "npx hardhat coverage --solcoverjs ./.solcover.ts", + "clean": "npx hardhat clean", + "test": "npx hardhat test", + "test-all": "npx hardhat migrate && npm run test", + "private-network": "npx hardhat node", + "private-network-fork": "npx hardhat node --fork https://mainnet.infura.io/v3/$(grep INFURA_KEY .env | cut -d '\"' -f2)", + "deploy-localhost": "npx hardhat migrate --network localhost", + "deploy-sepolia": "npx hardhat migrate --network sepolia --verify", + "generate-types": "TYPECHAIN_FORCE=true npx hardhat typechain && npx hardhat gobind", + "generate-docs": "npx hardhat markup", + "solhint-check": "solhint --noPoster \"./contracts/**/*.sol\"", + "lint-fix": "npm run lint-sol-fix && npm run lint-ts-fix && npm run lint-json-fix && npm run solhint-check", + "lint-json-fix": "prettier --write \"./**/*.json\"", + "lint-ts-fix": "prettier --write \"./**/*.ts\" --ignore-path .prettierignore", + "lint-sol-fix": "prettier --write \"contracts/**/*.sol\"", + "publish-to-npm": "npm run lint-fix && bash ./scripts/publish.sh --public" + }, + "dependencies": { + "@openzeppelin/contracts": "5.2.0", + "@openzeppelin/contracts-upgradeable": "5.2.0", + "@solarity/solidity-lib": "3.2.0", + "solady": "0.1.23" + }, + "devDependencies": { + "@nomicfoundation/hardhat-chai-matchers": "^2.0.8", + "@nomicfoundation/hardhat-ethers": "^3.0.8", + "@nomicfoundation/hardhat-network-helpers": "^1.0.12", + "@nomicfoundation/hardhat-verify": "^2.0.13", + "@openzeppelin/merkle-tree": "^1.0.8", + "@solarity/hardhat-gobind": "^1.2.2", + "@solarity/hardhat-markup": "^1.0.10", + "@solarity/hardhat-migrate": "^3.1.0", + "@typechain/ethers-v6": "^0.5.1", + "@typechain/hardhat": "^9.1.0", + "@types/chai": "^4.3.20", + "@types/fs-extra": "^11.0.4", + "@types/mocha": "^10.0.10", + "@types/node": "^22.13.2", + "axios": "^1.9.0", + "chai": "^4.5.0", + "dotenv": "^16.4.7", + "ethers": "^6.13.5", + "fs-extra": "^11.3.0", + "hardhat": "^2.22.18", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-gas-reporter": "^2.2.2", + "husky": "^9.1.7", + "mocha": "^11.1.0", + "prettier": "^3.5.0", + "prettier-plugin-solidity": "^1.4.2", + "solhint": "^6.0.0", + "solhint-plugin-prettier": "^0.1.0", + "solidity-coverage": "^0.8.14", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typechain": "^8.3.2", + "typescript": "^5.7.3" + } +} diff --git a/src/examples/scripts/index.ts b/src/examples/scripts/index.ts new file mode 100644 index 0000000..178cd64 --- /dev/null +++ b/src/examples/scripts/index.ts @@ -0,0 +1 @@ +export * from "./utils"; diff --git a/src/examples/scripts/utils/constants.ts b/src/examples/scripts/utils/constants.ts new file mode 100644 index 0000000..ef8f907 --- /dev/null +++ b/src/examples/scripts/utils/constants.ts @@ -0,0 +1,8 @@ +export const ETHER_ADDR = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + +export const SECONDS_IN_DAY = 86400; +export const SECONDS_IN_MONTH = SECONDS_IN_DAY * 30; + +export const DECIMAL = 10n ** 18n; +export const PRECISION = 10n ** 25n; +export const PERCENTAGE_100 = PRECISION * 100n; diff --git a/src/examples/scripts/utils/index.ts b/src/examples/scripts/utils/index.ts new file mode 100644 index 0000000..e8a6cf9 --- /dev/null +++ b/src/examples/scripts/utils/index.ts @@ -0,0 +1,2 @@ +export * from "./constants"; +export * from "./utils"; diff --git a/src/examples/scripts/utils/utils.ts b/src/examples/scripts/utils/utils.ts new file mode 100644 index 0000000..097bdc2 --- /dev/null +++ b/src/examples/scripts/utils/utils.ts @@ -0,0 +1,13 @@ +import { ethers } from "hardhat"; + +export function wei(value: string | number | bigint, decimal: number = 18): bigint { + if (typeof value == "number" || typeof value == "bigint") { + value = value.toString(); + } + + return ethers.parseUnits(value as string, decimal); +} + +export function fromWei(value: string | number | bigint, decimal: number = 18): string { + return (BigInt(value) / 10n ** BigInt(decimal)).toString(); +} diff --git a/src/examples/test/BTCWhitelist.test.ts b/src/examples/test/BTCWhitelist.test.ts new file mode 100644 index 0000000..b44c892 --- /dev/null +++ b/src/examples/test/BTCWhitelist.test.ts @@ -0,0 +1,266 @@ +import { expect } from "chai"; +import { ethers } from "hardhat"; + +import { + BlockHeaderData, + getBlockHeaderData, + getBlocksDataFilePath, + getHistoryProofDirPath, + getHistoryProofFromFile, + getHistoryProofPublicInputsFromFile, + MerkleRawProofParser, + Reverter, +} from "@test-helpers"; + +import { + BTCWhitelist, + SPVGatewayV2, + SPVGatewayV2__factory, + HistoryProofVerifier, + HistoryProofVerifier__factory, +} from "@ethers-v6"; +import { wei } from "@/scripts"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; + +describe("BTCWhitelist", () => { + const reverter = new Reverter(); + + const chunkSize: bigint = 1n; + const maxFrontierLength: bigint = 25n; + + const provedBlocksCount = 10n; + + const whitelistMinAmount = wei(30, 8); + const minConfirmationsCount = 5n; + + let OWNER: SignerWithAddress; + let FIRST: SignerWithAddress; + + let spvGatewayV2: SPVGatewayV2; + let btcWhitelist: BTCWhitelist; + + let historyProofVerifier: HistoryProofVerifier; + + let firstBlocksDataFilePath: string; + + before(async () => { + [OWNER, FIRST] = await ethers.getSigners(); + + const SPVGatewayV2Factory = new SPVGatewayV2__factory().connect(OWNER); + const HistoryProofVerifierFactory = new HistoryProofVerifier__factory().connect(OWNER); + + historyProofVerifier = await HistoryProofVerifierFactory.deploy(); + spvGatewayV2 = await SPVGatewayV2Factory.deploy(historyProofVerifier, chunkSize, maxFrontierLength); + + await spvGatewayV2.__SPVGatewayV2_init(); + + btcWhitelist = await ethers.deployContract("BTCWhitelist", [ + spvGatewayV2, + whitelistMinAmount, + minConfirmationsCount, + ]); + + firstBlocksDataFilePath = getBlocksDataFilePath("headers_1_30.json"); + + const historyProof10CDirPath = getHistoryProofDirPath(provedBlocksCount, false); + + const proof = getHistoryProofFromFile(historyProof10CDirPath); + const publicInputs = getHistoryProofPublicInputsFromFile(historyProof10CDirPath); + + await spvGatewayV2.updateMainchain({ + blocksCount: provedBlocksCount, + proof: proof, + publicInputs: publicInputs, + }); + + expect(await spvGatewayV2.getMainchainHeight()).to.be.eq(provedBlocksCount - 1n); + + await reverter.snapshot(); + }); + + afterEach(reverter.revert); + + describe("initialization", () => { + it("should set correct initial data", async () => { + expect(await btcWhitelist.spvGatewayV2()).to.be.eq(spvGatewayV2); + expect(await btcWhitelist.getWhitelistMinAmount()).to.be.eq(whitelistMinAmount); + expect(await btcWhitelist.getMinConfirmationsCount()).to.be.eq(minConfirmationsCount); + }); + }); + + describe("updateWhitelistMinAmount", () => { + it("should correctly update min amount to enter whitelist", async () => { + const newMinAmount = whitelistMinAmount * 2n; + + const tx = await btcWhitelist.updateWhitelistMinAmount(newMinAmount); + + await expect(tx).to.emit(btcWhitelist, "WhitelistMinAmountUpdated").withArgs(newMinAmount); + }); + + it("should get exception if not an owner try to call this function", async () => { + const newMinAmount = whitelistMinAmount * 2n; + + await expect(btcWhitelist.connect(FIRST).updateWhitelistMinAmount(newMinAmount)) + .to.be.revertedWithCustomError(btcWhitelist, "OwnableUnauthorizedAccount") + .withArgs(FIRST.address); + }); + }); + + describe("updateMinConfirmationsCount", () => { + it("should correctly update min amount to enter whitelist", async () => { + const newMinConfirmationsCount = 8n; + + const tx = await btcWhitelist.updateMinConfirmationsCount(newMinConfirmationsCount); + + await expect(tx).to.emit(btcWhitelist, "MinConfirmationsCountUpdated").withArgs(newMinConfirmationsCount); + }); + + it("should get exception if not an owner try to call this function", async () => { + const newMinConfirmationsCount = 8n; + + await expect(btcWhitelist.connect(FIRST).updateMinConfirmationsCount(newMinConfirmationsCount)) + .to.be.revertedWithCustomError(btcWhitelist, "OwnableUnauthorizedAccount") + .withArgs(FIRST.address); + }); + }); + + describe("enterToWhitelist", () => { + const blockHeight = 4; + const level2MerklePath = [ + "0xe32e10bf9f9f1bf1b57a958c51ed7a2a519eb8afcaf8530b24b414c64967819d", + "0x09dbdab95166b8d2e4ba0bb5939e716d62b1d1fdbccbc1cab85d75d90278702b", + "0xdc50af91c44dadd3f98cd581d18cb0e323e1643ea1bc43f76d2eb78713cd6006", + "0xcb73f4e3f81ce9fca9372b78e37d1be5c4cc7c974e261d7d0e3e444bc0daa479", + ]; + + // We will prove next tx - https://learnmeabitcoin.com/explorer/tx/df2b060fa2e5e9c8ed5eaf6a45c13753ec8c63282b2688322eba40cd98ea067a + const txid = "df2b060fa2e5e9c8ed5eaf6a45c13753ec8c63282b2688322eba40cd98ea067a"; + // To obtain the raw TX, we used the getrawtransaction RPC call with the txid + const rawTx = + "0x01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d011affffffff0100f2052a01000000434104184f32b212815c6e522e66686324030ff7e5bf08efb21f8b00614fb7690e19131dd31304c54f37baa40db231c918106bb9fd43373e37ae31a0befc6ecaefb867ac00000000"; + // To obtain the TX proof, we used the gettxoutproof RPC call with the txid and the block hash as parameters + const rawTxProof = + "010000004944469562ae1c2c74d9a535e00b6f3e40ffbad4f2fda3895501b582000000007a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf8cc16649ffff001d2bfee0a901000000017a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf0101"; + + let blockHeader: BlockHeaderData; + + beforeEach("setup", async () => { + blockHeader = getBlockHeaderData(firstBlocksDataFilePath, blockHeight); + }); + + it("should correctly enter to the whitelist", async () => { + const parser = new MerkleRawProofParser(txid, rawTxProof); + + const inclusionProofData = ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes", "uint256", "bytes32[]", "tuple(bytes32[],bytes32[],bytes32,uint256)"], + [ + blockHeader.rawHeader, + parser.getTxIndex(), + parser.getSiblings(), + [[], level2MerklePath, blockHeader.blockHash, blockHeight], + ], + ); + + const tx = await btcWhitelist.connect(FIRST).enterToWhitelist(rawTx, inclusionProofData); + + expect(await btcWhitelist.isAccountWhitelisted(FIRST)).to.be.true; + expect(await btcWhitelist.getWhitelistedAccountsCount()).to.be.eq(1n); + expect(await btcWhitelist.getAllWhitelistedAccounts()).to.be.deep.eq([FIRST.address]); + + await expect(tx).to.emit(btcWhitelist, "AccountWhitelisted").withArgs(FIRST.address); + }); + + it("should get exception if the min confirmation count not reached", async () => { + const newMinConfirmationsCount = 6n; + + await btcWhitelist.updateMinConfirmationsCount(newMinConfirmationsCount); + + expect(await btcWhitelist.getMinConfirmationsCount()).to.be.eq(newMinConfirmationsCount); + + const parser = new MerkleRawProofParser(txid, rawTxProof); + + const inclusionProofData = ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes", "uint256", "bytes32[]", "tuple(bytes32[],bytes32[],bytes32,uint256)"], + [ + blockHeader.rawHeader, + parser.getTxIndex(), + parser.getSiblings(), + [[], level2MerklePath, blockHeader.blockHash, blockHeight], + ], + ); + + await expect(btcWhitelist.connect(FIRST).enterToWhitelist(rawTx, inclusionProofData)) + .to.be.revertedWithCustomError(btcWhitelist, "MinConfirmationsCountNotReached") + .withArgs(blockHeight, await spvGatewayV2.getMainchainHeight()); + }); + + it("should get exception if the account is already whitelisted", async () => { + const parser = new MerkleRawProofParser(txid, rawTxProof); + + const inclusionProofData = ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes", "uint256", "bytes32[]", "tuple(bytes32[],bytes32[],bytes32,uint256)"], + [ + blockHeader.rawHeader, + parser.getTxIndex(), + parser.getSiblings(), + [[], level2MerklePath, blockHeader.blockHash, blockHeight], + ], + ); + + await btcWhitelist.connect(FIRST).enterToWhitelist(rawTx, inclusionProofData); + + await expect(btcWhitelist.connect(FIRST).enterToWhitelist(rawTx, inclusionProofData)) + .to.be.revertedWithCustomError(btcWhitelist, "AccountIsAlreadyWhitelisted") + .withArgs(FIRST.address); + }); + + it("should get exception if the whitelist entry rules are not matched", async () => { + const newWhitelistMinAmount = wei(51, 8); + + await btcWhitelist.updateWhitelistMinAmount(newWhitelistMinAmount); + + expect(await btcWhitelist.getWhitelistMinAmount()).to.be.eq(newWhitelistMinAmount); + + const parser = new MerkleRawProofParser(txid, rawTxProof); + + const inclusionProofData = ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes", "uint256", "bytes32[]", "tuple(bytes32[],bytes32[],bytes32,uint256)"], + [ + blockHeader.rawHeader, + parser.getTxIndex(), + parser.getSiblings(), + [[], level2MerklePath, blockHeader.blockHash, blockHeight], + ], + ); + + await expect( + btcWhitelist.connect(FIRST).enterToWhitelist(rawTx, inclusionProofData), + ).to.be.revertedWithCustomError(btcWhitelist, "WhitelistEntryRulesAreNotMatched"); + }); + + it("should get exception if the tx is not included in the passed block", async () => { + // TX from the block at height 7 + const newTxId = "8aa673bc752f2851fd645d6a0a92917e967083007d9c1684f9423b100540673f"; + const newRawTX = + "0x01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d012bffffffff0100f2052a01000000434104a59e64c774923d003fae7491b2a7f75d6b7aa3f35606a8ff1cf06cd3317d16a41aa16928b1df1f631f31f28c7da35d4edad3603adb2338c4d4dd268f31530555ac00000000"; + const newRawTxProof = + "010000008d778fdc15a2d3fb76b7122a3b5582bea4f21f5a0c693537e7a03130000000003f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68af1c66649ffff001d39a59c8601000000013f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68a0101"; + + const parser = new MerkleRawProofParser(newTxId, newRawTxProof); + + const inclusionProofData = ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes", "uint256", "bytes32[]", "tuple(bytes32[],bytes32[],bytes32,uint256)"], + [ + blockHeader.rawHeader, + parser.getTxIndex(), + parser.getSiblings(), + [[], level2MerklePath, blockHeader.blockHash, blockHeight], + ], + ); + + await expect( + btcWhitelist.connect(FIRST).enterToWhitelist(newRawTX, inclusionProofData), + ).to.be.revertedWithCustomError(btcWhitelist, "TxNotIncluded"); + }); + }); +}); diff --git a/src/examples/test/data/headers_1_30.json b/src/examples/test/data/headers_1_30.json new file mode 100644 index 0000000..a5bc054 --- /dev/null +++ b/src/examples/test/data/headers_1_30.json @@ -0,0 +1,662 @@ +[ + { + "height": 1, + "blockHash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", + "rawHeader": "010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe680e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e36299", + "parsedBlockHeader": { + "hash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", + "confirmations": 894626, + "height": 1, + "version": 1, + "versionHex": "00000001", + "merkleroot": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098", + "time": 1231469665, + "mediantime": 1231469665, + "nonce": 2573394689, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000200020002", + "nTx": 1, + "previousblockhash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", + "nextblockhash": "000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd" + } + }, + { + "height": 2, + "blockHash": "000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", + "rawHeader": "010000004860eb18bf1b1620e37e9490fc8a427514416fd75159ab86688e9a8300000000d5fdcc541e25de1c7a5addedf24858b8bb665c9f36ef744ee42c316022c90f9bb0bc6649ffff001d08d2bd61", + "parsedBlockHeader": { + "hash": "000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", + "confirmations": 894625, + "height": 2, + "version": 1, + "versionHex": "00000001", + "merkleroot": "9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5", + "time": 1231469744, + "mediantime": 1231469665, + "nonce": 1639830024, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000300030003", + "nTx": 1, + "previousblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", + "nextblockhash": "0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449" + } + }, + { + "height": 3, + "blockHash": "0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449", + "rawHeader": "01000000bddd99ccfda39da1b108ce1a5d70038d0a967bacb68b6b63065f626a0000000044f672226090d85db9a9f2fbfe5f0f9609b387af7be5b7fbb7a1767c831c9e995dbe6649ffff001d05e0ed6d", + "parsedBlockHeader": { + "hash": "0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449", + "confirmations": 894624, + "height": 3, + "version": 1, + "versionHex": "00000001", + "merkleroot": "999e1c837c76a1b7fbb7e57baf87b309960f5ffefbf2a9b95dd890602272f644", + "time": 1231470173, + "mediantime": 1231469744, + "nonce": 1844305925, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000400040004", + "nTx": 1, + "previousblockhash": "000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd", + "nextblockhash": "000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485" + } + }, + { + "height": 4, + "blockHash": "000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485", + "rawHeader": "010000004944469562ae1c2c74d9a535e00b6f3e40ffbad4f2fda3895501b582000000007a06ea98cd40ba2e3288262b28638cec5337c1456aaf5eedc8e9e5a20f062bdf8cc16649ffff001d2bfee0a9", + "parsedBlockHeader": { + "hash": "000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485", + "confirmations": 894623, + "height": 4, + "version": 1, + "versionHex": "00000001", + "merkleroot": "df2b060fa2e5e9c8ed5eaf6a45c13753ec8c63282b2688322eba40cd98ea067a", + "time": 1231470988, + "mediantime": 1231469744, + "nonce": 2850094635, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000500050005", + "nTx": 1, + "previousblockhash": "0000000082b5015589a3fdf2d4baff403e6f0be035a5d9742c1cae6295464449", + "nextblockhash": "000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc" + } + }, + { + "height": 5, + "blockHash": "000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc", + "rawHeader": "0100000085144a84488ea88d221c8bd6c059da090e88f8a2c99690ee55dbba4e00000000e11c48fecdd9e72510ca84f023370c9a38bf91ac5cae88019bee94d24528526344c36649ffff001d1d03e477", + "parsedBlockHeader": { + "hash": "000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc", + "confirmations": 894622, + "height": 5, + "version": 1, + "versionHex": "00000001", + "merkleroot": "63522845d294ee9b0188ae5cac91bf389a0c3723f084ca1025e7d9cdfe481ce1", + "time": 1231471428, + "mediantime": 1231470173, + "nonce": 2011431709, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000600060006", + "nTx": 1, + "previousblockhash": "000000004ebadb55ee9096c9a2f8880e09da59c0d68b1c228da88e48844a1485", + "nextblockhash": "000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d" + } + }, + { + "height": 6, + "blockHash": "000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d", + "rawHeader": "01000000fc33f596f822a0a1951ffdbf2a897b095636ad871707bf5d3162729b00000000379dfb96a5ea8c81700ea4ac6b97ae9a9312b2d4301a29580e924ee6761a2520adc46649ffff001d189c4c97", + "parsedBlockHeader": { + "hash": "000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d", + "confirmations": 894621, + "height": 6, + "version": 1, + "versionHex": "00000001", + "merkleroot": "20251a76e64e920e58291a30d4b212939aae976baca40e70818ceaa596fb9d37", + "time": 1231471789, + "mediantime": 1231470173, + "nonce": 2538380312, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000700070007", + "nTx": 1, + "previousblockhash": "000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc", + "nextblockhash": "0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444" + } + }, + { + "height": 7, + "blockHash": "0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444", + "rawHeader": "010000008d778fdc15a2d3fb76b7122a3b5582bea4f21f5a0c693537e7a03130000000003f674005103b42f984169c7d008370967e91920a6a5d64fd51282f75bc73a68af1c66649ffff001d39a59c86", + "parsedBlockHeader": { + "hash": "0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444", + "confirmations": 894620, + "height": 7, + "version": 1, + "versionHex": "00000001", + "merkleroot": "8aa673bc752f2851fd645d6a0a92917e967083007d9c1684f9423b100540673f", + "time": 1231472369, + "mediantime": 1231470988, + "nonce": 2258412857, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000800080008", + "nTx": 1, + "previousblockhash": "000000003031a0e73735690c5a1ff2a4be82553b2a12b776fbd3a215dc8f778d", + "nextblockhash": "00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6" + } + }, + { + "height": 8, + "blockHash": "00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6", + "rawHeader": "010000004494c8cf4154bdcc0720cd4a59d9c9b285e4b146d45f061d2b6c967100000000e3855ed886605b6d4a99d5fa2ef2e9b0b164e63df3c4136bebf2d0dac0f1f7a667c86649ffff001d1c4b5666", + "parsedBlockHeader": { + "hash": "00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6", + "confirmations": 894619, + "height": 8, + "version": 1, + "versionHex": "00000001", + "merkleroot": "a6f7f1c0dad0f2eb6b13c4f33de664b1b0e9f22efad5994a6d5b6086d85e85e3", + "time": 1231472743, + "mediantime": 1231470988, + "nonce": 1716931356, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000900090009", + "nTx": 1, + "previousblockhash": "0000000071966c2b1d065fd446b1e485b2c9d9594acd2007ccbd5441cfc89444", + "nextblockhash": "000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805" + } + }, + { + "height": 9, + "blockHash": "000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805", + "rawHeader": "01000000c60ddef1b7618ca2348a46e868afc26e3efc68226c78aa47f8488c4000000000c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd37047fca6649ffff001d28404f53", + "parsedBlockHeader": { + "hash": "000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805", + "confirmations": 894618, + "height": 9, + "version": 1, + "versionHex": "00000001", + "merkleroot": "0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9", + "time": 1231473279, + "mediantime": 1231471428, + "nonce": 1397702696, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000a000a000a", + "nTx": 1, + "previousblockhash": "00000000408c48f847aa786c2268fc3e6ec2af68e8468a34a28c61b7f1de0dc6", + "nextblockhash": "000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9" + } + }, + { + "height": 10, + "blockHash": "000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9", + "rawHeader": "010000000508085c47cc849eb80ea905cc7800a3be674ffc57263cf210c59d8d00000000112ba175a1e04b14ba9e7ea5f76ab640affeef5ec98173ac9799a852fa39add320cd6649ffff001d1e2de565", + "parsedBlockHeader": { + "hash": "000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9", + "confirmations": 894617, + "height": 10, + "version": 1, + "versionHex": "00000001", + "merkleroot": "d3ad39fa52a89997ac7381c95eeffeaf40b66af7a57e9eba144be0a175a12b11", + "time": 1231473952, + "mediantime": 1231471428, + "nonce": 1709518110, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000b000b000b", + "nTx": 1, + "previousblockhash": "000000008d9dc510f23c2657fc4f67bea30078cc05a90eb89e84cc475c080805", + "nextblockhash": "0000000097be56d606cdd9c54b04d4747e957d3608abe69198c661f2add73073" + } + }, + { + "height": 11, + "blockHash": "0000000097be56d606cdd9c54b04d4747e957d3608abe69198c661f2add73073", + "rawHeader": "01000000e915d9a478e3adf3186c07c61a22228b10fd87df343c92782ecc052c000000006e06373c80de397406dc3d19c90d71d230058d28293614ea58d6a57f8f5d32f8b8ce6649ffff001d173807f8", + "parsedBlockHeader": { + "hash": "0000000097be56d606cdd9c54b04d4747e957d3608abe69198c661f2add73073", + "confirmations": 894616, + "height": 11, + "version": 1, + "versionHex": "00000001", + "merkleroot": "f8325d8f7fa5d658ea143629288d0530d2710dc9193ddc067439de803c37066e", + "time": 1231474360, + "mediantime": 1231471789, + "nonce": 4161222679, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000c000c000c", + "nTx": 1, + "previousblockhash": "000000002c05cc2e78923c34df87fd108b22221ac6076c18f3ade378a4d915e9", + "nextblockhash": "0000000027c2488e2510d1acf4369787784fa20ee084c258b58d9fbd43802b5e" + } + }, + { + "height": 12, + "blockHash": "0000000027c2488e2510d1acf4369787784fa20ee084c258b58d9fbd43802b5e", + "rawHeader": "010000007330d7adf261c69891e6ab08367d957e74d4044bc5d9cd06d656be9700000000b8c8754fabb0ffeb04ca263a1368c39c059ca0d4af3151b876f27e197ebb963bc8d06649ffff001d3f596a0c", + "parsedBlockHeader": { + "hash": "0000000027c2488e2510d1acf4369787784fa20ee084c258b58d9fbd43802b5e", + "confirmations": 894615, + "height": 12, + "version": 1, + "versionHex": "00000001", + "merkleroot": "3b96bb7e197ef276b85131afd4a09c059cc368133a26ca04ebffb0ab4f75c8b8", + "time": 1231474888, + "mediantime": 1231472369, + "nonce": 208296255, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000d000d000d", + "nTx": 1, + "previousblockhash": "0000000097be56d606cdd9c54b04d4747e957d3608abe69198c661f2add73073", + "nextblockhash": "000000005c51de2031a895adc145ee2242e919a01c6d61fb222a54a54b4d3089" + } + }, + { + "height": 13, + "blockHash": "000000005c51de2031a895adc145ee2242e919a01c6d61fb222a54a54b4d3089", + "rawHeader": "010000005e2b8043bd9f8db558c284e00ea24f78879736f4acd110258e48c2270000000071b22998921efddf90c75ac3151cacee8f8084d3e9cb64332427ec04c7d562994cd16649ffff001d37d1ae86", + "parsedBlockHeader": { + "hash": "000000005c51de2031a895adc145ee2242e919a01c6d61fb222a54a54b4d3089", + "confirmations": 894614, + "height": 13, + "version": 1, + "versionHex": "00000001", + "merkleroot": "9962d5c704ec27243364cbe9d384808feeac1c15c35ac790dffd1e929829b271", + "time": 1231475020, + "mediantime": 1231472743, + "nonce": 2259603767, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000e000e000e", + "nTx": 1, + "previousblockhash": "0000000027c2488e2510d1acf4369787784fa20ee084c258b58d9fbd43802b5e", + "nextblockhash": "0000000080f17a0c5a67f663a9bc9969eb37e81666d9321125f0e293656f8a37" + } + }, + { + "height": 14, + "blockHash": "0000000080f17a0c5a67f663a9bc9969eb37e81666d9321125f0e293656f8a37", + "rawHeader": "0100000089304d4ba5542a22fb616d1ca019e94222ee45c1ad95a83120de515c00000000560164b8bad7675061aa0f43ced718884bdd8528cae07f24c58bb69592d8afe185d36649ffff001d29cbad24", + "parsedBlockHeader": { + "hash": "0000000080f17a0c5a67f663a9bc9969eb37e81666d9321125f0e293656f8a37", + "confirmations": 894613, + "height": 14, + "version": 1, + "versionHex": "00000001", + "merkleroot": "e1afd89295b68bc5247fe0ca2885dd4b8818d7ce430faa615067d7bab8640156", + "time": 1231475589, + "mediantime": 1231473279, + "nonce": 615369513, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000000f000f000f", + "nTx": 1, + "previousblockhash": "000000005c51de2031a895adc145ee2242e919a01c6d61fb222a54a54b4d3089", + "nextblockhash": "00000000b3322c8c3ef7d2cf6da009a776e6a99ee65ec5a32f3f345712238473" + } + }, + { + "height": 15, + "blockHash": "00000000b3322c8c3ef7d2cf6da009a776e6a99ee65ec5a32f3f345712238473", + "rawHeader": "01000000378a6f6593e2f0251132d96616e837eb6999bca963f6675a0c7af180000000000d080260d107d269ccba9247cfc64c952f1d13514b49e9f1230b3a197a8b7450fa276849ffff001d38d8fb98", + "parsedBlockHeader": { + "hash": "00000000b3322c8c3ef7d2cf6da009a776e6a99ee65ec5a32f3f345712238473", + "confirmations": 894612, + "height": 15, + "version": 1, + "versionHex": "00000001", + "merkleroot": "50748b7a193a0b23f1e9494b51131d2f954cc6cf4792bacc69d207d16002080d", + "time": 1231562746, + "mediantime": 1231473952, + "nonce": 2566641720, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001000100010", + "nTx": 1, + "previousblockhash": "0000000080f17a0c5a67f663a9bc9969eb37e81666d9321125f0e293656f8a37", + "nextblockhash": "00000000174a25bb399b009cc8deff1c4b3ea84df7e93affaaf60dc3416cc4f5" + } + }, + { + "height": 16, + "blockHash": "00000000174a25bb399b009cc8deff1c4b3ea84df7e93affaaf60dc3416cc4f5", + "rawHeader": "010000007384231257343f2fa3c55ee69ea9e676a709a06dcfd2f73e8c2c32b300000000442ee91b2b999fb15d61f6a88ecf2988e9c8ed48f002476128e670d3dac19fe706286849ffff001d049e12d6", + "parsedBlockHeader": { + "hash": "00000000174a25bb399b009cc8deff1c4b3ea84df7e93affaaf60dc3416cc4f5", + "confirmations": 894611, + "height": 16, + "version": 1, + "versionHex": "00000001", + "merkleroot": "e79fc1dad370e628614702f048edc8e98829cf8ea8f6615db19f992b1be92e44", + "time": 1231562758, + "mediantime": 1231474360, + "nonce": 3591544324, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001100110011", + "nTx": 1, + "previousblockhash": "00000000b3322c8c3ef7d2cf6da009a776e6a99ee65ec5a32f3f345712238473", + "nextblockhash": "000000003ff1d0d70147acfbef5d6a87460ff5bcfce807c2d5b6f0a66bfdf809" + } + }, + { + "height": 17, + "blockHash": "000000003ff1d0d70147acfbef5d6a87460ff5bcfce807c2d5b6f0a66bfdf809", + "rawHeader": "01000000f5c46c41c30df6aaff3ae9f74da83e4b1cffdec89c009b39bb254a17000000005d6291c35a88fd9a3aef5843124400936fbf2c9166314addcaf5678e55b7e0a30f2c6849ffff001d07608493", + "parsedBlockHeader": { + "hash": "000000003ff1d0d70147acfbef5d6a87460ff5bcfce807c2d5b6f0a66bfdf809", + "confirmations": 894610, + "height": 17, + "version": 1, + "versionHex": "00000001", + "merkleroot": "a3e0b7558e67f5cadd4a3166912cbf6f930044124358ef3a9afd885ac391625d", + "time": 1231563791, + "mediantime": 1231474888, + "nonce": 2474926087, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001200120012", + "nTx": 1, + "previousblockhash": "00000000174a25bb399b009cc8deff1c4b3ea84df7e93affaaf60dc3416cc4f5", + "nextblockhash": "000000008693e98cf893e4c85a446b410bb4dfa129bd1be582c09ed3f0261116" + } + }, + { + "height": 18, + "blockHash": "000000008693e98cf893e4c85a446b410bb4dfa129bd1be582c09ed3f0261116", + "rawHeader": "0100000009f8fd6ba6f0b6d5c207e8fcbcf50f46876a5deffbac4701d7d0f13f0000000023ca63b851cadfd7099ae68eb22147d09394adb72a78e86b69c42deb6df225f92e2e6849ffff001d323741f2", + "parsedBlockHeader": { + "hash": "000000008693e98cf893e4c85a446b410bb4dfa129bd1be582c09ed3f0261116", + "confirmations": 894609, + "height": 18, + "version": 1, + "versionHex": "00000001", + "merkleroot": "f925f26deb2dc4696be8782ab7ad9493d04721b28ee69a09d7dfca51b863ca23", + "time": 1231564334, + "mediantime": 1231475020, + "nonce": 4064360242, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001300130013", + "nTx": 1, + "previousblockhash": "000000003ff1d0d70147acfbef5d6a87460ff5bcfce807c2d5b6f0a66bfdf809", + "nextblockhash": "00000000841cb802ca97cf20fb9470480cae9e5daa5d06b4a18ae2d5dd7f186f" + } + }, + { + "height": 19, + "blockHash": "00000000841cb802ca97cf20fb9470480cae9e5daa5d06b4a18ae2d5dd7f186f", + "rawHeader": "01000000161126f0d39ec082e51bbd29a1dfb40b416b445ac8e493f88ce993860000000030e2a3e32abf1663a854efbef1b233c67c8cdcef5656fe3b4f28e52112469e9bae306849ffff001d16d1b42d", + "parsedBlockHeader": { + "hash": "00000000841cb802ca97cf20fb9470480cae9e5daa5d06b4a18ae2d5dd7f186f", + "confirmations": 894608, + "height": 19, + "version": 1, + "versionHex": "00000001", + "merkleroot": "9b9e461221e5284f3bfe5656efdc8c7cc633b2f1beef54a86316bf2ae3a3e230", + "time": 1231564974, + "mediantime": 1231475589, + "nonce": 766824726, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001400140014", + "nTx": 1, + "previousblockhash": "000000008693e98cf893e4c85a446b410bb4dfa129bd1be582c09ed3f0261116", + "nextblockhash": "0000000067a97a2a37b8f190a17f0221e9c3f4fa824ddffdc2e205eae834c8d7" + } + }, + { + "height": 20, + "blockHash": "0000000067a97a2a37b8f190a17f0221e9c3f4fa824ddffdc2e205eae834c8d7", + "rawHeader": "010000006f187fddd5e28aa1b4065daa5d9eae0c487094fb20cf97ca02b81c84000000005b7b25b51797f83192f9fd2c3871bfb27570a7d6b56d3a50760613d1a2fc1aeeab346849ffff001d36d95071", + "parsedBlockHeader": { + "hash": "0000000067a97a2a37b8f190a17f0221e9c3f4fa824ddffdc2e205eae834c8d7", + "confirmations": 894607, + "height": 20, + "version": 1, + "versionHex": "00000001", + "merkleroot": "ee1afca2d1130676503a6db5d6a77075b2bf71382cfdf99231f89717b5257b5b", + "time": 1231565995, + "mediantime": 1231562746, + "nonce": 1901123894, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001500150015", + "nTx": 1, + "previousblockhash": "00000000841cb802ca97cf20fb9470480cae9e5daa5d06b4a18ae2d5dd7f186f", + "nextblockhash": "000000006f016342d1275be946166cff975c8b27542de70a7113ac6d1ef3294f" + } + }, + { + "height": 21, + "blockHash": "000000006f016342d1275be946166cff975c8b27542de70a7113ac6d1ef3294f", + "rawHeader": "01000000d7c834e8ea05e2c2fddf4d82faf4c3e921027fa190f1b8372a7aa96700000000b41092b870cc096070ff3212c207c0881e3a2abafc1b92507941b4ef705917e0d9366849ffff001d2bd021d6", + "parsedBlockHeader": { + "hash": "000000006f016342d1275be946166cff975c8b27542de70a7113ac6d1ef3294f", + "confirmations": 894606, + "height": 21, + "version": 1, + "versionHex": "00000001", + "merkleroot": "e0175970efb4417950921bfcba2a3a1e88c007c21232ff706009cc70b89210b4", + "time": 1231566553, + "mediantime": 1231562758, + "nonce": 3592540203, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001600160016", + "nTx": 1, + "previousblockhash": "0000000067a97a2a37b8f190a17f0221e9c3f4fa824ddffdc2e205eae834c8d7", + "nextblockhash": "0000000098b58d427a10c860335a21c1a9a7639e96c3d6f1a03d8c8c885b5e3b" + } + }, + { + "height": 22, + "blockHash": "0000000098b58d427a10c860335a21c1a9a7639e96c3d6f1a03d8c8c885b5e3b", + "rawHeader": "010000004f29f31e6dac13710ae72d54278b5c97ff6c1646e95b27d14263016f000000004349d6a4e94f05a736ac830754e76dfdf7f140c331f316d1a278517e1daf2e9e6b3a6849ffff001d28140f62", + "parsedBlockHeader": { + "hash": "0000000098b58d427a10c860335a21c1a9a7639e96c3d6f1a03d8c8c885b5e3b", + "confirmations": 894605, + "height": 22, + "version": 1, + "versionHex": "00000001", + "merkleroot": "9e2eaf1d7e5178a2d116f331c340f1f7fd6de7540783ac36a7054fe9a4d64943", + "time": 1231567467, + "mediantime": 1231563791, + "nonce": 1645155368, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001700170017", + "nTx": 1, + "previousblockhash": "000000006f016342d1275be946166cff975c8b27542de70a7113ac6d1ef3294f", + "nextblockhash": "000000000cd339982e556dfffa9de94744a4135c53eeef15b7bcc9bdeb9c2182" + } + }, + { + "height": 23, + "blockHash": "000000000cd339982e556dfffa9de94744a4135c53eeef15b7bcc9bdeb9c2182", + "rawHeader": "010000003b5e5b888c8c3da0f1d6c3969e63a7a9c1215a3360c8107a428db598000000008c4cc1b42c9dab1973890ecdfdee032079ed39892ad53a6546844d237634cfe1fb3a6849ffff001d255ab455", + "parsedBlockHeader": { + "hash": "000000000cd339982e556dfffa9de94744a4135c53eeef15b7bcc9bdeb9c2182", + "confirmations": 894604, + "height": 23, + "version": 1, + "versionHex": "00000001", + "merkleroot": "e1cf3476234d8446653ad52a8939ed792003eefdcd0e897319ab9d2cb4c14c8c", + "time": 1231567611, + "mediantime": 1231564334, + "nonce": 1437882917, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001800180018", + "nTx": 1, + "previousblockhash": "0000000098b58d427a10c860335a21c1a9a7639e96c3d6f1a03d8c8c885b5e3b", + "nextblockhash": "00000000fc051fbbce89a487e811a5d4319d209785ea4f4b27fc83770d1e415f" + } + }, + { + "height": 24, + "blockHash": "00000000fc051fbbce89a487e811a5d4319d209785ea4f4b27fc83770d1e415f", + "rawHeader": "0100000082219cebbdc9bcb715efee535c13a44447e99dfaff6d552e9839d30c000000003e75f63c634ed5fb3d8e21de5fe143cfa63c8018fce0fa26cbc628378b9bc343953d6849ffff001d27ba00b1", + "parsedBlockHeader": { + "hash": "00000000fc051fbbce89a487e811a5d4319d209785ea4f4b27fc83770d1e415f", + "confirmations": 894603, + "height": 24, + "version": 1, + "versionHex": "00000001", + "merkleroot": "43c39b8b3728c6cb26fae0fc18803ca6cf43e15fde218e3dfbd54e633cf6753e", + "time": 1231568277, + "mediantime": 1231564974, + "nonce": 2969614887, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001900190019", + "nTx": 1, + "previousblockhash": "000000000cd339982e556dfffa9de94744a4135c53eeef15b7bcc9bdeb9c2182", + "nextblockhash": "000000008e35a1d59ea1be8d76683662f47fd13c62a9e347ad5845a26f762026" + } + }, + { + "height": 25, + "blockHash": "000000008e35a1d59ea1be8d76683662f47fd13c62a9e347ad5845a26f762026", + "rawHeader": "010000005f411e0d7783fc274b4fea8597209d31d4a511e887a489cebb1f05fc00000000be2123ad48038313b8b726a51cb080bb5a8b81c4166401493b017d2d33520f9b063f6849ffff001d2337f131", + "parsedBlockHeader": { + "hash": "000000008e35a1d59ea1be8d76683662f47fd13c62a9e347ad5845a26f762026", + "confirmations": 894602, + "height": 25, + "version": 1, + "versionHex": "00000001", + "merkleroot": "9b0f52332d7d013b49016416c4818b5abb80b01ca526b7b813830348ad2321be", + "time": 1231568646, + "mediantime": 1231565995, + "nonce": 837891875, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001a001a001a", + "nTx": 1, + "previousblockhash": "00000000fc051fbbce89a487e811a5d4319d209785ea4f4b27fc83770d1e415f", + "nextblockhash": "0000000041438e52d25bccab8798a92cabafdaad69a071d3d2a41718faf01098" + } + }, + { + "height": 26, + "blockHash": "0000000041438e52d25bccab8798a92cabafdaad69a071d3d2a41718faf01098", + "rawHeader": "010000002620766fa24558ad47e3a9623cd17ff4623668768dbea19ed5a1358e00000000dc1490b5ba227b1adbb2513f74e0252e8fe68b6c7de74c1a22adb63b14e8c16712466849ffff001d344eb75c", + "parsedBlockHeader": { + "hash": "0000000041438e52d25bccab8798a92cabafdaad69a071d3d2a41718faf01098", + "confirmations": 894601, + "height": 26, + "version": 1, + "versionHex": "00000001", + "merkleroot": "67c1e8143bb6ad221a4ce77d6c8be68f2e25e0743f51b2db1a7b22bab59014dc", + "time": 1231570450, + "mediantime": 1231566553, + "nonce": 1555516980, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001b001b001b", + "nTx": 1, + "previousblockhash": "000000008e35a1d59ea1be8d76683662f47fd13c62a9e347ad5845a26f762026", + "nextblockhash": "0000000071350772f98f84babf35502b33d42ee8466d3dde0f376c4120352081" + } + }, + { + "height": 27, + "blockHash": "0000000071350772f98f84babf35502b33d42ee8466d3dde0f376c4120352081", + "rawHeader": "010000009810f0fa1817a4d2d371a069addaafab2ca99887abcc5bd2528e434100000000654f005a6e4b4b57b42343fb0e47f32079b4ebfe643c2ea4ea20e46c3af00c238d466849ffff001d364c8cb3", + "parsedBlockHeader": { + "hash": "0000000071350772f98f84babf35502b33d42ee8466d3dde0f376c4120352081", + "confirmations": 894600, + "height": 27, + "version": 1, + "versionHex": "00000001", + "merkleroot": "230cf03a6ce420eaa42e3c64feebb47920f3470efb4323b4574b4b6e5a004f65", + "time": 1231570573, + "mediantime": 1231567467, + "nonce": 3012316214, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001c001c001c", + "nTx": 1, + "previousblockhash": "0000000041438e52d25bccab8798a92cabafdaad69a071d3d2a41718faf01098", + "nextblockhash": "00000000bb0d9430d3d1bab474be5050342161efcca9f7e45b151bff9a700944" + } + }, + { + "height": 28, + "blockHash": "00000000bb0d9430d3d1bab474be5050342161efcca9f7e45b151bff9a700944", + "rawHeader": "0100000081203520416c370fde3d6d46e82ed4332b5035bfba848ff97207357100000000bdaed84e0cbab735880d4763a1eb2df1ecd59dc261f3446db37bed5b6ccb99f331bf6849ffff001d2e5bd48e", + "parsedBlockHeader": { + "hash": "00000000bb0d9430d3d1bab474be5050342161efcca9f7e45b151bff9a700944", + "confirmations": 894599, + "height": 28, + "version": 1, + "versionHex": "00000001", + "merkleroot": "f399cb6c5bed7bb36d44f361c29dd5ecf12deba163470d8835b7ba0c4ed8aebd", + "time": 1231601457, + "mediantime": 1231567611, + "nonce": 2396281646, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001d001d001d", + "nTx": 1, + "previousblockhash": "0000000071350772f98f84babf35502b33d42ee8466d3dde0f376c4120352081", + "nextblockhash": "00000000c57a1b6351208c592eef8eff015d93c899a047fe35b35252a4a59bcb" + } + }, + { + "height": 29, + "blockHash": "00000000c57a1b6351208c592eef8eff015d93c899a047fe35b35252a4a59bcb", + "rawHeader": "010000004409709aff1b155be4f7a9ccef6121345050be74b4bad1d330940dbb00000000ec77d34cb2f84f3447c37ec1b4476e044e88478378998bd55d031f58f4e261c35fbf6849ffff001d32cb39a0", + "parsedBlockHeader": { + "hash": "00000000c57a1b6351208c592eef8eff015d93c899a047fe35b35252a4a59bcb", + "confirmations": 894598, + "height": 29, + "version": 1, + "versionHex": "00000001", + "merkleroot": "c361e2f4581f035dd58b99788347884e046e47b4c17ec347344ff8b24cd377ec", + "time": 1231601503, + "mediantime": 1231568277, + "nonce": 2688142130, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001e001e001e", + "nTx": 1, + "previousblockhash": "00000000bb0d9430d3d1bab474be5050342161efcca9f7e45b151bff9a700944", + "nextblockhash": "00000000bc919cfb64f62de736d55cf79e3d535b474ace256b4fbb56073f64db" + } + }, + { + "height": 30, + "blockHash": "00000000bc919cfb64f62de736d55cf79e3d535b474ace256b4fbb56073f64db", + "rawHeader": "01000000cb9ba5a45252b335fe47a099c8935d01ff8eef2e598c2051631b7ac50000000031534f7571b5ea98c1318eed04937d6ff16582ba72c53552581c40828b6ce2f5cac16849ffff001d080315e8", + "parsedBlockHeader": { + "hash": "00000000bc919cfb64f62de736d55cf79e3d535b474ace256b4fbb56073f64db", + "confirmations": 894597, + "height": 30, + "version": 1, + "versionHex": "00000001", + "merkleroot": "f5e26c8b82401c585235c572ba8265f16f7d9304ed8e31c198eab571754f5331", + "time": 1231602122, + "mediantime": 1231568646, + "nonce": 3893691144, + "bits": "1d00ffff", + "difficulty": 1, + "chainwork": "0000000000000000000000000000000000000000000000000000001f001f001f", + "nTx": 1, + "previousblockhash": "00000000c57a1b6351208c592eef8eff015d93c899a047fe35b35252a4a59bcb", + "nextblockhash": "000000009700ff3494f215c412cd8c0ceabf1deb0df03ce39bcfc223b769d3c4" + } + } +] diff --git a/src/examples/test/data/history_proof/10_c/proof_fields.json b/src/examples/test/data/history_proof/10_c/proof_fields.json new file mode 100644 index 0000000..39d5666 --- /dev/null +++ b/src/examples/test/data/history_proof/10_c/proof_fields.json @@ -0,0 +1,442 @@ +[ + "0x000000000000000000000000000000cbeb0ca24eb9fe24fb00462629c26ed659", + "0x00000000000000000000000000000000002e2173b597fee513efcc7b28fd91cf", + "0x000000000000000000000000000000004d319dfce3ecb72ec3fd743f940b8e85", + "0x000000000000000000000000000000000014c81305af3c55bd045d4b187bae74", + "0x000000000000000000000000000000565b90aff9128db19c885ce2d620db9743", + "0x0000000000000000000000000000000000099a24ecd5bc83cd56a055c9c189de", + "0x0000000000000000000000000000004a9694d29183c23afa08c7f477e2b862b7", + "0x000000000000000000000000000000000019ba298c9ae7e5682a89272dc36564", + "0x0000000000000000000000000000003ad31317ab50a2989bc6b8fd66e6a0227b", + "0x00000000000000000000000000000000000249cb49d59d0a0d79fa82e2c6ed19", + "0x00000000000000000000000000000077f01d8d73d11a1345549610f4f6ff070e", + "0x000000000000000000000000000000000026a372115a86b1b0563666ec9889da", + "0x000000000000000000000000000000c080bfded8dd48d813e3e493a1784c5d0d", + "0x00000000000000000000000000000000002632301d51d27df34f78eed9715f50", + "0x0000000000000000000000000000000be35e853e302a9724073387804c64c41e", + "0x00000000000000000000000000000000001423f7a3944db570a6b1eb28bec264", + "0x0000000000000000000000000000004ccad6769e7258dd17b15a483d6937a285", + "0x00000000000000000000000000000000002788e78980b242c53a4528b808d780", + "0x000000000000000000000000000000d4dca23381782d4c0eb3faccc29708f5c6", + "0x00000000000000000000000000000000002fc387b8c0953116f71e7b49f6f015", + "0x000000000000000000000000000000137df16513216f90502d8cf8d49b8b92be", + "0x00000000000000000000000000000000002cb1e28d26a6dd4f05feb490bff564", + "0x0000000000000000000000000000007c537e1440aceb124c6c0899da745d30b7", + "0x00000000000000000000000000000000001119bd0de0c4f0c752acb32b984e01", + "0x000000000000000000000000000000866bb2b99d67e8c2c976acb96d2fcfa1c3", + "0x000000000000000000000000000000000000c366ac114d9c2c7f8e59b90f05d1", + "0x000000000000000000000000000000b2f8b593b5307b4bc2167f55dd224616c4", + "0x0000000000000000000000000000000000025b7de4268fe6028ed0f3ff64ca22", + "0x000000000000000000000000000000f4654edd448113d3e9d409456abada908c", + "0x0000000000000000000000000000000000154011fb4a54cf3c523c35c083446a", + "0x0000000000000000000000000000009c7b3019cca7ece7463d4979812816b283", + "0x000000000000000000000000000000000025db6a07372b938a211b724dcc12ce", + "0x2094be14e9df3eb669c1c2b1f246d39512d05e1b269566dc0f7358d6049f0555", + "0x0fcf905df75261734e8e83048f3a84c815638a2d532409b5346e9cbdeb60faac", + "0x03808c62e2c633d77417597612b05cefdd313effc7c56b094698b0bc680dd618", + "0x0e2ea2f83d9ec3face5ad006fe81ae904b3997b7afded315cd04f7c50748e0a2", + "0x2f5f19763000c548b3ef977d83a306cbfcd70d583cd2fdb20de83a2d705179e0", + "0x059eed564d40d1843a5a5fe272fb7f896a8efdb1858a8c0438e13b93d338f3a9", + "0x2f86c1f3f977f898f2055316acd4bd78a6c02b7e3ac4e10fe9c7d74fedd63f8d", + "0x0064ac5b4ca76fc638963a8b34934b4a64e5fc3807fb787cde8be7de49f16281", + "0x257f3383853d2e9715bdf34e7590c3ced5d87166a88854bc6f0ad730d955a956", + "0x18799282f4cbf470ca4ad68a644fcf24fd650fa7174bc94203753679ffeeaacd", + "0x20bb15b70a650bb93c81abc92b459e6dc6c8815b456e1593e3351f1b8db547aa", + "0x2daaaa46b54ca67b8ab85b436698ec6a0cea0fa435cbf92e04948b4256b0efb1", + "0x2ce4d68490d6d5cea4718e17138d3cdcd22014b09bf3d2c5fc0eaeec3dec5905", + "0x162015c3e543bc8747791835071e543f093ed481313db72d902eeb72265650a1", + "0x070b97b4b8916794569b4767bb563ae479c1a14d46febc6fa4919ce9020b7650", + "0x1f6d2b8c0f1a0edb992807d780a0c88c5b8b8117f96a208dccb48d932aaecc70", + "0x1e8ae05a4e0e85ff68f549033ff68c2e1e6b7cd3cd7083311b7bb6c765729993", + "0x2ecfadc08d86e712d70f80f53f6ee204756079a0600bc30ffe52e3ef1ea7ab58", + "0x172b48d8dcc3cc827e8c840d453b02b6830d457b3845184961c1d2fa6aa5a1d7", + "0x0117d2b69e927dca789f17a3533bc52f77687c5c9c697c1a4016de29b8268a48", + "0x1c15f510e068334f9e3ea1710f53b8663928b9ea78a0f61e82bc153861af498d", + "0x2bb64d9025ec866890a83c49cf102021030212454fa4637a43a4c29be9f27557", + "0x207072db618980d472433d592ee9f9e87ddc034e905f951c3d3d7d2c1036fa6f", + "0x2f0a095f037d5d10b9d4fb63549cc123e35e705c8aa2b6dfb5309335eedfea26", + "0x079e858cf1ccff688508e3320b5760750f151a6e28e8e416077bba65e2099f33", + "0x2f853e31d1c74c4fd1bd369a125bdfc5c10e8221672ed5ddf770a4f04fe38db6", + "0x1c063adf67fa3da42c1d8f3c2b77b29ff84727f70991fc0b61a9812ba253547b", + "0x2cb858f878901987d93e84b3aa5b8a65c8fd621381bcf31090cb18cf8feac984", + "0x07c1571ed01e41830c5bc80129d3854b6167c8d79cb22fb5c3d3da78693b29e3", + "0x2718e6ebf642578dcbba2cdfad2f9bd632382ca9b2a16f890d4a861b72518fc1", + "0x060abf93514a8b204af881fac387a4996a470aa5774014850e3bf3b8a055bf1b", + "0x1d782405a91252e881ed0bd627383a42204982bfe8c857018ad31798e50596df", + "0x2a9080c548294dfa7a096a1b6309103bc0e52b32f5ea88290da82be43f8e2028", + "0x1cf39076531bf6042ef600f2f4e86cacbb07053215f68ab20659bbd5097134b2", + "0x2ea3f68352681ce550686bc64b774eabcaa32df49dfe7cf27758d77725eee1f1", + "0x2f5c91c7a5706b42caa05bcb4c514c7d4c9556c5c721bad138720c78ef06b758", + "0x24d3778d49c320af8146299c6eda01fa2137c3ff5759f8cc31b989ead5c678e4", + "0x09175f6786c4387ad31412a4db84c4728aa3386827f03ee01588372685eb5d4a", + "0x1b81898845b6daaed8c117bf0a020884a79435f3bc8986d2cd1c0a2ae36c2cde", + "0x28de5f1c06e5ea157487eddd91ed2c9f2c5bb6505a270a8b3c9f518660c747c6", + "0x2259486547626f98ad69966caa27f38592bd2fc8958a5f771ca7e29b1a29632f", + "0x0f51ac86af1e61e0ccaad115b446470778130dc1cf3bee2f10ae41588d749d2c", + "0x0c1b8c8863018a5fbd99dcec6ff53f05572d5b7731ae31a78a424d5956e6cd13", + "0x0ee1db7c5b08b08fe44ea1373d819044becaf959439de97d3154d469f59fc82a", + "0x2fa29b11544d97277dd982e5e477935d177c6e28150ae45c68a061579df4dbd6", + "0x2b3213200e8e470ead092b94876d7a4052c12e09aadba50c952ef7aa1a65a663", + "0x28d53b4bac392ee9f3cad48b6f9650d5283eedc65d27dd5ca702b4c2f7bae5c8", + "0x0d4c2aaf966153030b0e66d917f10e51990647177b073092ca48f651760ae3a8", + "0x02081658896b2ffbd79463dee85e7722b7d88c676c6954bbcf41019bcc20fb7b", + "0x24d851273ff290f5abdf2cf9665f04423accb28b3d7851f6b37ddf47df88f9c2", + "0x27c00f15d2962261bbcec4d12e6f3362e6c9fcb010c3ffe8af5d28bb1a28d71c", + "0x11338a16131ef2d021a9e7d23d134321acba2300460ee2b458fa1814889f2c63", + "0x0803607f731d47bffef83bf2c6e6c8e9790f6d68dfccfd64fd67d94e55fe9555", + "0x2b55306a32496059218efc90a1f279e60639ce1555bea7231c88815a4e288c87", + "0x05a2ca972af79b121b3033c06438e622a8265279cc624e5b6eb985f1386ef9be", + "0x01191ed5eeb5f358b1c8024f278d9ca8db86ec01c3dfe57884f8b1a83a1687a7", + "0x1b5dcfbb9944b59a9be15090a0da37958b83bbdbe156a067d5aa3494f74f6288", + "0x10c31bc10a09b71d2ddb137b2f5002303c8c4bd711b5a2b84ac51382196ea7c7", + "0x0cb8affa2a03b663fbc4ef0aef099f2813b32242e1831db590bab924f9538f33", + "0x20deb4bfeb2e93b21f0c0d05240aa08982d8c88d53f5925bb6b69393589de93e", + "0x0b9cc7607bd52b9fad7ebfbe6b233b3831e7cec0b02e4979332e8f263f4e4e35", + "0x2039b4a7c8451f1d5c8f1fd66d578b8e9255b9b666a901e2e8fc1412e4708cca", + "0x049bab5b4d19cf0632ff6d3080469025dd115554d5ba84dcb13eee82cdcc54bd", + "0x1cfead21792b229b58fed5aece47794fca4859e8307cdb959469938bf9842712", + "0x23d4b6bde09707d19dfd21373d460fac4e733d591b74e44ac308ef2f471b0c40", + "0x07dcefa454c85be6ac4fbf926b4266852fc938ae2e338a9c6a39fbd2b42aefcd", + "0x22e5871423c9bdbae772be5ab87f9a9913f87debf05854035af6e8704637d783", + "0x1907c6d3ced7d0b385d725fc76401ea42a4dea6180d1bf85b8608f7349ab895d", + "0x2a1a453ddcc790d7cb556c501747930baafb479d2279341e906ca0193e8e1c0b", + "0x215b6c5577c8d05d5fc80c290acfe8f71c91d60292c0cdb1c7742c8c6402de95", + "0x293901d0a502ded05d360a052399eb51669508e73ba9451312a339882ee05eaa", + "0x1ce2ec2e6dea3cc60aeb944877a46c933e356215a23c298f4b624c42db309cb8", + "0x06c4d6bf267d0206e9b6aabea44ddcad8c4a50cef0d06aafe3ff361803235f30", + "0x232f212463953047c00be0406743a7da2e58f9cbff7191a101ef934304fa8051", + "0x0a5fce30996f4dd66598207721fcdbd7bc76d6bafe5422319749250950d58380", + "0x1fc0d3eba16a0b842249795083ed5a5301357088ca687bc947ade5793faa777e", + "0x05de47675a4dca27d16ea03fdbe63aecd4dc8508c0e03924f35e0e38c2cd425d", + "0x21e17cd6e07c9ef572b5607d7806d93d31f93bcf1c2d8fd2653e0143358ae8d0", + "0x207cff2f2cd4a769012003886136c8527fc562c0dde86f2bbfc8d18d94bc1182", + "0x3010d801667556a45cf972a509c07c940fffe9b0919d22ca9d5dbe024c747824", + "0x20dae2fa51fe7addb5748b1e399f1ec5a9b84e57bcd86502e220aff5869d355c", + "0x223ee9cc81b683e1d0fb536a651e21c105b45b5189cd82dd9a224e6803d5a583", + "0x1f9ffa9fb6de8b56a2c724c98e2de1ca5ff40ccb3a3bba279322ecc5e22e4973", + "0x2201242630e8bd245d717ac558fd3159b2917702ca9a90705873974383ea99ff", + "0x2c143c97df44a542adf34d961ea4f65a97d9629d0fc8ec1bf617a8bab75a721c", + "0x1e778aee22ac4640f6d70e31e1423757a035a22cd85d5fb894b8cb99273bd50d", + "0x06e7960c41718aaeea6fa42bbc29909370cc8c3dc80eb3e0a2d35625dcce9008", + "0x0136ffc60305f5ab77c48b5296191dafc77679287242dbac37744571dbaac9dc", + "0x1368ceb43ac19d465a8be9df2e914b3e358a58b903c88ce8607104a36fb99e28", + "0x04dc35039cc449cc4aba496956a2e22d0dc82d45b9d9ecaeedcbd8f0014bbde8", + "0x0bd40eb9b4d9f110477290f74423f293984375d9a8ff15c55152762db462bb27", + "0x1f44b2d5aea1269c2a0779fbe01e6b02f322d2131bb81f66a16ba4ac4a8dde70", + "0x0aa27907ee83a9d72bdcb54a2da87f7c99b871925b77c82b87a1a9dbe94e34e1", + "0x2caeab785df3122852066efa81be0e0437d9da17db8d721a047ffd5ccc127a4e", + "0x0f778daf75ee6a2d7fd7101d197dbdee6bd2872950f37bdd13245a8b4ee6f4f6", + "0x0211b8931b82de097822fca7e45c596d72141484edaa18fb62f7bf566ce01cad", + "0x01c7a16c09568c6d73756c10a52fd7d2e8592af9f564cb2106972016dbc81831", + "0x0c65f0a2b3e1c25a75e3e87f5c4ebcc471967e97f0628f470f73022024e5d1bb", + "0x043fad72b9c92cc6cd8715ed52a7d6a54348fe1bfa201164ee058c17910acc20", + "0x2949ccbea14cf37006344e0ed3fc964c8f4fcba66c3c73336c0d2abfdf222812", + "0x22736c1f901b70886699bc0af518b77847a77c7578782818c58e3c4f3b8ff914", + "0x3022862de4673fbad5079e64255ce6f9106431f1fc37456c4c2eaa28360f2d80", + "0x240917c25287f860b9d28a541f9cb7225d5525b48401d0e066ec7438d1b6648c", + "0x13907d1c84cf7ef39252c0f81f6da7a5e69026388f6fb796f2b09b02224ecf8c", + "0x1621ec2b7e1ea6dca4621f2171d7dcc000d97ebc90a0c6295d567e0cb158cadf", + "0x0d7bac1619208de2afa47f1297ae83d5f4d79e3acacde76df6164c4035c7b660", + "0x07942f154c8d2858ac782ce111d3626233d749f8b9ef1064e1650aca4b75984d", + "0x03d188fa68fb8bf6e6229e7a3f8f014197e6ac23b2832f48ef6bc3ed237ffb40", + "0x298cc57c16dd42940388354e15d59ff44bf4d45cd76b4dae1c206a4223dd9e05", + "0x1b4fb994ba6d87b7e44af3a23e3c231c65895822a195a3652ea8fabf85234142", + "0x16f7bd7f9aa32535050c7328951549dbabef9b41fa22426d2aa2d41cae535b66", + "0x2019123e1598534956c66acfc0c4e40dcdfd451262d6e4a17ee48037631a0d8f", + "0x038e3375a488aa073dd951f4a405ae85c097e1a8fec3d308a49e2dc16a5fb1bc", + "0x172b60aa300ba2de576c46258aa7f602063b1120b0372bcb945ac1bb2229ffaa", + "0x04a889af82f16081169c27527584e0ab998279a618fe9d469f9304fb55ca822f", + "0x26fdfe8ffc3305bfdccdebcdb39b3df65bffa939e656c88783b9d1594d82a8b9", + "0x1f0a759017a46f77492ed7eabb10824d39e7a21b9cbdc4e3eac26703344ff78d", + "0x2bac466b4c86c90eaa5796d896b22fdaed99e66affa4a10b6083aa566afa0984", + "0x0a528501047a39cb1ffd632b685e83e6dd32c91bfc068ee6d1243dbaed37fbd5", + "0x204f0bec28e1df68286d226413e35334d282e3e65a609d734ff8b58875602c72", + "0x2b0d3372ce9417b05fa566e3cfbc0588182d1d2dce08317760f435f16e291deb", + "0x164520b6f52ea043e233f03c2af27030a85fa4c73b8f8367cde8f2698421d7c9", + "0x219aeca93b5a359d2c8c864c734c8f988bd46a2842b1cb995f7be08821352b55", + "0x2e0307cdbccd82438e57b3166ed11da770cd0f27405219af2158df77c4125c1f", + "0x20e534c4fd601721be50b1b87d93104d89a5aaaadd3045dd22fcb79d0d7dc045", + "0x2b638096596db82d567ef20861bcac10392d5ec6f26d8ceeb176752177030478", + "0x247d210038a5ef46169df2eef586977dffe75ddb9ab2c40f0cfcc9a011058d8a", + "0x030726e41d8df4f3b6164140fef94a51529d273a6e9f71604ec753ba0f46b866", + "0x12fa37e9992168e8261e0af3ca13b65ad507d0e6a1d106c1054d375c3803343e", + "0x1c29aa8fae406b159af6facd787527455b2b9af8d84c1a76359340b3430542e3", + "0x04462c42d9716efcc50b10a8f28d1cedfa9bb838a76fb73214e6bb7ca4ae94b8", + "0x1ab5d2acaafefe62db7694afa3147bb2b3ea41934808c2601b91ebc1d1fcfe84", + "0x11ac87d931e0f1d9b0153d9d6f4433bea820ca5447b8b5d335806c5abbf67c75", + "0x0b77f72df84d5d150f56371c0f561fd18228cd579b6b10d6a699beda6114d18a", + "0x1352a451ece9a7130d2389564018a642a1686f8b7be603b112767f76da89f1d7", + "0x1b915437ee6228831d2619a2a63d9184f8467558e731a2167fd024985c458047", + "0x25e2aa7f7d9d0935d38957abad43c45f2535cae4518ae313e7a1e5d6b0f2e907", + "0x2a407442aca8303dbaa7357bdebd562a4241ac95963bfa30a478389796b1eec7", + "0x1e9721f3a0eed569cc744675e80ab5b82ce5de8b354793838631c94dc5896a27", + "0x2468be72f4b8f1ad1bcf71f50c33ea961cdd7a72b621018ed6556a647d07af33", + "0x04d6e6cd33124a47c3115a63df1965709585a34282f9fd2c271ac0bcaacde6ea", + "0x0c66a0ffc7ce53fd4562b3b81684b8176a309487aa0573bf95d313cf30c699d2", + "0x084d7acbdb941427fe88e0250065d2637152a5621f1503ad6820ba45e152e0cc", + "0x0187a2ecf58e1b30572eb5961973e3f5bd2581555b5f6debd9770c83e9cda1b4", + "0x2ef24e1e9841118c71b391bb139779ec4c48dcd9c6f0069f4a2ac526a7310f09", + "0x05394ed66c92496f25c27ada9d691f054248ad84bfe3cea7dabd2534722cf6d7", + "0x1505bde04336909066d106f8a3effafac55b465ca39e3511eab08a07fd74b4ee", + "0x23d7dfc25d7f7a2a15bfc6a3ef9f9147b963b8d2db98a17df418481ebd786601", + "0x1cba591cab9321a068b6cf2e466433b847fd9d6a311aaae64d227ff0d59756f6", + "0x27a2dae6f0662be2c4e1fce57c26953d0c8a99d255691ee28e15a1cddc2f6fb8", + "0x12b9dbbfe805b69d8619532ee031e347d29e6a3855a7f7302fe3f77ece0dd373", + "0x06fea7b21599268fa48435f8a56635285a3ae7b0cbaac8f87631cffcef04c18e", + "0x21184c327647bc3393d709625a3414d411321d20f52ef0690802322be30e2f1e", + "0x0ef2316c89988c35d4c3651c5e37cb3800e779d8acc532d6f42593d98933ac43", + "0x262514856fe09a2eeaa94d8b09d2823a0f2691519ef7b7fe4ac83530c4b5eb74", + "0x20f4dd788afb7c78e3d764620e23060065aa46926a31b91589f123a1e77b1c9a", + "0x12e8fd80b9694bc3b35ef705726843547c22570a4e5c27bb53d9f5162394b161", + "0x17857429710775a204649651950f20c940abe6b472fff7a108cc324b1a0db031", + "0x0272013658099076d5db7da24c0819b45ae7a6dc4c481e0d8e4b3406a878a164", + "0x0cf69f46224b4c38a49e54c994675de66a7ae473f529a53d4c3ac9dc8ce22709", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0f3050a781ab9c51e0e8805edee41534c1624f2c0420ff17b0591543443694d7", + "0x2643cf39043d1d91665f912cb6cc023ce7ea2ed00ca09663abd9118ad4c101d7", + "0x0268e36cc87649f0d6fa8734c9f3407df624d74a9a27d98d2511172eab3caf9b", + "0x1d324db345427bad6df6f41c38d13558bc3d56497121e8b27a6b30a08d31bff7", + "0x15f063c9dbf0eb57128d5995efa8e6a5baa9c0ec300834ad3434d1748f654628", + "0x09a7945b0f4d6457e5ebc17304093c0b61be8fa7dfe955f283ba7ff2c66e7800", + "0x0445a05bf51ada3ad083507134c9011a180ff4270343f0de74b854414ec3b432", + "0x1737803da66848fe64612896e5b88383ccd6c60d65005c0062ecba127ab50571", + "0x0716d56c273e3417e2556b22452e5b5752dbf33e6d83d49e57c59791ceb489ee", + "0x18fe93b569fab2f9d90f05617561a1e04d0d539935a1f347f0a8311849d30855", + "0x1e5cbda0a8f0c715dc9a4ce54f33e1ac224bbd4d598b995b786b892c2af59bbc", + "0x1324f4a20a81c3513821928a857888f3a892a7b757eb22a5cafa5e3e4bde73e2", + "0x00015e6cee81dcafe2dcabcea8b7b87e46055359e144f0a9ee31b7d08027f500", + "0x2ba0a61039b5b0c944b30cb9b2b55529cea98bb4e00f353604635feabda1e1f7", + "0x282f0c3b647e51bd52372e976c4d3c84cc384638c57192937a876c787364f751", + "0x23a9bc9d6050f173f45a8597fb453162ef020cc6cb0e6d0d3419350d79db1eab", + "0x0b64df2f68345f41618e629bd93550bfc49dabbd9eca549607a2970d4bd44ebc", + "0x2f25a369a1d9643ad57ec4d288e418709b85b96f3044fd3f255852ef1dfa3884", + "0x17fdbdc07447dd1e5d3042d4e862859783557f86e92c8ef5f47656b34f741ff0", + "0x2a9346228fe4c294d458de51032ee70fdc7a0a09c123dd8e6b00c81d83ba3b94", + "0x2e2769545c957bf00fd20217b542711aaf10d7e030d3388070847566462b78e8", + "0x0b7232f1e8528980161c0c0f7a1155561bb389d7c6e370a745cb96e6e4e415d4", + "0x0cbe38e384ecbbcd7b942d82f241ebb09301f8ca6d5ac261a69cb1110f17ea68", + "0x1ab3195605f8d2eae8f9d43f06eddda3e6990e70f131070939f8768a962a3386", + "0x06b9f1262e0fe07bc9c26c771480ae3c77918a695fc105643e9bbf1a0bbfe5b7", + "0x0e4ae0c6e13d6b1f650ec3407769b1aa4f014a14ffcea6b06f63ebab1aca3483", + "0x01244f4c2e22209a548472a648a827faefd09bb225607e5c526548da31e025b1", + "0x0aca01d88a3b8626c6574783371d07031b15298e4352699edb3f5256df5c89f8", + "0x0a1ed77961bdd707448c5f38bc85736a54b57b308ce7a326e2f45fdf7ba040f2", + "0x29f8d494253b14bb6e9a37983ac139118e9377559480ea75f01b48c9fc0c8898", + "0x02d239852609f0ac314b6e4a926f9bc5ba92dfb96075189c5f569ac96f8f9c3c", + "0x10799fd485cc53d456a06bc1caeda2279f45908abcbfcd395159d81d0e8b0588", + "0x0dbd1fec791eb85069d1292b701f73ac5dba6095aea384a94ec8a66dd9ca2fa6", + "0x09cc1c211f6eadda07e19bf3d95a3da5fdc71fcae7f92bb9679212b5367025f6", + "0x148d43ddd89081054963e7a47f2924d14f7ecabb90b59ce3a8f653008fd47c08", + "0x07a182f868c385bd8ef21839cba09a4074196ac223942c35878284b3d95daac3", + "0x1563c6c3b50d3f3e8b889009396c0633436a9dacacedd35663c9c7d4dea80b0b", + "0x2dba6d28b3637c636994e8358f3b83daf4ce4caf3303167c200f6f4bbbc7b610", + "0x218243268372ff4ccc9b0752b35b27d9b8fe9029f71797d00b970e8e4b3780e9", + "0x19272d40300dee7bb2d9ac5b8e2719b4d51277ad85a355fe1435b65a4958c60e", + "0x0000000000000000000000000000003e90737a5a8fc6fcddb679295a4f8e7a49", + "0x00000000000000000000000000000000000407d9992d2c08039cdf2102a6a274", + "0x000000000000000000000000000000e30cb57187f5d63ece1cde0866b4fd2cb7", + "0x000000000000000000000000000000000006c87a93935863f8ad9c46305fd02b", + "0x00000000000000000000000000000047b1210912ed6a31a3163ae6b4d2a30296", + "0x00000000000000000000000000000000001e15b85be9aec41e0aaf4e928e741b", + "0x0000000000000000000000000000000abf41b789c943cc82e08723619b767f64", + "0x000000000000000000000000000000000008b9b57d9ad49b31f9e2fc41160fef", + "0x000000000000000000000000000000eaa017437219937923e09338d3103827e3", + "0x0000000000000000000000000000000000135897872cfb99d593fd84ec3f4e21", + "0x000000000000000000000000000000d32e2856fcdde0f877d9a81499d7b69a43", + "0x0000000000000000000000000000000000090168fa939c1c0cf5849d8b8c7d7f", + "0x0000000000000000000000000000009c1b12cfa71f3f90288e58c60659226c23", + "0x00000000000000000000000000000000000c75a14fb8877b949873231d50a13e", + "0x0000000000000000000000000000005d8e1af1d29226e0b1aced839b61be7d19", + "0x0000000000000000000000000000000000124c0dc74d344e3fb95a6931c67791", + "0x000000000000000000000000000000da45088ff825afe05a53d065f622f6b551", + "0x00000000000000000000000000000000002208b3d54ad1d0aa31839e736fc38d", + "0x000000000000000000000000000000e60808560d383de43157abc2bd99fae062", + "0x00000000000000000000000000000000000c05b20906f4ec33fb64ec24196df4", + "0x00000000000000000000000000000084916c1e2337ebe07ca22cbfffbe7892ba", + "0x000000000000000000000000000000000029066738d101bb38f9b11448ab4dd8", + "0x00000000000000000000000000000037d7d04a64887b207ece31a3b01139b7d5", + "0x0000000000000000000000000000000000104ec1c1c48cb28bdf1f591735d4c9", + "0x0000000000000000000000000000009b5f1c0ecf719b4390a274790f6109ee5a", + "0x00000000000000000000000000000000000eaf91aeab39fd4dfb473d07b42278", + "0x0000000000000000000000000000006e2ccd84e64bde916697087e014da9122d", + "0x00000000000000000000000000000000001ab19366c0087cc4c5a1be3ac37dee", + "0x00000000000000000000000000000008ef80dfe4e0f6acc38da22208c13aff6e", + "0x000000000000000000000000000000000004d6aad037f70effbe5e794959936a", + "0x000000000000000000000000000000542d0771117e88b5d0baca38d5add50bf2", + "0x0000000000000000000000000000000000112c41d4390a92f543bba53c590c3d", + "0x00000000000000000000000000000059b54594affe2d7e413d991917b1c1ba32", + "0x00000000000000000000000000000000000cd03c878769d86218eb95edd05357", + "0x000000000000000000000000000000e9820ec546423a74d373b899fa5a699971", + "0x00000000000000000000000000000000002293d6d2f2702dc2ab6a7ebc5cacc6", + "0x000000000000000000000000000000ccc1ac737c0f8b42fd85a209efcb5a8dad", + "0x00000000000000000000000000000000001107b4805c3549361571768b0a3b76", + "0x0000000000000000000000000000008476a670c05e821cfd02e164f96c3ae7d3", + "0x0000000000000000000000000000000000046179ece0cccf8ee1baec39f7a260", + "0x00000000000000000000000000000025c36af1aacf9476babfc3e08bc6264ea7", + "0x00000000000000000000000000000000001bf533e2e60e07903eb5ac0f58b983", + "0x0000000000000000000000000000003b84706298f81bd627c7531207aa58a950", + "0x00000000000000000000000000000000000c44119db0bfedde592fc4eddac1e1", + "0x0000000000000000000000000000004f83274891b0d336339c57c4b23a1bdc8c", + "0x000000000000000000000000000000000028504942fb4697b3038ad623f001a4", + "0x000000000000000000000000000000d59e4672537a2e48bb7b8ac9528103fd27", + "0x000000000000000000000000000000000025181519d415ecfc5a412664ecdcdc", + "0x0000000000000000000000000000008670edc0f7ca9b3dc1bbf5c083f2fe45ff", + "0x0000000000000000000000000000000000247dbec5aacf01d3f56f8dd069dd51", + "0x000000000000000000000000000000600ac12e82b54dd9f5f48185f240e7b0cf", + "0x00000000000000000000000000000000000d66bea968eff728d8cbb6bdd8e8f2", + "0x000000000000000000000000000000fd4de4e3858c243d1bc2f2c80da51670e1", + "0x00000000000000000000000000000000001d23c9bb5215d8ca0b70b99feb8120", + "0x0000000000000000000000000000005e905bfe9b857bd47bb5a33f5adc8be5ea", + "0x000000000000000000000000000000000009aecc8a6a15b24088e05f3c492e67", + "0x000000000000000000000000000000285ae065e3e50451d2b8cc2a577582dabe", + "0x000000000000000000000000000000000029e94c3934b6b92971fa1d98356b56", + "0x000000000000000000000000000000cc9cb8c1d53be6c37bab7433a74a19dd15", + "0x0000000000000000000000000000000000132e8b7d6774a751d1ea7c5427240d", + "0x000000000000000000000000000000b4f12317bade2af292fe27297c6248de88", + "0x00000000000000000000000000000000001487709dfa0bdd75e849c2062a8d83", + "0x000000000000000000000000000000a6693344e2b22b2e563836c4ec46517558", + "0x000000000000000000000000000000000014dbaafbe05476b484378b6d34cbc8", + "0x000000000000000000000000000000763d48a13f78bd3ada4a3f9d96316eda79", + "0x000000000000000000000000000000000013f5feafe0d0091bec427400084682", + "0x000000000000000000000000000000b741600301bd4603257bacacaf0da4d58e", + "0x000000000000000000000000000000000027185473d92d4a29121e3f3e829204", + "0x0000000000000000000000000000005f9e7ae93dbdbb31f5cf3075fe571541da", + "0x00000000000000000000000000000000000bcb74d5cd004343d618bdb24794de", + "0x000000000000000000000000000000c13d6b1b829b795d1d06e1fc225da5f32d", + "0x000000000000000000000000000000000020e4296493caea951223fd4342884a", + "0x000000000000000000000000000000a3e4433ca75094dabd6998a9019bdacda6", + "0x00000000000000000000000000000000002d3bd3dc623b573d5e5bb365c5106e", + "0x000000000000000000000000000000f0e5557793c7ce8102312e8409ce0821f3", + "0x0000000000000000000000000000000000160f3fbdaef59c7989b59f69b9221e", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x1ef4fb0bd3b55bf17e1f263bd5f1e71de16fcd4bef1d93efb9812f94416d31f8", + "0x0c765111603684985ddd3727723f8e2f86a823c22772a638225d9844ae54fb18", + "0x1eaf4d198b37fece3d043ceca3cdd9baa37a49144909e2296177e2766cb9253d", + "0x123c074c5f7f9828b3fe8b5fe85be412a0bc9b4d97bb65f8707a66b2d2766534", + "0x1518c721bbf1833bf8548f891c7e6dc9b5daf41a78acc11adecafc8ff4c500f9", + "0x1cb5504d8591d3fe161a7861d2d9706bcc87538c1c2a55c89163659ce349c914", + "0x13586a2ca5a677cc07516b7baa21e805fb4da35bde9731762bd21a9c040d062e", + "0x1555a53f3e58d8b3c0cae074c090401e8785ee66e31dfc1fdb546e45680d61d9", + "0x05521dd5343ca949a0a4a90fdf9628d2a8bf17ee3e09c08395a3e6882f86ea67", + "0x0d834e7b3d4ac7151cc664fb34b7a23101343c3d5072f0235af4caf693aaec9c", + "0x11f21aa46466aea3a71574b1148f9bb803f27799fd92c89960282e04c580b845", + "0x103b5b5044035163e18019d867b825070ab2dcac0e3b0fe1776bdb61cb33f881", + "0x0c3bf934e3c203f6561f10f4cb6a00bfccebeb26825366d7a695cdfd077ef2fc", + "0x264f635ca7223fb72a57f8557e149e2712f512b97b0d36512ee2b80b8a0520ac", + "0x26d7b9b728712dd17e4ec428a34f693cf8568a59224abe3cb8d2f35ce686ef30", + "0x0d0a608f938228a428df6b0619d4b927ba14ddffb4cc2486e125fdda659e8a60", + "0x0ffa546a1acc34974a7d8364580fa5445aa54d7cf7907533519dbe6ecb388079", + "0x1a4e2ee169c431a5f1b2fc3a9c97cb3aad2e916dc43460ee0be198ecde4cbd04", + "0x1137e03a5073429ce1d3d79deeb7c42c57e4ddbe8e033077e617772b1af43e24", + "0x02ca042cdfe8e8118c27633f9d7c4fcdff405688a8da27c17af296a800968a72", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000031207fb4b624d8e3a909b1b1acce1b2019", + "0x0000000000000000000000000000000000242d189bc325e1b87ab9201c7d4a62", + "0x0000000000000000000000000000005d2a68f20c011604f2ef7af90f847ff9aa", + "0x00000000000000000000000000000000002f4888c4b3cfdabb9e8c1418db6272", + "0x000000000000000000000000000000454b7cc9c00049476106f7eefbdf302cf2", + "0x0000000000000000000000000000000000125705b1dc3db16adc80d8617a1863", + "0x00000000000000000000000000000013e0ded238c082bf26f2b2547c73ba3705", + "0x0000000000000000000000000000000000261edbc8b77ede368d9a2643688aa3" +] diff --git a/src/examples/test/data/history_proof/10_c/public_inputs_fields.json b/src/examples/test/data/history_proof/10_c/public_inputs_fields.json new file mode 100644 index 0000000..2960803 --- /dev/null +++ b/src/examples/test/data/history_proof/10_c/public_inputs_fields.json @@ -0,0 +1,897 @@ +[ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000000000000000000000000000000000008d", + "0x000000000000000000000000000000000000000000000000000000000000009d", + "0x00000000000000000000000000000000000000000000000000000000000000c5", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "0x00000000000000000000000000000000000000000000000000000000000000f2", + "0x000000000000000000000000000000000000000000000000000000000000003c", + "0x0000000000000000000000000000000000000000000000000000000000000026", + "0x0000000000000000000000000000000000000000000000000000000000000057", + "0x00000000000000000000000000000000000000000000000000000000000000fc", + "0x000000000000000000000000000000000000000000000000000000000000004f", + "0x0000000000000000000000000000000000000000000000000000000000000067", + "0x00000000000000000000000000000000000000000000000000000000000000be", + "0x00000000000000000000000000000000000000000000000000000000000000a3", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000078", + "0x00000000000000000000000000000000000000000000000000000000000000cc", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x00000000000000000000000000000000000000000000000000000000000000a9", + "0x000000000000000000000000000000000000000000000000000000000000000e", + "0x00000000000000000000000000000000000000000000000000000000000000b8", + "0x000000000000000000000000000000000000000000000000000000000000009e", + "0x0000000000000000000000000000000000000000000000000000000000000084", + "0x00000000000000000000000000000000000000000000000000000000000000cc", + "0x0000000000000000000000000000000000000000000000000000000000000047", + "0x000000000000000000000000000000000000000000000000000000000000005c", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x00000000000000000000000000000000000000000000000000000000495fab29", + "0x000000000000000000000000000000000000000000000000000000004966bc61", + "0x000000000000000000000000000000000000000000000000000000004966bcb0", + "0x000000000000000000000000000000000000000000000000000000004966be5d", + "0x000000000000000000000000000000000000000000000000000000004966c18c", + "0x000000000000000000000000000000000000000000000000000000004966c344", + "0x000000000000000000000000000000000000000000000000000000004966c4ad", + "0x000000000000000000000000000000000000000000000000000000004966c6f1", + "0x000000000000000000000000000000000000000000000000000000004966c867", + "0x000000000000000000000000000000000000000000000000000000004966ca7f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x0000000000000000000000000000000000000000000000000000000a000a000a", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000000000fb", + "0x0000000000000000000000000000000000000000000000000000000000000067", + "0x000000000000000000000000000000000000000000000000000000000000002f", + "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x0000000000000000000000000000000000000000000000000000000000000065", + "0x0000000000000000000000000000000000000000000000000000000000000090", + "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x000000000000000000000000000000000000000000000000000000000000009a", + "0x00000000000000000000000000000000000000000000000000000000000000f9", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x0000000000000000000000000000000000000000000000000000000000000066", + "0x0000000000000000000000000000000000000000000000000000000000000059", + "0x0000000000000000000000000000000000000000000000000000000000000050", + "0x0000000000000000000000000000000000000000000000000000000000000046", + "0x0000000000000000000000000000000000000000000000000000000000000038", + "0x000000000000000000000000000000000000000000000000000000000000006a", + "0x0000000000000000000000000000000000000000000000000000000000000037", + "0x00000000000000000000000000000000000000000000000000000000000000c6", + "0x000000000000000000000000000000000000000000000000000000000000002d", + "0x000000000000000000000000000000000000000000000000000000000000008d", + "0x00000000000000000000000000000000000000000000000000000000000000b9", + "0x00000000000000000000000000000000000000000000000000000000000000cf", + "0x00000000000000000000000000000000000000000000000000000000000000f2", + "0x000000000000000000000000000000000000000000000000000000000000009f", + "0x000000000000000000000000000000000000000000000000000000000000007a", + "0x0000000000000000000000000000000000000000000000000000000000000022", + "0x00000000000000000000000000000000000000000000000000000000000000cf", + "0x00000000000000000000000000000000000000000000000000000000000000f5", + "0x00000000000000000000000000000000000000000000000000000000000000ae", + "0x0000000000000000000000000000000000000000000000000000000000000068", + "0x0000000000000000000000000000000000000000000000000000000000000091", + "0x0000000000000000000000000000000000000000000000000000000000000093", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000093", + "0x000000000000000000000000000000000000000000000000000000000000001d", + "0x00000000000000000000000000000000000000000000000000000000000000fc", + "0x00000000000000000000000000000000000000000000000000000000000000fe", + "0x00000000000000000000000000000000000000000000000000000000000000f7", + "0x000000000000000000000000000000000000000000000000000000000000001b", + "0x0000000000000000000000000000000000000000000000000000000000000066", + "0x0000000000000000000000000000000000000000000000000000000000000013", + "0x000000000000000000000000000000000000000000000000000000000000005b", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x00000000000000000000000000000000000000000000000000000000000000f4", + "0x00000000000000000000000000000000000000000000000000000000000000d9", + "0x00000000000000000000000000000000000000000000000000000000000000b3", + "0x000000000000000000000000000000000000000000000000000000000000006d", + "0x000000000000000000000000000000000000000000000000000000000000006b", + "0x000000000000000000000000000000000000000000000000000000000000002d", + "0x00000000000000000000000000000000000000000000000000000000000000b7", + "0x00000000000000000000000000000000000000000000000000000000000000b9", + "0x0000000000000000000000000000000000000000000000000000000000000098", + "0x0000000000000000000000000000000000000000000000000000000000000081", + "0x0000000000000000000000000000000000000000000000000000000000000095", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x00000000000000000000000000000000000000000000000000000000000000db", + "0x00000000000000000000000000000000000000000000000000000000000000e2", + "0x00000000000000000000000000000000000000000000000000000000000000ba", + "0x000000000000000000000000000000000000000000000000000000000000004c", + "0x00000000000000000000000000000000000000000000000000000000000000d5", + "0x0000000000000000000000000000000000000000000000000000000000000048", + "0x0000000000000000000000000000000000000000000000000000000000000099", + "0x0000000000000000000000000000000000000000000000000000000000000061", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x0000000000000000000000000000000000000000000000000000000000000048", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000000000000000000000000000000000000495fab29", + "0x0000000000000000000000000000000000000000000000000000000000000023", + "0x00000000000000000000000000000000000000000000000000000000000000be", + "0x00000000000000000000000000000000000000000000000000000000000000c0", + "0x00000000000000000000000000000000000000000000000000000000000000c2", + "0x000000000000000000000000000000000000000000000000000000000000007c", + "0x000000000000000000000000000000000000000000000000000000000000008b", + "0x0000000000000000000000000000000000000000000000000000000000000087", + "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x00000000000000000000000000000000000000000000000000000000000000d0", + "0x0000000000000000000000000000000000000000000000000000000000000072", + "0x00000000000000000000000000000000000000000000000000000000000000db", + "0x00000000000000000000000000000000000000000000000000000000000000ea", + "0x000000000000000000000000000000000000000000000000000000000000001f", + "0x0000000000000000000000000000000000000000000000000000000000000035", + "0x00000000000000000000000000000000000000000000000000000000000000b2", + "0x00000000000000000000000000000000000000000000000000000000000000e3", + "0x0000000000000000000000000000000000000000000000000000000000000082", + "0x000000000000000000000000000000000000000000000000000000000000009f", + "0x000000000000000000000000000000000000000000000000000000000000007f", + "0x00000000000000000000000000000000000000000000000000000000000000ca", + "0x0000000000000000000000000000000000000000000000000000000000000056", + "0x000000000000000000000000000000000000000000000000000000000000007d", + "0x0000000000000000000000000000000000000000000000000000000000000074", + "0x00000000000000000000000000000000000000000000000000000000000000ba", + "0x000000000000000000000000000000000000000000000000000000000000004d", + "0x000000000000000000000000000000000000000000000000000000000000006c", + "0x0000000000000000000000000000000000000000000000000000000000000089", + "0x0000000000000000000000000000000000000000000000000000000000000050", + "0x00000000000000000000000000000000000000000000000000000000000000fa", + "0x00000000000000000000000000000000000000000000000000000000000000b6", + "0x00000000000000000000000000000000000000000000000000000000000000e5", + "0x0000000000000000000000000000000000000000000000000000000000000040", + "0x00000000000000000000000000000000000000000000000469c11c149a312c0c", + "0x0000000000000000000000000000000000000000000000058d08d9bc9b9522ce", + "0x00000000000000000000000000000000000000000000000d41a73b047fccdc4e", + "0x000000000000000000000000000000000000000000000000000297ba5892d56f", + "0x00000000000000000000000000000000000000000000000d5a32f847928791d0", + "0x00000000000000000000000000000000000000000000000539240bd39e66e97d", + "0x0000000000000000000000000000000000000000000000061bcba96190f858f9", + "0x0000000000000000000000000000000000000000000000000002aa51f2e2c1cd", + "0x00000000000000000000000000000000000000000000000af0f401b233897958", + "0x000000000000000000000000000000000000000000000001f07f46005fedd8ff", + "0x0000000000000000000000000000000000000000000000021d1fa64a6b65e96a", + "0x000000000000000000000000000000000000000000000000000297763e518109", + "0x00000000000000000000000000000000000000000000000cff39d4cb22154230", + "0x00000000000000000000000000000000000000000000000be83ba2b60b87c0e7", + "0x00000000000000000000000000000000000000000000000d079cf5af8d9d724b", + "0x000000000000000000000000000000000000000000000000000055bfecc11f7e" +] diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/BaseHonkVerifier.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/BaseHonkVerifier.json new file mode 100644 index 0000000..ce30c04 --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/BaseHonkVerifier.json @@ -0,0 +1,55 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "BaseHonkVerifier", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/CommitmentSchemeLib.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/CommitmentSchemeLib.json new file mode 100644 index 0000000..51e871b --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/CommitmentSchemeLib.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "CommitmentSchemeLib", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/FrLib.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/FrLib.json new file mode 100644 index 0000000..f0879b1 --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/FrLib.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "FrLib", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HistoryProofVerifier.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HistoryProofVerifier.json new file mode 100644 index 0000000..2e802f9 --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HistoryProofVerifier.json @@ -0,0 +1,55 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "HistoryProofVerifier", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [ + { + "inputs": [], + "name": "ProofLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "PublicInputsLengthWrong", + "type": "error" + }, + { + "inputs": [], + "name": "ShpleminiFailed", + "type": "error" + }, + { + "inputs": [], + "name": "SumcheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60e0604052348015600f57600080fd5b5062100000608052601460a05261037f60c05260805160a05160c051615b8161005f60003960006105ea01526000818161069801528181610f9b0152611039015260006105910152615b816000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ea50d0e414610030575b600080fd5b61004361003e3660046156ba565b610057565b604051901515815260200160405180910390f35b60006100666101b860206157bc565b841461009e576040517fed74ac0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006100a8610207565b905060006100b6878761021c565b604083015190915084146100f6576040517ffa06659300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061010f8287878660000151876040015160016104ca565b905061015e86868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050845160608101516080909101519092509050600161057a565b815160a001526000610170838361068f565b9050806101a9576040517f9fc3a21800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101b68486856107af565b9050806101ef576040517fa5d82e8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8180156101f95750805b9a9950505050505050505050565b61020f614e2e565b6102176113c3565b905090565b6102246151e5565b61023a6102356080600085876157d3565b611ca9565b815261024e610235610100608085876157d3565b602082015261026661023561018061010085876157d3565b604082015261027e61023561020061018085876157d3565b60a082015261029661023561028061020085876157d3565b60c08201526102ae61023561030061028085876157d3565b60608201526102c661023561038061030085876157d3565b60e08201526102de61023561040061038085876157d3565b608082015261040060005b601c8110156103775760005b600881101561036e5761032186848761030f8260206157fd565b9261031c939291906157d3565b611dc6565b84610100015183601c811061033857610338615810565b6020020151826008811061034e5761034e615810565b60200201818152505060208361036491906157fd565b92506001016102f5565b506001016102e9565b5060005b60288110156103cc5761039585838661030f8260206157fd565b83610120015182602881106103ac576103ac615810565b6020020181815250506020826103c291906157fd565b915060010161037b565b5060005b6103dc6001601c61583f565b811015610432576104018583866103f48260806157fd565b92610235939291906157d3565b83610140015182601b811061041857610418615810565b60200201526104286080836157fd565b91506001016103d0565b5060005b601c8110156104875761045085838661030f8260206157fd565b83610160015182601c811061046757610467615810565b60200201818152505060208261047d91906157fd565b9150600101610436565b506104998482856103f48260806157fd565b6101808301526104aa8160806157fd565b90506104bd8482856103f48260806157fd565b6101a08301525092915050565b6104d2615400565b60006104e388888888888887611e46565b90835290506104f28189611ece565b602084019190915290506105058161206b565b6040840191909152905061051988826120ce565b6060840191909152905061052d88826121a5565b608084019190915290506105418882612233565b60a0840191909152905061055588826123a3565b60c084019190915290506105698882612417565b5060e0830152509695505050505050565b6000600180826105c4866105bf896105ba6105b58a7f00000000000000000000000000000000000000000000000000000000000000006157fd565b61246f565b6124a1565b6124ce565b905060006105e3876105de8a6105ba6105b58b60016157fd565b6124fb565b905060005b7f00000000000000000000000000000000000000000000000000000000000000008110156106775760006106348b838151811061062757610627615810565b602002602001015161246f565b9050610644866105ba86846124ce565b9550610654856105ba85846124ce565b9450610660848b6124ce565b935061066c838b6124fb565b9250506001016105e8565b506106828484612551565b9998505050505050505050565b6000806001815b7f000000000000000000000000000000000000000000000000000000000000000081101561078357600086610100015182601c81106106d7576106d7615810565b6020020151905060006106ea8286612560565b905080610723576040517f9fc3a21800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000876060015184601c811061073b5761073b615810565b6020020151905061074c838261257e565b9550610773886040015185601c811061076757610767615810565b60200201518683612732565b9450505050806001019050610696565b50600061079f866101200151866000015187602001518561275e565b90508281145b9695505050505050565b60006108006040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600061080f8460a001516127cd565b905061081961548e565b6108216154ad565b60e08601516108419061083c908560005b60200201516124fb565b612832565b60a085015260e08601516108619061083c908560005b60200201516124ce565b60c080860182905260a086015190880151610880926105bf91906124a1565b845260a08601516108ae9061089490612832565b6105ba8660a001516105de8a60c001518960c001516124a1565b6020858101919091526001835261018089015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091528152600160608501819052600060808601525b602381116109b85761093361092986600001516128c6565b86606001516124a1565b83826046811061094557610945615810565b602002015260808501516101208a015161098891906105bf9061096960018661583f565b6028811061097957610979615810565b602002015188606001516124a1565b8560800181815250506109a3856060015188608001516124a1565b60608601526109b181615852565b9050610911565b5060006109c7602360016157fd565b90505b60288111610a48576109e261092986602001516128c6565b8382604681106109f4576109f4615810565b602002015260808501516101208a0151610a1891906105bf9061096960018661583f565b856080018181525050610a33856060015188608001516124a1565b6060860152610a4181615852565b90506109ca565b50606087015181600160200201526080870151816002602002015260a0870151816003602002015260c0870151816004602002015260e0870151816005602002015261010087015181600660200201526101208701518160076020020152610140870151816008602002015261016087015181600960200201526101a087015181600a602002015261018087015181600b60200201526101c087015181600c60200201526101e087015181600d602002015261020087015181600e602002015261022087015181600f60200201526102408701518160106020020152610260870151816011602002015261028087015181601260200201526102a087015181601360200201526102c087015181601460200201526102e08701518160156020020152610300870151816016602002015261032087015181601760200201526103408701518160186020020152610360870151816019602002015261038087015181601a60200201526103a087015181601b60200201528751610c10906040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b61038082015260208881015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091526103a082015260408881015181518083018352600080825260209182015282518084018452818301518351608891821b178252606084015193909401519290931b909117908201526103c0820152606088810151604080518082018252600080825260209182015281518083018352818401518451608891821b1782529484015192909301519190931b17918101919091526103e08201526080880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261040082015260e0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261042082015260a0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261044082015260c0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b909117908201526104608201528751604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261048082015260208881015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091526104a082015260408881015181518083018352600080825260209182015282518084018452818301518351608891821b178252606084015193909401519290931b909117908201526104c0820152606088810151604080518082018252600080825260209182015281518083018352818401518451608891821b1782529484015192909301519190931b17918101919091526104e08201526080880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b90911790820152610500820152606086015160808501516101608a0151600092610fbf929091877f00000000000000000000000000000000000000000000000000000000000000006128f2565b805160a0870151919250610fd2916124a1565b604086018190526101608a01515160c089015161100292916105bf91610ff891906124a1565b8860c001516124a1565b604086015260c087015161101590612a10565b606086015260005b6110296001601c61583f565b81101561127457600061105d60017f000000000000000000000000000000000000000000000000000000000000000061583f565b8210159050806111d35761109061083c8a60e001518885600161108091906157fd565b601c811061083257610832615810565b60a088015260e08901516110be9061083c90886110ae8660016157fd565b601c811061085757610857615810565b60c0880152606087015160a08801516110d791906124a1565b60e0880152606087015160c08a01516110f391610ff8916124a1565b610100880181905261111590611108906128c6565b6105bf8960e001516128c6565b8583611123602860016157fd565b61112d91906157fd565b6046811061113d5761113d615810565b60200201526101008701516101608c015160009161117a916111608660016157fd565b601c811061117057611170615810565b60200201516124a1565b9050611196816105bf8a60e001518787600161116091906157fd565b90506111a68860400151826124ce565b6040890152606088015160c08b01516111cc916111c2916124a1565b8b60c001516124a1565b6060890152505b61123e8b610140015183601b81106111ed576111ed615810565b60200201516040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b848361124c602860016157fd565b61125691906157fd565b6046811061126657611266615810565b60200201525060010161101d565b5060408051808201909152600181526002602082015282611297601c60286157fd565b604681106112a7576112a7615810565b60200201526040850151836112be601c60286157fd565b604681106112ce576112ce615810565b60200201526101a089015160009061132c906040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b9050808361133c601c60286157fd565b6113479060016157fd565b6046811061135757611357615810565b602002015260e08801518461136e601c60286157fd565b6113799060016157fd565b6046811061138957611389615810565b6020020152600061139a8486612a1c565b905060006113a783612aef565b90506113b38282612b67565b9c9b505050505050505050505050565b6113cb614e2e565b50604080516103c081018252621000008152601460208083019190915261037f82840152825180840184527f028571c71a70ecafc36c647b367fd58fdc9f3f88754f8be87da4c26abd037f5881527f27863c1a0bbbe90f7d93d54c3ab59c9e7b353ce01e7410f4e3141b24a6d22947818301526060830152825180840184527f1b0200bd59d09643414f599544948720001793e9e33bd29d89f228c690d16b2281527f14e606c3291107ce8d7bec2383feeb2b2126398aec584c392bb30e48fc212fe5818301526080830152825180840184527f16da4e30fa9c5e532eccc50143ec6d2458b26239f6c7ffb01cc275e7df8d5e6b81527f11177adf1d7fe5d607386b626157161c2838bfc290191e468d16bf50078da97a8183015260a0830152825180840184527f0e05a8ae100929943ad202a84475ee441fabd1afd3f14eb93bebdf9b17687ba181527f2ae604f47e2685d7e4ea7e13788ff394bb7ad71f72e5a2d8c19b139e2013a1308183015260c0830152825180840184527f2178aed4f93ecddaa6f2e2eab9b970d8da6d2eb200a3e99ff8155712a0cf6b9281527f250fcab74ba6f0cbe128546a3ebac370812a5a54e9e9b9927daed028487d7a9e8183015260e0830152825180840184527f13016f6697daa5732a19a445de49aebddd5346b43650f9e1dcf4de9ef349a69181527f066c30afae78bed94cd6488b9e9d379cd6838a90137f9bde38774bb0a1d2cc2381830152610100830152825180840184527f11ffc2e16b5547e10db1dbbad2b77065ba7fdb98112f731c75dd3db9537b6bbe81527f22779b282581a25c87355af900c36c408edba710cccb93bce55a74e8ea56fe7081830152610120830152825180840184527f277367838217c76a234e0f06c00b5786cbd0456fffff9eb5043315afdb3ed9ef81527f279a27939c24d56c655d2ae10dc8e0ff493c962dc20162c20727d4bbfe0e709581830152610140830152825180840184527f1bacfa423fb1fbf07ad93f568e7c050dcb42ae40bce5d9770787cca283ad2a8281527f2f706a0c3e7712bb3e5015d0f57a8878237ccb892b2c57cb77daa5e47b5b587781830152610160830152825180840184527f227edd26972b15200568f901e51df33d51406314e859f36371691c1be968c08681527f0ff95bc17a3489f931fd530668a2329057da7ba1b813ef18283044188991ccd181830152610180830152825180840184527f0d7f307c9322ebe9e7f5614cb4bfb4bf3e9ed6ddeb181fef99a5e59e46c991e481527f1a01f6de8c329bc31fb60e7485385a358b08efb3ba886a3f177738a22fd3d64f818301526101a0830152825180840184527f0ece3c3c50faf554a93cd38e0804b6fac154e6375685a550fc8048f93501b38c81527f1d74548cd03cdbf504e187223c8c621184f09dac68ee72f870d0754f560f1e1a818301526101c0830152825180840184527f2ae7add8f634f4fe1b905a0a217c2a14c1719d08cf19a9b41e5c6b46813393b681527f2f2e0745881fbe47efb795573e26980793e9eeb38e4c753a98662c0ea46cda60818301526101e0830152825180840184527f143e1e54bafeab3f128b9451206fd144002d284afcb8fae4d35ca58bee3214c781527f13467341be44c277d3341aee031fe2f2b3425faddb3dfc09140f00e88bd7b84281830152610200830152825180840184527f2837c2375c3b85a3e51cfd55f9f464263b6c1bb5344cffba913d2bddc9aa482981527f2c4205b6240165815142723f427c2201ab0303fe1ea5c8207989e5964e77ec9581830152610220830152825180840184527f156f8c2e1a8d2e336190d06ebb302e7d945c7d8afffa00071154de9cd745ae9981527f0374f3069e2677f3a0a27097eed8919113b6f33fe2dbffc955a22ff5b7adffaa81830152610240830152825180840184527f15be80c4bf84770966d8c29859ea52bbfcb7d4fd671d32723807d7b7408ad8e381527f295cb30ee3ebdcff633e566ce60cc0976b3608bf83e50a4d834cdd7e99f5e99781830152610260830152825180840184527f01502386547bc313c6f2952ab504feb968716dab247d8279375bb055d3b458bc81527f1aea7d24ede4f9075e7df80da513cca3d2d9c8539ba12853bf087906107cb45781830152610280830152825180840184527f094b69f82c8afd0edab0fc4dd6231d0f99e41de35c42acef28d01dd329c511d881527f0eb9579f5ae5fc6772cf59bda9486ff76a8c7dcb5acbb9229022805e58ab1b44818301526102a0830152825180840184527f194ec606d18b3f74bee7143c4f12738b22d915cd5428ba133bc443f92733902581527f18bed5c7977467e3bb43c302e1480bd1b7061b6145dde0e60f462e94edd9d92f818301526102c0830152825180840184527f2259a9e38b616bdb7e9d79f793d77a8bf83041301fd6f7912d3812957a812b6181527f08cd81bdf2488d15482fab09e03941aae83460da851b02e9ec8e5b94e6c7e46f818301526102e0830152825180840184527f02fa6c1e772d4326a1b41dae0536309d58b8c72190b0103836c5c11594cceb3881527f2e3dfec902a316ddb0822d4a3f50a8f570a2efa5a11ca2f946daeb4ebc2851f181830152610300830152825180840184527f15f36fd35ab00a4f5488d568268b62a1a3b911e7e581c6273b5a6aed68d5ffbc81527f125e1fa454d9958f921944414bb3e94e06d3b748dbee6ac22a81c3a49e19bca981830152610320830152825180840184527f0a8d8881c8e7bbf87d37191fb3a8ef77e7abf7de04696a74d58293f8ab91c4cc81527f271274ed1b7d005bd5f87113856dd9841766913a2b1b8e9465b027d06a0c99bc81830152610340830152825180840184527f2770c1aa143acdf5f6e29ac2a15326f337cb57f57d10756d4c3fe1699021052781527e569125fa720db8dce31beab5160f8c6933f40e804977b288515686d6d6e16181830152610360830152825180840184526001815260028183015261038083015282518084019093527f050375219221fe68c1f9e5c3fed768de50bb1342a34f1a2948837176741dc01383527f1639e4ab4d1e100fbf57002222b74c97afb3de94a1ad0204b44cc64f84d04a93908301526103a081019190915290565b611cd46040518060800160405280600081526020016000815260200160008152602001600081525090565b60808214611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420627974657320706f696e740000000000000000000000000060448201526064015b60405180910390fd5b604080516080810190915280611d5d6020600086886157d3565b611d669161588a565b8152602090810190611d7c9060409086886157d3565b611d859161588a565b8152602001611d986060604086886157d3565b611da19161588a565b8152602001611db46080606086886157d3565b611dbd9161588a565b90529392505050565b600060208214611e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f696e76616c6964206279746573207363616c61720000000000000000000000006044820152606401611d3a565b611e3f6105b5838561588a565b9392505050565b611e7f6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611e8f898989898989612d7e565b604086019190915260208501919091529083529250611eae838a6131a9565b608085019190915260608401919091529199919850909650505050505050565b611ed66154e7565b6000611ee0615506565b84815260e0848101805151602080850191909152815181015160408086019190915282518101516060808701919091529251830151608080870191909152880180515160a0870152805183015160c08701528051820151948601949094529251909101516101008401529051611f7791611f5c918491016158c6565b6040516020818303038152906040528051906020012061246f565b9150611f8282613276565b6020850152835260015b611f986002601961592a565b81101561201857611fb583604051602001611f5c91815260200190565b9250611fc083613276565b85611fcc8460026157bc565b60198110611fdc57611fdc615810565b6020020186611fec8560026157bc565b611ff79060016157fd565b6019811061200757612007615810565b602002019190915252600101611f8c565b5061202f82604051602001611f5c91815260200190565b9150600061203c83613276565b856120496001601961583f565b6019811061205957612059615810565b60200201919091525050509250929050565b612073615525565b6000805b601c8110156120c75761209684604051602001611f5c91815260200190565b935060006120a385613276565b8584601c81106120b5576120b5615810565b60200201919091525050600101612077565b5090929050565b6120d6615525565b6000805b601c81101561219c576120eb615506565b84815260005b60088110156121555786610100015183601c811061211157612111615810565b6020020151816008811061212757612127615810565b6020020151826121388360016157fd565b6009811061214857612148615810565b60200201526001016120f1565b5061216a81604051602001611f5c91906158c6565b9450600061217786613276565b8685601c811061218957612189615810565b60200201919091525050506001016120da565b50909391925050565b6000806121b0615544565b83815260005b60288110156122045785610120015181602881106121d6576121d6615810565b6020020151826121e78360016157fd565b602981106121f7576121f7615810565b60200201526001016121b6565b5061221981604051602001611f5c919061593e565b9150600061222683613276565b5096929550919350505050565b60008061223e615563565b83815260005b6122506001601c61583f565b81101561238e5785610140015181601b811061226e5761226e615810565b602002015151826122808360046157bc565b61228b9060016157fd565b606d811061229b5761229b615810565b602002015261014086015181601b81106122b7576122b7615810565b602002015160200151828260046122ce91906157bc565b6122d99060026157fd565b606d81106122e9576122e9615810565b602002015261014086015181601b811061230557612305615810565b6020020151604001518261231a8360046157bc565b6123259060036157fd565b606d811061233557612335615810565b602002015261014086015181601b811061235157612351615810565b602002015160600151826123668360046157bc565b6123719060046157fd565b606d811061238157612381615810565b6020020152600101612244565b5061221981604051602001611f5c9190615973565b6000806123ae615582565b83815260005b601c8110156124025785610160015181601c81106123d4576123d4615810565b6020020151826123e58360016157fd565b601d81106123f5576123f5615810565b60200201526001016123b4565b5061221981604051602001611f5c91906159a8565b6000806124226155a1565b8381526101808501805151602080840191909152815181015160408085019190915282518101516060808601919091529251909201516080840152905161221991611f5c918491016159dd565b600061249b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183615a11565b92915050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018284099392505050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018284089392505050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001612548837f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b84089392505050565b6000611e3f836105ba84612832565b8151600090819061257390856001610857565b929092149392505050565b60408051610100810182527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526102d060208201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffff1191810191909152609060608201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffff71608082015260f060a08201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3160c08201526113b060e08201526000906001825b60088110156126665761265c826105ba87846124fb565b9150600101612645565b5061266f6155bf565b60005b60088110156126d257600084826008811061268f5761268f615810565b602002015190506126a4816105ba89856124fb565b90506126af81612832565b9050808383600881106126c4576126c4615810565b602002015250600101612672565b5060005b60088110156127275760008782600881106126f3576126f3615810565b602002015190506127108184846008811061117057611170615810565b905061271c86826124ce565b9550506001016126d6565b506107a584836124a1565b60008061274960016105bf856105ba8960016124fb565b905061275584826124a1565b95945050505050565b60006127686155de565b6127738682856132b0565b61277f86868386613461565b61278b8686838661364e565b612796868285613855565b6127a1868285613a47565b6127ad86868386613dac565b6127b88682856146b9565b6127c3868285614a95565b6107a58185614d97565b6127d5615525565b81815260015b601c81101561282c5761280d826127f360018461583f565b601c811061280357612803615810565b6020020151612a10565b8282601c811061281f5761281f615810565b60200201526001016127db565b50919050565b6000808290506000604051602081526020808201526020604082015282606082015260027f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010360808201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000160a08201526020600060c08360055afa9050806128ba57600080fd5b50506000519392505050565b600061249b827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b6128fa615525565b601c5b8015612a065760008461291160018461583f565b601c811061292157612921615810565b6020020151905060008861293660018561583f565b601c811061294657612946615810565b6020020151905060006129a261296661295f858c6124a1565b60026124a1565b6105de8a61297560018961583f565b601c811061298557612985615810565b60200201516105ba61299c886105ba60018a6124fb565b876124fb565b90506129c3816105ba61083c6129bd876105ba6001896124fb565b866124ce565b90508584116129f25797508780856129dc60018761583f565b601c81106129ec576129ec615810565b60200201525b505050806129ff90615a25565b90506128fd565b5095945050505050565b600061249b82836124a1565b60408051808201909152600080825260208201526000612a3e601c60286157fd565b612a499060026157fd565b90506001604051855151604082015285516020015160608201528451608082015260408160606040840160075afa8216915060015b83811015612ad75760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612a7e565b50805184526020810151602085015250505092915050565b60408051808201909152600080825260208201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782602001517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47612b54919061583f565b612b5e9190615a11565b60208301525090565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e5561018082015260009081906101a0016040516020818303038152906040529050600080600873ffffffffffffffffffffffffffffffffffffffff1683604051612d0c9190615a5a565b600060405180830381855afa9150503d8060008114612d47576040519150601f19603f3d011682016040523d82523d6000602084013e612d4c565b606091505b5091509150600081806020019051810190612d679190615a89565b9050828015612d735750805b979650505050505050565b600080808080612d8f8760036157fd565b612d9a90600c6157fd565b67ffffffffffffffff811115612db257612db2615aab565b604051908082528060200260200182016040528015612ddb578160200160208202803683370190505b5090508760001b81600081518110612df557612df5615810565b6020026020010181815250508660001b81600181518110612e1857612e18615810565b6020026020010181815250508560001b81600281518110612e3b57612e3b615810565b60200260200101818152505060005b87811015612e9c578a8a82818110612e6457612e64615810565b9050602002013582826003612e7991906157fd565b81518110612e8957612e89615810565b6020908102919091010152600101612e4a565b508a515181612eac8960036157fd565b81518110612ebc57612ebc615810565b6020908102919091018101919091528b51015181612edb8960036157fd565b612ee69060016157fd565b81518110612ef657612ef6615810565b60209081029190910101528a516040015181612f138960036157fd565b612f1e9060026157fd565b81518110612f2e57612f2e615810565b60209081029190910101528a516060015181612f4b8960036157fd565b612f569060036157fd565b81518110612f6657612f66615810565b6020908102919091018101919091528b01515181612f858960036157fd565b612f909060046157fd565b81518110612fa057612fa0615810565b6020908102919091018101919091528b810151015181612fc18960036157fd565b612fcc9060056157fd565b81518110612fdc57612fdc615810565b6020908102919091018101919091528b01516040015181612ffe8960036157fd565b6130099060066157fd565b8151811061301957613019615810565b6020908102919091018101919091528b0151606001518161303b8960036157fd565b6130469060076157fd565b8151811061305657613056615810565b602090810291909101015260408b015151816130738960036157fd565b61307e9060086157fd565b8151811061308e5761308e615810565b60209081029190910181019190915260408c01510151816130b08960036157fd565b6130bb9060096157fd565b815181106130cb576130cb615810565b60209081029190910101526040808c01510151816130ea8960036157fd565b6130f590600a6157fd565b8151811061310557613105615810565b602090810291909101015260408b015160600151816131258960036157fd565b61313090600b6157fd565b8151811061314057613140615810565b60200260200101818152505061316081604051602001611f5c9190615ada565b915061316b82613276565b60408051602081018690529297509095506131869101611f5c565b9150600061319383613276565b50959c949b509499509097509195505050505050565b60008060006131b66155fd565b85815260a0858101805151602080850191909152815181015160408086019190915282518101516060808701919091529251830151608086015260c0808a0180515195870195909552845183015190860152835181015160e08601529251820151610100850152818801805151610120860152805182015161014086015280518401516101608601525190910151610180840152905161325c91611f5c91849101615b10565b915061326782613276565b90979096509194509092505050565b600080826fffffffffffffffffffffffffffffffff8116608082901c61329b8261246f565b94506132a68161246f565b9350505050915091565b60006132bd846007614dfd565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000600061332061331a6132f38560036124fb565b6105ba61330f6133048b6000614dfd565b6105ba8c601c614dfd565b6105ba8b601b614dfd565b836124a1565b90506133a161339661337d61336461334b856105bf6133408d6002614dfd565b6105ba8e601b614dfd565b6105bf6133598c6003614dfd565b6105ba8d601c614dfd565b6105bf6133728b6004614dfd565b6105ba8c601d614dfd565b6105bf61338b8a6005614dfd565b6105ba8b601e614dfd565b6105bf886001614dfd565b90506133c0816105bf6133b58660016124fb565b6105ba8a6026614dfd565b90506133cc81846124a1565b90506133d881856124a1565b855250600090506134146134096133fe6133f388601b614dfd565b6105bf89601e614dfd565b6105de886023614dfd565b6105bf876000614dfd565b9050613425816105ba8460026124fb565b9050613436816105ba8460016124fb565b905061344281836124a1565b905061344e81846124a1565b9050808460015b60200201525050505050565b600080600061349961348f61347789601b614dfd565b6105bf6134858b6011614dfd565b8a606001516124a1565b87608001516124ce565b90506134d2816105ba6134c86134b08b601c614dfd565b6105bf6134be8d6012614dfd565b8c606001516124a1565b89608001516124ce565b90506134f7816105ba6134c86134e98b601d614dfd565b6105bf6134be8d6013614dfd565b905061351c816105ba6134c861350e8b601e614dfd565b6105bf6134be8d6014614dfd565b92506000905061354161348f61353389601b614dfd565b6105bf6134858b600d614dfd565b9050613566816105ba6134c86135588b601c614dfd565b6105bf6134be8d600e614dfd565b905061358b816105ba6134c861357d8b601d614dfd565b6105bf6134be8d600f614dfd565b90506135b0816105ba6134c86135a28b601e614dfd565b6105bf6134be8d6010614dfd565b9150600090506135d86135d26135c789601f614dfd565b6105bf8a6019614dfd565b846124a1565b905061360d816105de6136076135ef8b6027614dfd565b6105bf6135fd8d601a614dfd565b8c60a001516124a1565b856124a1565b905061361981856124a1565b604086015250600061363d61360761363289601a614dfd565b6105ba8a6027614dfd565b606090950194909452505050505050565b6000806136ad61369561367d6136686134c88a6015614dfd565b6105bf6136768b6016614dfd565b8a516124a1565b6105bf61368b8a6017614dfd565b89602001516124a1565b6105bf6136a3896018614dfd565b88604001516124a1565b915060006136e56136cc6136c289601b614dfd565b88608001516124ce565b6105bf6136da8a6003614dfd565b6105ba8b6023614dfd565b905060006137106136f789601c614dfd565b6105bf6137058b6000614dfd565b6105ba8c6024614dfd565b9050600061373b6137228a601d614dfd565b6105bf6137308c6001614dfd565b6105ba8d6025614dfd565b905061377b613763613755856105bf868d600001516124a1565b6105bf848c602001516124a1565b6105bf6137718c6004614dfd565b8b604001516124a1565b935050505060006137906135d2886020614dfd565b905060006137a26135d2896020614dfd565b905060006137db6137c26137b78b6022614dfd565b6105bf8c6006614dfd565b6105de6137d08c6022614dfd565b6105ba8d6006614dfd565b905060006138006137fa6137ef87896124a1565b6105ba8d6020614dfd565b836124fb565b905061380c81886124a1565b905060006138356138276138218d6006614dfd565b876124a1565b6105de6138218e6021614dfd565b60808a018390529050808960055b60200201525050505050505050505050565b6000613863600060016124fb565b90506000613873600060026124fb565b90506000613883600060036124fb565b905060006138a061389588601c614dfd565b6105de89601b614dfd565b905060006138bd6138b289601d614dfd565b6105de8a601c614dfd565b905060006138da6138cf8a601e614dfd565b6105de8b601d614dfd565b905060006138f76138ec8b6023614dfd565b6105de8c601e614dfd565b905083613908816105ba818b6124ce565b9050613918816105ba878a6124ce565b9050613928816105ba87896124ce565b9050613939816105ba8d6008614dfd565b9050613945818a6124a1565b60c08b0152508261395a816105ba818b6124ce565b905061396a816105ba868a6124ce565b905061397a816105ba86896124ce565b905061398b816105ba8d6008614dfd565b9050613997818a6124a1565b60e08b015250816139ac816105ba818b6124ce565b90506139bc816105ba858a6124ce565b90506139cc816105ba85896124ce565b90506139dd816105ba8d6008614dfd565b90506139e9818a6124a1565b6101008b015250806139ff816105ba818b6124ce565b9050613a0f816105ba848a6124ce565b9050613a1f816105ba84896124ce565b9050613a30816105ba8d6008614dfd565b9050613a3c818a6124a1565b9050808a6009613843565b613a876040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613a9284601c614dfd565b8152613a9f84601d614dfd565b6020820152613aaf846023614dfd565b6040820152613abf846026614dfd565b6060820152613acf846025614dfd565b6080820152613adf846024614dfd565b60a08201526000613af1856002614dfd565b90506000613b00866000614dfd565b90506000613b16846040015185600001516124fb565b90506000613b2c856020015186602001516124a1565b60608601519091508690600090613b4390806124a1565b90506000613b62613b5c89602001518a606001516124a1565b886124a1565b90506000613b82613b7b8a60a001518b604001516124ce565b8a516124ce565b9050613b9161382182886124a1565b9050613bb8613bb2613bac613ba684876124fb565b886124fb565b846124ce565b836124ce565b9050613be0613bd5613bca83876124a1565b6105ba8f6009614dfd565b6105ba60018a6124fb565b6101408c01525050505060208501516080860151600091613c00916124ce565b90506000613c1f613c158860600151886124a1565b88602001516124fb565b90506000613c45613c3084876124a1565b6105bf6136078b60a001518c600001516124fb565b9050613c6d613c62613c57838c6124a1565b6105ba8e6009614dfd565b6105ba6001896124fb565b6101608b01525060009150613c8f9050613c888360116124ce565b87516124a1565b90506000613c9d83846124ce565b9050613ca981826124ce565b90506000613cb88360096124a1565b9050613ce2613cdc6135d2613cd58b60a001518c600001516124ce565b8b516124ce565b826124fb565b60c08901819052600090613cfe90613b5c90613bca908d6124a1565b9050613d118b600a6020020151826124ce565b6101408c01525050865160009250613d399150613c8890613d3290806124ce565b88516124ce565b90506000613d7b613d56836105ba8a600001518b60a001516124fb565b60208901516105de90613d6990806124ce565b6105ba8b602001518c608001516124ce565b9050613d9889600b60200201516105bf613b5c613bca858d6124a1565b89600b602002015250505050505050505050565b613e56604051806102c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613e8b613e72613e6787601b614dfd565b6105ba886024614dfd565b6105bf613e80886023614dfd565b6105ba89601c614dfd565b8152613ed0613ec5613eac613ea188601b614dfd565b6105ba89601e614dfd565b6105bf613eba89601c614dfd565b6105ba8a601d614dfd565b6105de876025614dfd565b60408201819052613eea90681000000000000000006124a1565b60408201819052613f00906105de876026614dfd565b604082018190528151613f1391906124ce565b60408201819052613f29906105ba876005614dfd565b60408201528051613f4390681000000000000000006124a1565b808252613f63906105bf613f58886023614dfd565b6105ba896024614dfd565b80825260208201819052613f7f906105de6133f388601d614dfd565b60208201819052613f95906105ba876004614dfd565b6020820152805160608201819052613fb2906105bf87601e614dfd565b60608201819052613fd6906105de613fcb886025614dfd565b6105bf896026614dfd565b60608201819052613fec906105ba876000614dfd565b816060018181525050600061401661400c836020015184604001516124ce565b83606001516124ce565b9050614027816105ba886003614dfd565b905061403f614037876024614dfd565b6140006124a1565b60808301819052614055906105bf886023614dfd565b60808301819052614068906140006124a1565b6080830181905261407e906105bf88601d614dfd565b60808301819052614091906140006124a1565b608083018190526140a7906105bf88601c614dfd565b608083018190526140ba906140006124a1565b608083018190526140d0906105bf88601b614dfd565b608083018190526140e6906105de88601e614dfd565b608083018190526140fc906105ba886005614dfd565b608083015261410f614037876025614dfd565b60a08301819052614125906105bf886024614dfd565b60a08301819052614138906140006124a1565b60a0830181905261414e906105bf886023614dfd565b60a08301819052614161906140006124a1565b60a08301819052614177906105bf88601e614dfd565b60a0830181905261418a906140006124a1565b60a083018190526141a0906105bf88601d614dfd565b60a083018190526141b6906105de886026614dfd565b60a083018190526141cc906105ba886000614dfd565b60a0830181905260808301516000916141e591906124ce565b90506141f6816105ba896004614dfd565b905061421061420688601d614dfd565b87604001516124a1565b60c08401819052614229906105bf61368b8a601c614dfd565b60c08401819052614249906105bf6142428a601b614dfd565b89516124a1565b60c0840181905261425f906105bf896001614dfd565b60c0840181905260e0840181905261427c906105de89601e614dfd565b60c084015261428f613895886023614dfd565b6101408401526142ae6142a3886026614dfd565b6105de89601e614dfd565b6101208401526101408301516142d3906142c890806124a1565b8461014001516124fb565b6102808401526101408301516143289061431d90614316906105ba60017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b60016124ce565b8461012001516124a1565b610160840181905261435f90614351906105ba6143468b6002614dfd565b6105ba8c6003614dfd565b6105ba6138218a600a614dfd565b6101a086015261028083015161438190614351906105ba6143468b6002614dfd565b6101c086015260c08301516143a9906105ba61439e8a6002614dfd565b6105ba8b6003614dfd565b6101e084015260006143c96143bf89601e614dfd565b8560e001516124fb565b90506143d8613cdc82836124a1565b6101a08501526143ec6136a3896025614dfd565b6101008501819052614410906105bf6144068b6024614dfd565b8a602001516124a1565b610100850181905261442a906105bf6136768b6023614dfd565b61010085015261444961443e896026614dfd565b8561010001516124fb565b610100850152600061445f6138cf8a6025614dfd565b90506144d96144a061331a61431688610140015160017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016105ba919061583f565b6105ba61431688610100015160017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016105ba919061583f565b6101808601526101008501516144fe906144f390806124a1565b8661010001516124fb565b6101c08601526101808501516145319061451d906105ba8c6007614dfd565b6105ba61452b8c600a614dfd565b896124a1565b6101e08801526102808501516145509061451d906105ba8c6007614dfd565b6102008801526101c085015161456f9061451d906105ba8c6007614dfd565b6102208801526101a085015161458a906105ba8b6007614dfd565b6102008601526145a961459e8a6024614dfd565b6105de8b601c614dfd565b6102208601526101408501516145fb906138cf906145f090614316906105ba60017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b8761022001516124a1565b61024086018190526101e08601516102608701819052614632916105bf906105ba6146278e6005614dfd565b6105ba8f6002614dfd565b610260860181905260c086015161465691906105bf906105ba6146278e6000614dfd565b610260860181905261020086015161466e91906124ce565b610260860181905261468490613bac90866124ce565b6102a0860181905261469e906105ba61452b8c600a614dfd565b6102a0860181905287600c6020020152505050505050505050565b61474060405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61475961474e85601b614dfd565b6105bf866002614dfd565b815261477461476985601c614dfd565b6105bf866003614dfd565b602082015261479261478785601d614dfd565b6105bf866004614dfd565b60408201526147b06147a585601e614dfd565b6105bf866005614dfd565b606082015280516147e2906147db906147d4906147cd90806124a1565b84516124a1565b83516124a1565b82516124a1565b60808201526020810151614820906148169061480c9061480290806124a1565b84602001516124a1565b83602001516124a1565b82602001516124a1565b60a0820152604081015161485e906148549061484a9061484090806124a1565b84604001516124a1565b83604001516124a1565b82604001516124a1565b60c0820152606081015161489c90614892906148889061487e90806124a1565b84606001516124a1565b83606001516124a1565b82606001516124a1565b60e0820152608081015160a08201516148b591906124ce565b61010082015260c081015160e08201516148cf91906124ce565b61012082015260a08101516148f3906148e890806124ce565b8261012001516124ce565b61014082015260e08101516149179061490c90806124ce565b8261010001516124ce565b61016082015261012081015161492d90806124ce565b6101e0820181905261494e9061494390806124ce565b8261016001516124ce565b6101e082015261010081015161496490806124ce565b6101a082018190526149859061497a90806124ce565b8261014001516124ce565b6101a0820181905261016082015161499c916124ce565b6101808201526101408101516101e08201516149b891906124ce565b6101c08201526149cc61331a85600b614dfd565b61020082018190526102408401516101808301516149f7926105bf916105ba906105de8a6023614dfd565b8360126020020152614a2783601360200201516105bf8361020001516105ba856101a001516105de8a6024614dfd565b8360136020020152614a5783601460200201516105bf8361020001516105ba856101c001516105de8a6025614dfd565b8360146020020152614a8783601560200201516105bf8361020001516105ba856101e001516105de8a6026614dfd565b836015602002015250505050565b614af260405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006040518060800160405280614b287f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e761246f565b8152602001614b567f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b61246f565b8152602001614b837e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac1561246f565b8152602001614bb17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b61246f565b90529050614bce614bc386601b614dfd565b6105bf876002614dfd565b6101208301819052614c0290614bf79061431d90614bec90806124a1565b8561012001516124a1565b8361012001516124a1565b8252614c0f85601c614dfd565b6020830152614c1f85601d614dfd565b6040830152614c2f85601e614dfd565b606083015281516020830151614c579161400c91614c4d91906124ce565b84604001516124ce565b6080830152614c6a6135d286600c614dfd565b6101408301528151614c8c90614c8290836000611170565b83608001516124ce565b60a0830152614cb884601660200201516105bf8461014001516105ba8660a001516105de8b6023614dfd565b6102c08501526020820151614cd390614c8290836001611170565b60c0830152614cff84601760200201516105bf8461014001516105ba8660c001516105de8b6024614dfd565b6102e08501526040820151614d1a90614c8290836002611170565b60e0830152614d4684601860200201516105bf8461014001516105ba8660e001516105de8b6025614dfd565b6103008501526060820151614d6190614c8290836003611170565b610100830152614d8f84601960200201516105bf8461014001516105ba8661010001516105de8b6026614dfd565b846019613455565b6000614da4818481610857565b905060015b601a811015614df657614dec826105bf8684601a8110614dcb57614dcb615810565b602002015186614ddc60018761583f565b6019811061117057611170615810565b9150600101614da9565b5092915050565b600082826027811115614e1257614e12615b45565b60288110614e2257614e22615810565b60200201519392505050565b604051806103c00160405280600081526020016000815260200160008152602001614e6c604051806040016040528060008152602001600081525090565b8152602001614e8e604051806040016040528060008152602001600081525090565b8152602001614eb0604051806040016040528060008152602001600081525090565b8152602001614ed2604051806040016040528060008152602001600081525090565b8152602001614ef4604051806040016040528060008152602001600081525090565b8152602001614f16604051806040016040528060008152602001600081525090565b8152602001614f38604051806040016040528060008152602001600081525090565b8152602001614f5a604051806040016040528060008152602001600081525090565b8152602001614f7c604051806040016040528060008152602001600081525090565b8152602001614f9e604051806040016040528060008152602001600081525090565b8152602001614fc0604051806040016040528060008152602001600081525090565b8152602001614fe2604051806040016040528060008152602001600081525090565b8152602001615004604051806040016040528060008152602001600081525090565b8152602001615026604051806040016040528060008152602001600081525090565b8152602001615048604051806040016040528060008152602001600081525090565b815260200161506a604051806040016040528060008152602001600081525090565b815260200161508c604051806040016040528060008152602001600081525090565b81526020016150ae604051806040016040528060008152602001600081525090565b81526020016150d0604051806040016040528060008152602001600081525090565b81526020016150f2604051806040016040528060008152602001600081525090565b8152602001615114604051806040016040528060008152602001600081525090565b8152602001615136604051806040016040528060008152602001600081525090565b8152602001615158604051806040016040528060008152602001600081525090565b815260200161517a604051806040016040528060008152602001600081525090565b815260200161519c604051806040016040528060008152602001600081525090565b81526020016151be604051806040016040528060008152602001600081525090565b81526020016151e0604051806040016040528060008152602001600081525090565b905290565b604051806101c0016040528061521c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161524c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161527c6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016152ac6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016152dc6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161530c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161533c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161536c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161537961561c565b815260200161538661564a565b8152602001615393615669565b81526020016153a0615525565b81526020016153d06040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016151e06040518060800160405280600081526020016000815260200160008152602001600081525090565b6040518061010001604052806154456040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016154526154e7565b815260200161545f615525565b815260200161546c615525565b8152602001600081526020016000815260200160008152602001600081525090565b604051806108c001604052806046906020820280368337509192915050565b604051806108c001604052806046905b60408051808201909152600080825260208201528152602001906001900390816154bd5790505090565b6040518061032001604052806019906020820280368337509192915050565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518061052001604052806029906020820280368337509192915050565b60405180610da00160405280606d906020820280368337509192915050565b604051806103a00160405280601d906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b6040518061010001604052806008906020820280368337509192915050565b604051806103400160405280601a906020820280368337509192915050565b604051806101a00160405280600d906020820280368337509192915050565b604051806103800160405280601c905b6156346155bf565b81526020019060019003908161562c5790505090565b6040518061050001604052806028906020820280368337509192915050565b604051806103600160405280601b905b6156a46040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816156795790505090565b600080600080604085870312156156d057600080fd5b843567ffffffffffffffff8111156156e757600080fd5b8501601f810187136156f857600080fd5b803567ffffffffffffffff81111561570f57600080fd5b87602082840101111561572157600080fd5b60209182019550935085013567ffffffffffffffff81111561574257600080fd5b8501601f8101871361575357600080fd5b803567ffffffffffffffff81111561576a57600080fd5b8760208260051b840101111561577f57600080fd5b949793965060200194505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761249b5761249b61578d565b600080858511156157e357600080fd5b838611156157f057600080fd5b5050820193919092039150565b8082018082111561249b5761249b61578d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561249b5761249b61578d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036158835761588361578d565b5060010190565b8035602083101561249b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60008183825b60098110156158eb5781518352602092830192909101906001016158cc565b5050506101208201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615939576159396158fb565b500490565b60008183825b6029811015615963578151835260209283019290910190600101615944565b5050506105208201905092915050565b60008183825b606d811015615998578151835260209283019290910190600101615979565b505050610da08201905092915050565b60008183825b601d8110156159cd5781518352602092830192909101906001016159ae565b5050506103a08201905092915050565b60008183825b6005811015615a025781518352602092830192909101906001016159e3565b50505060a08201905092915050565b600082615a2057615a206158fb565b500690565b600081615a3457615a3461578d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b6000825160005b81811015615a7b5760208186018101518583015201615a61565b506000920191825250919050565b600060208284031215615a9b57600080fd5b81518015158114611e3f57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8151600090829060208501835b82811015615b05578151845260209384019390910190600101615ae7565b509195945050505050565b60008183825b600d811015615b35578151835260209283019290910190600101615b16565b5050506101a08201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063ea50d0e414610030575b600080fd5b61004361003e3660046156ba565b610057565b604051901515815260200160405180910390f35b60006100666101b860206157bc565b841461009e576040517fed74ac0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006100a8610207565b905060006100b6878761021c565b604083015190915084146100f6576040517ffa06659300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061010f8287878660000151876040015160016104ca565b905061015e86868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050845160608101516080909101519092509050600161057a565b815160a001526000610170838361068f565b9050806101a9576040517f9fc3a21800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101b68486856107af565b9050806101ef576040517fa5d82e8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8180156101f95750805b9a9950505050505050505050565b61020f614e2e565b6102176113c3565b905090565b6102246151e5565b61023a6102356080600085876157d3565b611ca9565b815261024e610235610100608085876157d3565b602082015261026661023561018061010085876157d3565b604082015261027e61023561020061018085876157d3565b60a082015261029661023561028061020085876157d3565b60c08201526102ae61023561030061028085876157d3565b60608201526102c661023561038061030085876157d3565b60e08201526102de61023561040061038085876157d3565b608082015261040060005b601c8110156103775760005b600881101561036e5761032186848761030f8260206157fd565b9261031c939291906157d3565b611dc6565b84610100015183601c811061033857610338615810565b6020020151826008811061034e5761034e615810565b60200201818152505060208361036491906157fd565b92506001016102f5565b506001016102e9565b5060005b60288110156103cc5761039585838661030f8260206157fd565b83610120015182602881106103ac576103ac615810565b6020020181815250506020826103c291906157fd565b915060010161037b565b5060005b6103dc6001601c61583f565b811015610432576104018583866103f48260806157fd565b92610235939291906157d3565b83610140015182601b811061041857610418615810565b60200201526104286080836157fd565b91506001016103d0565b5060005b601c8110156104875761045085838661030f8260206157fd565b83610160015182601c811061046757610467615810565b60200201818152505060208261047d91906157fd565b9150600101610436565b506104998482856103f48260806157fd565b6101808301526104aa8160806157fd565b90506104bd8482856103f48260806157fd565b6101a08301525092915050565b6104d2615400565b60006104e388888888888887611e46565b90835290506104f28189611ece565b602084019190915290506105058161206b565b6040840191909152905061051988826120ce565b6060840191909152905061052d88826121a5565b608084019190915290506105418882612233565b60a0840191909152905061055588826123a3565b60c084019190915290506105698882612417565b5060e0830152509695505050505050565b6000600180826105c4866105bf896105ba6105b58a7f00000000000000000000000000000000000000000000000000000000000000006157fd565b61246f565b6124a1565b6124ce565b905060006105e3876105de8a6105ba6105b58b60016157fd565b6124fb565b905060005b7f00000000000000000000000000000000000000000000000000000000000000008110156106775760006106348b838151811061062757610627615810565b602002602001015161246f565b9050610644866105ba86846124ce565b9550610654856105ba85846124ce565b9450610660848b6124ce565b935061066c838b6124fb565b9250506001016105e8565b506106828484612551565b9998505050505050505050565b6000806001815b7f000000000000000000000000000000000000000000000000000000000000000081101561078357600086610100015182601c81106106d7576106d7615810565b6020020151905060006106ea8286612560565b905080610723576040517f9fc3a21800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000876060015184601c811061073b5761073b615810565b6020020151905061074c838261257e565b9550610773886040015185601c811061076757610767615810565b60200201518683612732565b9450505050806001019050610696565b50600061079f866101200151866000015187602001518561275e565b90508281145b9695505050505050565b60006108006040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600061080f8460a001516127cd565b905061081961548e565b6108216154ad565b60e08601516108419061083c908560005b60200201516124fb565b612832565b60a085015260e08601516108619061083c908560005b60200201516124ce565b60c080860182905260a086015190880151610880926105bf91906124a1565b845260a08601516108ae9061089490612832565b6105ba8660a001516105de8a60c001518960c001516124a1565b6020858101919091526001835261018089015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091528152600160608501819052600060808601525b602381116109b85761093361092986600001516128c6565b86606001516124a1565b83826046811061094557610945615810565b602002015260808501516101208a015161098891906105bf9061096960018661583f565b6028811061097957610979615810565b602002015188606001516124a1565b8560800181815250506109a3856060015188608001516124a1565b60608601526109b181615852565b9050610911565b5060006109c7602360016157fd565b90505b60288111610a48576109e261092986602001516128c6565b8382604681106109f4576109f4615810565b602002015260808501516101208a0151610a1891906105bf9061096960018661583f565b856080018181525050610a33856060015188608001516124a1565b6060860152610a4181615852565b90506109ca565b50606087015181600160200201526080870151816002602002015260a0870151816003602002015260c0870151816004602002015260e0870151816005602002015261010087015181600660200201526101208701518160076020020152610140870151816008602002015261016087015181600960200201526101a087015181600a602002015261018087015181600b60200201526101c087015181600c60200201526101e087015181600d602002015261020087015181600e602002015261022087015181600f60200201526102408701518160106020020152610260870151816011602002015261028087015181601260200201526102a087015181601360200201526102c087015181601460200201526102e08701518160156020020152610300870151816016602002015261032087015181601760200201526103408701518160186020020152610360870151816019602002015261038087015181601a60200201526103a087015181601b60200201528751610c10906040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b61038082015260208881015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091526103a082015260408881015181518083018352600080825260209182015282518084018452818301518351608891821b178252606084015193909401519290931b909117908201526103c0820152606088810151604080518082018252600080825260209182015281518083018352818401518451608891821b1782529484015192909301519190931b17918101919091526103e08201526080880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261040082015260e0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261042082015260a0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261044082015260c0880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b909117908201526104608201528751604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b9091179082015261048082015260208881015160408051808201825260008082529084015280518082018252828401518351608891821b178252606084015192909301519190921b17918101919091526104a082015260408881015181518083018352600080825260209182015282518084018452818301518351608891821b178252606084015193909401519290931b909117908201526104c0820152606088810151604080518082018252600080825260209182015281518083018352818401518451608891821b1782529484015192909301519190931b17918101919091526104e08201526080880151604080518082018252600080825260209182015281518083018352818401518451608891821b178252606085015193909401519290931b90911790820152610500820152606086015160808501516101608a0151600092610fbf929091877f00000000000000000000000000000000000000000000000000000000000000006128f2565b805160a0870151919250610fd2916124a1565b604086018190526101608a01515160c089015161100292916105bf91610ff891906124a1565b8860c001516124a1565b604086015260c087015161101590612a10565b606086015260005b6110296001601c61583f565b81101561127457600061105d60017f000000000000000000000000000000000000000000000000000000000000000061583f565b8210159050806111d35761109061083c8a60e001518885600161108091906157fd565b601c811061083257610832615810565b60a088015260e08901516110be9061083c90886110ae8660016157fd565b601c811061085757610857615810565b60c0880152606087015160a08801516110d791906124a1565b60e0880152606087015160c08a01516110f391610ff8916124a1565b610100880181905261111590611108906128c6565b6105bf8960e001516128c6565b8583611123602860016157fd565b61112d91906157fd565b6046811061113d5761113d615810565b60200201526101008701516101608c015160009161117a916111608660016157fd565b601c811061117057611170615810565b60200201516124a1565b9050611196816105bf8a60e001518787600161116091906157fd565b90506111a68860400151826124ce565b6040890152606088015160c08b01516111cc916111c2916124a1565b8b60c001516124a1565b6060890152505b61123e8b610140015183601b81106111ed576111ed615810565b60200201516040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b848361124c602860016157fd565b61125691906157fd565b6046811061126657611266615810565b60200201525060010161101d565b5060408051808201909152600181526002602082015282611297601c60286157fd565b604681106112a7576112a7615810565b60200201526040850151836112be601c60286157fd565b604681106112ce576112ce615810565b60200201526101a089015160009061132c906040805180820190915260008082526020820152604051806040016040528060888460200151901b846000015117815260200160888460600151901b8460400151178152509050919050565b9050808361133c601c60286157fd565b6113479060016157fd565b6046811061135757611357615810565b602002015260e08801518461136e601c60286157fd565b6113799060016157fd565b6046811061138957611389615810565b6020020152600061139a8486612a1c565b905060006113a783612aef565b90506113b38282612b67565b9c9b505050505050505050505050565b6113cb614e2e565b50604080516103c081018252621000008152601460208083019190915261037f82840152825180840184527f028571c71a70ecafc36c647b367fd58fdc9f3f88754f8be87da4c26abd037f5881527f27863c1a0bbbe90f7d93d54c3ab59c9e7b353ce01e7410f4e3141b24a6d22947818301526060830152825180840184527f1b0200bd59d09643414f599544948720001793e9e33bd29d89f228c690d16b2281527f14e606c3291107ce8d7bec2383feeb2b2126398aec584c392bb30e48fc212fe5818301526080830152825180840184527f16da4e30fa9c5e532eccc50143ec6d2458b26239f6c7ffb01cc275e7df8d5e6b81527f11177adf1d7fe5d607386b626157161c2838bfc290191e468d16bf50078da97a8183015260a0830152825180840184527f0e05a8ae100929943ad202a84475ee441fabd1afd3f14eb93bebdf9b17687ba181527f2ae604f47e2685d7e4ea7e13788ff394bb7ad71f72e5a2d8c19b139e2013a1308183015260c0830152825180840184527f2178aed4f93ecddaa6f2e2eab9b970d8da6d2eb200a3e99ff8155712a0cf6b9281527f250fcab74ba6f0cbe128546a3ebac370812a5a54e9e9b9927daed028487d7a9e8183015260e0830152825180840184527f13016f6697daa5732a19a445de49aebddd5346b43650f9e1dcf4de9ef349a69181527f066c30afae78bed94cd6488b9e9d379cd6838a90137f9bde38774bb0a1d2cc2381830152610100830152825180840184527f11ffc2e16b5547e10db1dbbad2b77065ba7fdb98112f731c75dd3db9537b6bbe81527f22779b282581a25c87355af900c36c408edba710cccb93bce55a74e8ea56fe7081830152610120830152825180840184527f277367838217c76a234e0f06c00b5786cbd0456fffff9eb5043315afdb3ed9ef81527f279a27939c24d56c655d2ae10dc8e0ff493c962dc20162c20727d4bbfe0e709581830152610140830152825180840184527f1bacfa423fb1fbf07ad93f568e7c050dcb42ae40bce5d9770787cca283ad2a8281527f2f706a0c3e7712bb3e5015d0f57a8878237ccb892b2c57cb77daa5e47b5b587781830152610160830152825180840184527f227edd26972b15200568f901e51df33d51406314e859f36371691c1be968c08681527f0ff95bc17a3489f931fd530668a2329057da7ba1b813ef18283044188991ccd181830152610180830152825180840184527f0d7f307c9322ebe9e7f5614cb4bfb4bf3e9ed6ddeb181fef99a5e59e46c991e481527f1a01f6de8c329bc31fb60e7485385a358b08efb3ba886a3f177738a22fd3d64f818301526101a0830152825180840184527f0ece3c3c50faf554a93cd38e0804b6fac154e6375685a550fc8048f93501b38c81527f1d74548cd03cdbf504e187223c8c621184f09dac68ee72f870d0754f560f1e1a818301526101c0830152825180840184527f2ae7add8f634f4fe1b905a0a217c2a14c1719d08cf19a9b41e5c6b46813393b681527f2f2e0745881fbe47efb795573e26980793e9eeb38e4c753a98662c0ea46cda60818301526101e0830152825180840184527f143e1e54bafeab3f128b9451206fd144002d284afcb8fae4d35ca58bee3214c781527f13467341be44c277d3341aee031fe2f2b3425faddb3dfc09140f00e88bd7b84281830152610200830152825180840184527f2837c2375c3b85a3e51cfd55f9f464263b6c1bb5344cffba913d2bddc9aa482981527f2c4205b6240165815142723f427c2201ab0303fe1ea5c8207989e5964e77ec9581830152610220830152825180840184527f156f8c2e1a8d2e336190d06ebb302e7d945c7d8afffa00071154de9cd745ae9981527f0374f3069e2677f3a0a27097eed8919113b6f33fe2dbffc955a22ff5b7adffaa81830152610240830152825180840184527f15be80c4bf84770966d8c29859ea52bbfcb7d4fd671d32723807d7b7408ad8e381527f295cb30ee3ebdcff633e566ce60cc0976b3608bf83e50a4d834cdd7e99f5e99781830152610260830152825180840184527f01502386547bc313c6f2952ab504feb968716dab247d8279375bb055d3b458bc81527f1aea7d24ede4f9075e7df80da513cca3d2d9c8539ba12853bf087906107cb45781830152610280830152825180840184527f094b69f82c8afd0edab0fc4dd6231d0f99e41de35c42acef28d01dd329c511d881527f0eb9579f5ae5fc6772cf59bda9486ff76a8c7dcb5acbb9229022805e58ab1b44818301526102a0830152825180840184527f194ec606d18b3f74bee7143c4f12738b22d915cd5428ba133bc443f92733902581527f18bed5c7977467e3bb43c302e1480bd1b7061b6145dde0e60f462e94edd9d92f818301526102c0830152825180840184527f2259a9e38b616bdb7e9d79f793d77a8bf83041301fd6f7912d3812957a812b6181527f08cd81bdf2488d15482fab09e03941aae83460da851b02e9ec8e5b94e6c7e46f818301526102e0830152825180840184527f02fa6c1e772d4326a1b41dae0536309d58b8c72190b0103836c5c11594cceb3881527f2e3dfec902a316ddb0822d4a3f50a8f570a2efa5a11ca2f946daeb4ebc2851f181830152610300830152825180840184527f15f36fd35ab00a4f5488d568268b62a1a3b911e7e581c6273b5a6aed68d5ffbc81527f125e1fa454d9958f921944414bb3e94e06d3b748dbee6ac22a81c3a49e19bca981830152610320830152825180840184527f0a8d8881c8e7bbf87d37191fb3a8ef77e7abf7de04696a74d58293f8ab91c4cc81527f271274ed1b7d005bd5f87113856dd9841766913a2b1b8e9465b027d06a0c99bc81830152610340830152825180840184527f2770c1aa143acdf5f6e29ac2a15326f337cb57f57d10756d4c3fe1699021052781527e569125fa720db8dce31beab5160f8c6933f40e804977b288515686d6d6e16181830152610360830152825180840184526001815260028183015261038083015282518084019093527f050375219221fe68c1f9e5c3fed768de50bb1342a34f1a2948837176741dc01383527f1639e4ab4d1e100fbf57002222b74c97afb3de94a1ad0204b44cc64f84d04a93908301526103a081019190915290565b611cd46040518060800160405280600081526020016000815260200160008152602001600081525090565b60808214611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f696e76616c696420627974657320706f696e740000000000000000000000000060448201526064015b60405180910390fd5b604080516080810190915280611d5d6020600086886157d3565b611d669161588a565b8152602090810190611d7c9060409086886157d3565b611d859161588a565b8152602001611d986060604086886157d3565b611da19161588a565b8152602001611db46080606086886157d3565b611dbd9161588a565b90529392505050565b600060208214611e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f696e76616c6964206279746573207363616c61720000000000000000000000006044820152606401611d3a565b611e3f6105b5838561588a565b9392505050565b611e7f6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6000611e8f898989898989612d7e565b604086019190915260208501919091529083529250611eae838a6131a9565b608085019190915260608401919091529199919850909650505050505050565b611ed66154e7565b6000611ee0615506565b84815260e0848101805151602080850191909152815181015160408086019190915282518101516060808701919091529251830151608080870191909152880180515160a0870152805183015160c08701528051820151948601949094529251909101516101008401529051611f7791611f5c918491016158c6565b6040516020818303038152906040528051906020012061246f565b9150611f8282613276565b6020850152835260015b611f986002601961592a565b81101561201857611fb583604051602001611f5c91815260200190565b9250611fc083613276565b85611fcc8460026157bc565b60198110611fdc57611fdc615810565b6020020186611fec8560026157bc565b611ff79060016157fd565b6019811061200757612007615810565b602002019190915252600101611f8c565b5061202f82604051602001611f5c91815260200190565b9150600061203c83613276565b856120496001601961583f565b6019811061205957612059615810565b60200201919091525050509250929050565b612073615525565b6000805b601c8110156120c75761209684604051602001611f5c91815260200190565b935060006120a385613276565b8584601c81106120b5576120b5615810565b60200201919091525050600101612077565b5090929050565b6120d6615525565b6000805b601c81101561219c576120eb615506565b84815260005b60088110156121555786610100015183601c811061211157612111615810565b6020020151816008811061212757612127615810565b6020020151826121388360016157fd565b6009811061214857612148615810565b60200201526001016120f1565b5061216a81604051602001611f5c91906158c6565b9450600061217786613276565b8685601c811061218957612189615810565b60200201919091525050506001016120da565b50909391925050565b6000806121b0615544565b83815260005b60288110156122045785610120015181602881106121d6576121d6615810565b6020020151826121e78360016157fd565b602981106121f7576121f7615810565b60200201526001016121b6565b5061221981604051602001611f5c919061593e565b9150600061222683613276565b5096929550919350505050565b60008061223e615563565b83815260005b6122506001601c61583f565b81101561238e5785610140015181601b811061226e5761226e615810565b602002015151826122808360046157bc565b61228b9060016157fd565b606d811061229b5761229b615810565b602002015261014086015181601b81106122b7576122b7615810565b602002015160200151828260046122ce91906157bc565b6122d99060026157fd565b606d81106122e9576122e9615810565b602002015261014086015181601b811061230557612305615810565b6020020151604001518261231a8360046157bc565b6123259060036157fd565b606d811061233557612335615810565b602002015261014086015181601b811061235157612351615810565b602002015160600151826123668360046157bc565b6123719060046157fd565b606d811061238157612381615810565b6020020152600101612244565b5061221981604051602001611f5c9190615973565b6000806123ae615582565b83815260005b601c8110156124025785610160015181601c81106123d4576123d4615810565b6020020151826123e58360016157fd565b601d81106123f5576123f5615810565b60200201526001016123b4565b5061221981604051602001611f5c91906159a8565b6000806124226155a1565b8381526101808501805151602080840191909152815181015160408085019190915282518101516060808601919091529251909201516080840152905161221991611f5c918491016159dd565b600061249b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000183615a11565b92915050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018284099392505050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018284089392505050565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001612548837f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b84089392505050565b6000611e3f836105ba84612832565b8151600090819061257390856001610857565b929092149392505050565b60408051610100810182527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffec5181526102d060208201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffff1191810191909152609060608201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffff71608082015260f060a08201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffd3160c08201526113b060e08201526000906001825b60088110156126665761265c826105ba87846124fb565b9150600101612645565b5061266f6155bf565b60005b60088110156126d257600084826008811061268f5761268f615810565b602002015190506126a4816105ba89856124fb565b90506126af81612832565b9050808383600881106126c4576126c4615810565b602002015250600101612672565b5060005b60088110156127275760008782600881106126f3576126f3615810565b602002015190506127108184846008811061117057611170615810565b905061271c86826124ce565b9550506001016126d6565b506107a584836124a1565b60008061274960016105bf856105ba8960016124fb565b905061275584826124a1565b95945050505050565b60006127686155de565b6127738682856132b0565b61277f86868386613461565b61278b8686838661364e565b612796868285613855565b6127a1868285613a47565b6127ad86868386613dac565b6127b88682856146b9565b6127c3868285614a95565b6107a58185614d97565b6127d5615525565b81815260015b601c81101561282c5761280d826127f360018461583f565b601c811061280357612803615810565b6020020151612a10565b8282601c811061281f5761281f615810565b60200201526001016127db565b50919050565b6000808290506000604051602081526020808201526020604082015282606082015260027f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010360808201527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000160a08201526020600060c08360055afa9050806128ba57600080fd5b50506000519392505050565b600061249b827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b6128fa615525565b601c5b8015612a065760008461291160018461583f565b601c811061292157612921615810565b6020020151905060008861293660018561583f565b601c811061294657612946615810565b6020020151905060006129a261296661295f858c6124a1565b60026124a1565b6105de8a61297560018961583f565b601c811061298557612985615810565b60200201516105ba61299c886105ba60018a6124fb565b876124fb565b90506129c3816105ba61083c6129bd876105ba6001896124fb565b866124ce565b90508584116129f25797508780856129dc60018761583f565b601c81106129ec576129ec615810565b60200201525b505050806129ff90615a25565b90506128fd565b5095945050505050565b600061249b82836124a1565b60408051808201909152600080825260208201526000612a3e601c60286157fd565b612a499060026157fd565b90506001604051855151604082015285516020015160608201528451608082015260408160606040840160075afa8216915060015b83811015612ad75760208102870160208202870181515160408501528151602001516060850152805160808501525050604080830160606040850160075afa8316925060408260808460065afa90921691600101612a7e565b50805184526020810151602085015250505092915050565b60408051808201909152600080825260208201527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4782602001517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47612b54919061583f565b612b5e9190615a11565b60208301525090565b81516020808401518351848301516040805194850195909552938301919091527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260608301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60808301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60a08301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60c083015260e08201526101008101919091527f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c16101208201527f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b06101408201527f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe46101608201527f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e5561018082015260009081906101a0016040516020818303038152906040529050600080600873ffffffffffffffffffffffffffffffffffffffff1683604051612d0c9190615a5a565b600060405180830381855afa9150503d8060008114612d47576040519150601f19603f3d011682016040523d82523d6000602084013e612d4c565b606091505b5091509150600081806020019051810190612d679190615a89565b9050828015612d735750805b979650505050505050565b600080808080612d8f8760036157fd565b612d9a90600c6157fd565b67ffffffffffffffff811115612db257612db2615aab565b604051908082528060200260200182016040528015612ddb578160200160208202803683370190505b5090508760001b81600081518110612df557612df5615810565b6020026020010181815250508660001b81600181518110612e1857612e18615810565b6020026020010181815250508560001b81600281518110612e3b57612e3b615810565b60200260200101818152505060005b87811015612e9c578a8a82818110612e6457612e64615810565b9050602002013582826003612e7991906157fd565b81518110612e8957612e89615810565b6020908102919091010152600101612e4a565b508a515181612eac8960036157fd565b81518110612ebc57612ebc615810565b6020908102919091018101919091528b51015181612edb8960036157fd565b612ee69060016157fd565b81518110612ef657612ef6615810565b60209081029190910101528a516040015181612f138960036157fd565b612f1e9060026157fd565b81518110612f2e57612f2e615810565b60209081029190910101528a516060015181612f4b8960036157fd565b612f569060036157fd565b81518110612f6657612f66615810565b6020908102919091018101919091528b01515181612f858960036157fd565b612f909060046157fd565b81518110612fa057612fa0615810565b6020908102919091018101919091528b810151015181612fc18960036157fd565b612fcc9060056157fd565b81518110612fdc57612fdc615810565b6020908102919091018101919091528b01516040015181612ffe8960036157fd565b6130099060066157fd565b8151811061301957613019615810565b6020908102919091018101919091528b0151606001518161303b8960036157fd565b6130469060076157fd565b8151811061305657613056615810565b602090810291909101015260408b015151816130738960036157fd565b61307e9060086157fd565b8151811061308e5761308e615810565b60209081029190910181019190915260408c01510151816130b08960036157fd565b6130bb9060096157fd565b815181106130cb576130cb615810565b60209081029190910101526040808c01510151816130ea8960036157fd565b6130f590600a6157fd565b8151811061310557613105615810565b602090810291909101015260408b015160600151816131258960036157fd565b61313090600b6157fd565b8151811061314057613140615810565b60200260200101818152505061316081604051602001611f5c9190615ada565b915061316b82613276565b60408051602081018690529297509095506131869101611f5c565b9150600061319383613276565b50959c949b509499509097509195505050505050565b60008060006131b66155fd565b85815260a0858101805151602080850191909152815181015160408086019190915282518101516060808701919091529251830151608086015260c0808a0180515195870195909552845183015190860152835181015160e08601529251820151610100850152818801805151610120860152805182015161014086015280518401516101608601525190910151610180840152905161325c91611f5c91849101615b10565b915061326782613276565b90979096509194509092505050565b600080826fffffffffffffffffffffffffffffffff8116608082901c61329b8261246f565b94506132a68161246f565b9350505050915091565b60006132bd846007614dfd565b90507f183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000600061332061331a6132f38560036124fb565b6105ba61330f6133048b6000614dfd565b6105ba8c601c614dfd565b6105ba8b601b614dfd565b836124a1565b90506133a161339661337d61336461334b856105bf6133408d6002614dfd565b6105ba8e601b614dfd565b6105bf6133598c6003614dfd565b6105ba8d601c614dfd565b6105bf6133728b6004614dfd565b6105ba8c601d614dfd565b6105bf61338b8a6005614dfd565b6105ba8b601e614dfd565b6105bf886001614dfd565b90506133c0816105bf6133b58660016124fb565b6105ba8a6026614dfd565b90506133cc81846124a1565b90506133d881856124a1565b855250600090506134146134096133fe6133f388601b614dfd565b6105bf89601e614dfd565b6105de886023614dfd565b6105bf876000614dfd565b9050613425816105ba8460026124fb565b9050613436816105ba8460016124fb565b905061344281836124a1565b905061344e81846124a1565b9050808460015b60200201525050505050565b600080600061349961348f61347789601b614dfd565b6105bf6134858b6011614dfd565b8a606001516124a1565b87608001516124ce565b90506134d2816105ba6134c86134b08b601c614dfd565b6105bf6134be8d6012614dfd565b8c606001516124a1565b89608001516124ce565b90506134f7816105ba6134c86134e98b601d614dfd565b6105bf6134be8d6013614dfd565b905061351c816105ba6134c861350e8b601e614dfd565b6105bf6134be8d6014614dfd565b92506000905061354161348f61353389601b614dfd565b6105bf6134858b600d614dfd565b9050613566816105ba6134c86135588b601c614dfd565b6105bf6134be8d600e614dfd565b905061358b816105ba6134c861357d8b601d614dfd565b6105bf6134be8d600f614dfd565b90506135b0816105ba6134c86135a28b601e614dfd565b6105bf6134be8d6010614dfd565b9150600090506135d86135d26135c789601f614dfd565b6105bf8a6019614dfd565b846124a1565b905061360d816105de6136076135ef8b6027614dfd565b6105bf6135fd8d601a614dfd565b8c60a001516124a1565b856124a1565b905061361981856124a1565b604086015250600061363d61360761363289601a614dfd565b6105ba8a6027614dfd565b606090950194909452505050505050565b6000806136ad61369561367d6136686134c88a6015614dfd565b6105bf6136768b6016614dfd565b8a516124a1565b6105bf61368b8a6017614dfd565b89602001516124a1565b6105bf6136a3896018614dfd565b88604001516124a1565b915060006136e56136cc6136c289601b614dfd565b88608001516124ce565b6105bf6136da8a6003614dfd565b6105ba8b6023614dfd565b905060006137106136f789601c614dfd565b6105bf6137058b6000614dfd565b6105ba8c6024614dfd565b9050600061373b6137228a601d614dfd565b6105bf6137308c6001614dfd565b6105ba8d6025614dfd565b905061377b613763613755856105bf868d600001516124a1565b6105bf848c602001516124a1565b6105bf6137718c6004614dfd565b8b604001516124a1565b935050505060006137906135d2886020614dfd565b905060006137a26135d2896020614dfd565b905060006137db6137c26137b78b6022614dfd565b6105bf8c6006614dfd565b6105de6137d08c6022614dfd565b6105ba8d6006614dfd565b905060006138006137fa6137ef87896124a1565b6105ba8d6020614dfd565b836124fb565b905061380c81886124a1565b905060006138356138276138218d6006614dfd565b876124a1565b6105de6138218e6021614dfd565b60808a018390529050808960055b60200201525050505050505050505050565b6000613863600060016124fb565b90506000613873600060026124fb565b90506000613883600060036124fb565b905060006138a061389588601c614dfd565b6105de89601b614dfd565b905060006138bd6138b289601d614dfd565b6105de8a601c614dfd565b905060006138da6138cf8a601e614dfd565b6105de8b601d614dfd565b905060006138f76138ec8b6023614dfd565b6105de8c601e614dfd565b905083613908816105ba818b6124ce565b9050613918816105ba878a6124ce565b9050613928816105ba87896124ce565b9050613939816105ba8d6008614dfd565b9050613945818a6124a1565b60c08b0152508261395a816105ba818b6124ce565b905061396a816105ba868a6124ce565b905061397a816105ba86896124ce565b905061398b816105ba8d6008614dfd565b9050613997818a6124a1565b60e08b015250816139ac816105ba818b6124ce565b90506139bc816105ba858a6124ce565b90506139cc816105ba85896124ce565b90506139dd816105ba8d6008614dfd565b90506139e9818a6124a1565b6101008b015250806139ff816105ba818b6124ce565b9050613a0f816105ba848a6124ce565b9050613a1f816105ba84896124ce565b9050613a30816105ba8d6008614dfd565b9050613a3c818a6124a1565b9050808a6009613843565b613a876040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613a9284601c614dfd565b8152613a9f84601d614dfd565b6020820152613aaf846023614dfd565b6040820152613abf846026614dfd565b6060820152613acf846025614dfd565b6080820152613adf846024614dfd565b60a08201526000613af1856002614dfd565b90506000613b00866000614dfd565b90506000613b16846040015185600001516124fb565b90506000613b2c856020015186602001516124a1565b60608601519091508690600090613b4390806124a1565b90506000613b62613b5c89602001518a606001516124a1565b886124a1565b90506000613b82613b7b8a60a001518b604001516124ce565b8a516124ce565b9050613b9161382182886124a1565b9050613bb8613bb2613bac613ba684876124fb565b886124fb565b846124ce565b836124ce565b9050613be0613bd5613bca83876124a1565b6105ba8f6009614dfd565b6105ba60018a6124fb565b6101408c01525050505060208501516080860151600091613c00916124ce565b90506000613c1f613c158860600151886124a1565b88602001516124fb565b90506000613c45613c3084876124a1565b6105bf6136078b60a001518c600001516124fb565b9050613c6d613c62613c57838c6124a1565b6105ba8e6009614dfd565b6105ba6001896124fb565b6101608b01525060009150613c8f9050613c888360116124ce565b87516124a1565b90506000613c9d83846124ce565b9050613ca981826124ce565b90506000613cb88360096124a1565b9050613ce2613cdc6135d2613cd58b60a001518c600001516124ce565b8b516124ce565b826124fb565b60c08901819052600090613cfe90613b5c90613bca908d6124a1565b9050613d118b600a6020020151826124ce565b6101408c01525050865160009250613d399150613c8890613d3290806124ce565b88516124ce565b90506000613d7b613d56836105ba8a600001518b60a001516124fb565b60208901516105de90613d6990806124ce565b6105ba8b602001518c608001516124ce565b9050613d9889600b60200201516105bf613b5c613bca858d6124a1565b89600b602002015250505050505050505050565b613e56604051806102c00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b613e8b613e72613e6787601b614dfd565b6105ba886024614dfd565b6105bf613e80886023614dfd565b6105ba89601c614dfd565b8152613ed0613ec5613eac613ea188601b614dfd565b6105ba89601e614dfd565b6105bf613eba89601c614dfd565b6105ba8a601d614dfd565b6105de876025614dfd565b60408201819052613eea90681000000000000000006124a1565b60408201819052613f00906105de876026614dfd565b604082018190528151613f1391906124ce565b60408201819052613f29906105ba876005614dfd565b60408201528051613f4390681000000000000000006124a1565b808252613f63906105bf613f58886023614dfd565b6105ba896024614dfd565b80825260208201819052613f7f906105de6133f388601d614dfd565b60208201819052613f95906105ba876004614dfd565b6020820152805160608201819052613fb2906105bf87601e614dfd565b60608201819052613fd6906105de613fcb886025614dfd565b6105bf896026614dfd565b60608201819052613fec906105ba876000614dfd565b816060018181525050600061401661400c836020015184604001516124ce565b83606001516124ce565b9050614027816105ba886003614dfd565b905061403f614037876024614dfd565b6140006124a1565b60808301819052614055906105bf886023614dfd565b60808301819052614068906140006124a1565b6080830181905261407e906105bf88601d614dfd565b60808301819052614091906140006124a1565b608083018190526140a7906105bf88601c614dfd565b608083018190526140ba906140006124a1565b608083018190526140d0906105bf88601b614dfd565b608083018190526140e6906105de88601e614dfd565b608083018190526140fc906105ba886005614dfd565b608083015261410f614037876025614dfd565b60a08301819052614125906105bf886024614dfd565b60a08301819052614138906140006124a1565b60a0830181905261414e906105bf886023614dfd565b60a08301819052614161906140006124a1565b60a08301819052614177906105bf88601e614dfd565b60a0830181905261418a906140006124a1565b60a083018190526141a0906105bf88601d614dfd565b60a083018190526141b6906105de886026614dfd565b60a083018190526141cc906105ba886000614dfd565b60a0830181905260808301516000916141e591906124ce565b90506141f6816105ba896004614dfd565b905061421061420688601d614dfd565b87604001516124a1565b60c08401819052614229906105bf61368b8a601c614dfd565b60c08401819052614249906105bf6142428a601b614dfd565b89516124a1565b60c0840181905261425f906105bf896001614dfd565b60c0840181905260e0840181905261427c906105de89601e614dfd565b60c084015261428f613895886023614dfd565b6101408401526142ae6142a3886026614dfd565b6105de89601e614dfd565b6101208401526101408301516142d3906142c890806124a1565b8461014001516124fb565b6102808401526101408301516143289061431d90614316906105ba60017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b60016124ce565b8461012001516124a1565b610160840181905261435f90614351906105ba6143468b6002614dfd565b6105ba8c6003614dfd565b6105ba6138218a600a614dfd565b6101a086015261028083015161438190614351906105ba6143468b6002614dfd565b6101c086015260c08301516143a9906105ba61439e8a6002614dfd565b6105ba8b6003614dfd565b6101e084015260006143c96143bf89601e614dfd565b8560e001516124fb565b90506143d8613cdc82836124a1565b6101a08501526143ec6136a3896025614dfd565b6101008501819052614410906105bf6144068b6024614dfd565b8a602001516124a1565b610100850181905261442a906105bf6136768b6023614dfd565b61010085015261444961443e896026614dfd565b8561010001516124fb565b610100850152600061445f6138cf8a6025614dfd565b90506144d96144a061331a61431688610140015160017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016105ba919061583f565b6105ba61431688610100015160017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016105ba919061583f565b6101808601526101008501516144fe906144f390806124a1565b8661010001516124fb565b6101c08601526101808501516145319061451d906105ba8c6007614dfd565b6105ba61452b8c600a614dfd565b896124a1565b6101e08801526102808501516145509061451d906105ba8c6007614dfd565b6102008801526101c085015161456f9061451d906105ba8c6007614dfd565b6102208801526101a085015161458a906105ba8b6007614dfd565b6102008601526145a961459e8a6024614dfd565b6105de8b601c614dfd565b6102208601526101408501516145fb906138cf906145f090614316906105ba60017f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161583f565b8761022001516124a1565b61024086018190526101e08601516102608701819052614632916105bf906105ba6146278e6005614dfd565b6105ba8f6002614dfd565b610260860181905260c086015161465691906105bf906105ba6146278e6000614dfd565b610260860181905261020086015161466e91906124ce565b610260860181905261468490613bac90866124ce565b6102a0860181905261469e906105ba61452b8c600a614dfd565b6102a0860181905287600c6020020152505050505050505050565b61474060405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b61475961474e85601b614dfd565b6105bf866002614dfd565b815261477461476985601c614dfd565b6105bf866003614dfd565b602082015261479261478785601d614dfd565b6105bf866004614dfd565b60408201526147b06147a585601e614dfd565b6105bf866005614dfd565b606082015280516147e2906147db906147d4906147cd90806124a1565b84516124a1565b83516124a1565b82516124a1565b60808201526020810151614820906148169061480c9061480290806124a1565b84602001516124a1565b83602001516124a1565b82602001516124a1565b60a0820152604081015161485e906148549061484a9061484090806124a1565b84604001516124a1565b83604001516124a1565b82604001516124a1565b60c0820152606081015161489c90614892906148889061487e90806124a1565b84606001516124a1565b83606001516124a1565b82606001516124a1565b60e0820152608081015160a08201516148b591906124ce565b61010082015260c081015160e08201516148cf91906124ce565b61012082015260a08101516148f3906148e890806124ce565b8261012001516124ce565b61014082015260e08101516149179061490c90806124ce565b8261010001516124ce565b61016082015261012081015161492d90806124ce565b6101e0820181905261494e9061494390806124ce565b8261016001516124ce565b6101e082015261010081015161496490806124ce565b6101a082018190526149859061497a90806124ce565b8261014001516124ce565b6101a0820181905261016082015161499c916124ce565b6101808201526101408101516101e08201516149b891906124ce565b6101c08201526149cc61331a85600b614dfd565b61020082018190526102408401516101808301516149f7926105bf916105ba906105de8a6023614dfd565b8360126020020152614a2783601360200201516105bf8361020001516105ba856101a001516105de8a6024614dfd565b8360136020020152614a5783601460200201516105bf8361020001516105ba856101c001516105de8a6025614dfd565b8360146020020152614a8783601560200201516105bf8361020001516105ba856101e001516105de8a6026614dfd565b836015602002015250505050565b614af260405180610160016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006040518060800160405280614b287f10dc6e9c006ea38b04b1e03b4bd9490c0d03f98929ca1d7fb56821fd19d3b6e761246f565b8152602001614b567f0c28145b6a44df3e0149b3d0a30b3bb599df9756d4dd9b84a86b38cfb45a740b61246f565b8152602001614b837e544b8338791518b2c7645a50392798b21f75bb60e3596170067d00141cac1561246f565b8152602001614bb17f222c01175718386f2e2e82eb122789e352e105a3b8fa852613bc534433ee428b61246f565b90529050614bce614bc386601b614dfd565b6105bf876002614dfd565b6101208301819052614c0290614bf79061431d90614bec90806124a1565b8561012001516124a1565b8361012001516124a1565b8252614c0f85601c614dfd565b6020830152614c1f85601d614dfd565b6040830152614c2f85601e614dfd565b606083015281516020830151614c579161400c91614c4d91906124ce565b84604001516124ce565b6080830152614c6a6135d286600c614dfd565b6101408301528151614c8c90614c8290836000611170565b83608001516124ce565b60a0830152614cb884601660200201516105bf8461014001516105ba8660a001516105de8b6023614dfd565b6102c08501526020820151614cd390614c8290836001611170565b60c0830152614cff84601760200201516105bf8461014001516105ba8660c001516105de8b6024614dfd565b6102e08501526040820151614d1a90614c8290836002611170565b60e0830152614d4684601860200201516105bf8461014001516105ba8660e001516105de8b6025614dfd565b6103008501526060820151614d6190614c8290836003611170565b610100830152614d8f84601960200201516105bf8461014001516105ba8661010001516105de8b6026614dfd565b846019613455565b6000614da4818481610857565b905060015b601a811015614df657614dec826105bf8684601a8110614dcb57614dcb615810565b602002015186614ddc60018761583f565b6019811061117057611170615810565b9150600101614da9565b5092915050565b600082826027811115614e1257614e12615b45565b60288110614e2257614e22615810565b60200201519392505050565b604051806103c00160405280600081526020016000815260200160008152602001614e6c604051806040016040528060008152602001600081525090565b8152602001614e8e604051806040016040528060008152602001600081525090565b8152602001614eb0604051806040016040528060008152602001600081525090565b8152602001614ed2604051806040016040528060008152602001600081525090565b8152602001614ef4604051806040016040528060008152602001600081525090565b8152602001614f16604051806040016040528060008152602001600081525090565b8152602001614f38604051806040016040528060008152602001600081525090565b8152602001614f5a604051806040016040528060008152602001600081525090565b8152602001614f7c604051806040016040528060008152602001600081525090565b8152602001614f9e604051806040016040528060008152602001600081525090565b8152602001614fc0604051806040016040528060008152602001600081525090565b8152602001614fe2604051806040016040528060008152602001600081525090565b8152602001615004604051806040016040528060008152602001600081525090565b8152602001615026604051806040016040528060008152602001600081525090565b8152602001615048604051806040016040528060008152602001600081525090565b815260200161506a604051806040016040528060008152602001600081525090565b815260200161508c604051806040016040528060008152602001600081525090565b81526020016150ae604051806040016040528060008152602001600081525090565b81526020016150d0604051806040016040528060008152602001600081525090565b81526020016150f2604051806040016040528060008152602001600081525090565b8152602001615114604051806040016040528060008152602001600081525090565b8152602001615136604051806040016040528060008152602001600081525090565b8152602001615158604051806040016040528060008152602001600081525090565b815260200161517a604051806040016040528060008152602001600081525090565b815260200161519c604051806040016040528060008152602001600081525090565b81526020016151be604051806040016040528060008152602001600081525090565b81526020016151e0604051806040016040528060008152602001600081525090565b905290565b604051806101c0016040528061521c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161524c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161527c6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016152ac6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016152dc6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161530c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161533c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161536c6040518060800160405280600081526020016000815260200160008152602001600081525090565b815260200161537961561c565b815260200161538661564a565b8152602001615393615669565b81526020016153a0615525565b81526020016153d06040518060800160405280600081526020016000815260200160008152602001600081525090565b81526020016151e06040518060800160405280600081526020016000815260200160008152602001600081525090565b6040518061010001604052806154456040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016154526154e7565b815260200161545f615525565b815260200161546c615525565b8152602001600081526020016000815260200160008152602001600081525090565b604051806108c001604052806046906020820280368337509192915050565b604051806108c001604052806046905b60408051808201909152600080825260208201528152602001906001900390816154bd5790505090565b6040518061032001604052806019906020820280368337509192915050565b6040518061012001604052806009906020820280368337509192915050565b604051806103800160405280601c906020820280368337509192915050565b6040518061052001604052806029906020820280368337509192915050565b60405180610da00160405280606d906020820280368337509192915050565b604051806103a00160405280601d906020820280368337509192915050565b6040518060a001604052806005906020820280368337509192915050565b6040518061010001604052806008906020820280368337509192915050565b604051806103400160405280601a906020820280368337509192915050565b604051806101a00160405280600d906020820280368337509192915050565b604051806103800160405280601c905b6156346155bf565b81526020019060019003908161562c5790505090565b6040518061050001604052806028906020820280368337509192915050565b604051806103600160405280601b905b6156a46040518060800160405280600081526020016000815260200160008152602001600081525090565b8152602001906001900390816156795790505090565b600080600080604085870312156156d057600080fd5b843567ffffffffffffffff8111156156e757600080fd5b8501601f810187136156f857600080fd5b803567ffffffffffffffff81111561570f57600080fd5b87602082840101111561572157600080fd5b60209182019550935085013567ffffffffffffffff81111561574257600080fd5b8501601f8101871361575357600080fd5b803567ffffffffffffffff81111561576a57600080fd5b8760208260051b840101111561577f57600080fd5b949793965060200194505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761249b5761249b61578d565b600080858511156157e357600080fd5b838611156157f057600080fd5b5050820193919092039150565b8082018082111561249b5761249b61578d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8181038181111561249b5761249b61578d565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036158835761588361578d565b5060010190565b8035602083101561249b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60008183825b60098110156158eb5781518352602092830192909101906001016158cc565b5050506101208201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615939576159396158fb565b500490565b60008183825b6029811015615963578151835260209283019290910190600101615944565b5050506105208201905092915050565b60008183825b606d811015615998578151835260209283019290910190600101615979565b505050610da08201905092915050565b60008183825b601d8110156159cd5781518352602092830192909101906001016159ae565b5050506103a08201905092915050565b60008183825b6005811015615a025781518352602092830192909101906001016159e3565b50505060a08201905092915050565b600082615a2057615a206158fb565b500690565b600081615a3457615a3461578d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b6000825160005b81811015615a7b5760208186018101518583015201615a61565b506000920191825250919050565b600060208284031215615a9b57600080fd5b81518015158114611e3f57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8151600090829060208501835b82811015615b05578151845260209384019390910190600101615ae7565b509195945050505050565b60008183825b600d811015615b35578151835260209283019290910190600101615b16565b5050506101a08201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/Honk.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/Honk.json new file mode 100644 index 0000000..a61718d --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/Honk.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Honk", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HonkVerificationKey.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HonkVerificationKey.json new file mode 100644 index 0000000..b8c84ad --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/HonkVerificationKey.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "HonkVerificationKey", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/IVerifier.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/IVerifier.json new file mode 100644 index 0000000..f086761 --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/IVerifier.json @@ -0,0 +1,35 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "IVerifier", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_proof", + "type": "bytes" + }, + { + "internalType": "bytes32[]", + "name": "_publicInputs", + "type": "bytes32[]" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/RelationsLib.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/RelationsLib.json new file mode 100644 index 0000000..0b99444 --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/RelationsLib.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "RelationsLib", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/TranscriptLib.json b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/TranscriptLib.json new file mode 100644 index 0000000..8bfec2b --- /dev/null +++ b/src/examples/test/fixed-artifacts/HistoryProofVerifier.sol/TranscriptLib.json @@ -0,0 +1,10 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TranscriptLib", + "sourceName": "contracts/verifiers/HistoryProofVerifier.sol", + "abi": [], + "bytecode": "0x602d6037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/fixed-artifacts/SPVGatewayV2.sol/SPVGatewayV2.json b/src/examples/test/fixed-artifacts/SPVGatewayV2.sol/SPVGatewayV2.json new file mode 100644 index 0000000..6239aa7 --- /dev/null +++ b/src/examples/test/fixed-artifacts/SPVGatewayV2.sol/SPVGatewayV2.json @@ -0,0 +1,980 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SPVGatewayV2", + "sourceName": "contracts/SPVGatewayV2.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "proofVerifier_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chunkSize_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxProofFrontierLength_", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "name": "BlockHashNotInTheMainchain", + "type": "error" + }, + { + "inputs": [], + "name": "BufferOverflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "blockHeaderHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "inclusionProofHash", + "type": "bytes32" + } + ], + "name": "DifferentBlockHashes", + "type": "error" + }, + { + "inputs": [], + "name": "ECDSAInvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "length", + "type": "uint256" + } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + } + ], + "name": "ERC2612ExpiredSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "ERC2612InvalidSigner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "currentNonce", + "type": "uint256" + } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddressCommitment", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidBlockHeaderDataLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMerkleNode", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProofBlockHeight", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "currentCumulativeWork", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newCumulativeWork", + "type": "uint256" + } + ], + "name": "NotANewMainchain", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "OnlyDeployer", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "newHeight", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCumulativeWork", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newBlocksTreeRoot", + "type": "bytes32" + } + ], + "name": "MainchainUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newRewardsAmount", + "type": "uint256" + } + ], + "name": "SPVTokenRewardsAmountUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsAmount", + "type": "uint256" + } + ], + "name": "SPVTokenRewardsSent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_SPV_TOKEN_REWARDS_AMOUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPV_GATEWAY_V2_STORAGE_SLOT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPV_TOKEN_REWARDS_HALVING_PERIOD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "__SPVGatewayV2_init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes32[]", + "name": "level1MerkleProof", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "level2MerkleProof", + "type": "bytes32[]" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockHeight", + "type": "uint256" + } + ], + "internalType": "struct ISPVGatewayV2.HistoryBlockInclusionProofData", + "name": "inclusionProofData_", + "type": "tuple" + } + ], + "name": "checkBlockInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "merkleProof_", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "blockHeaderRaw_", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "txId_", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "txIndex_", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "bytes32[]", + "name": "level1MerkleProof", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "level2MerkleProof", + "type": "bytes32[]" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "blockHeight", + "type": "uint256" + } + ], + "internalType": "struct ISPVGatewayV2.HistoryBlockInclusionProofData", + "name": "blockInclusionProofData_", + "type": "tuple" + } + ], + "name": "checkTxInclusion", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chunkSize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBlocksTreeRoot", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMainchainCumulativeWork", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMainchainHeight", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProofsCountFromHalving", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSPVTokenRewardsAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxProofFrontierLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "proofVerifier", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "blocksCount", + "type": "uint64" + }, + { + "internalType": "bytes32[]", + "name": "publicInputs", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + } + ], + "internalType": "struct ProofHelper.ProofData", + "name": "proofData_", + "type": "tuple" + } + ], + "name": "updateMainchain", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x61010060405234801561001157600080fd5b5060405161437d38038061437d8339810160408190526100309161004e565b336080526001600160a01b039290921660a05260c05260e052610091565b60008060006060848603121561006357600080fd5b83516001600160a01b038116811461007a57600080fd5b602085015160409095015190969495509392505050565b60805160a05160c05160e0516142896100f46000396000818161033e0152610a1c0152600081816104a701528181610649015281816106ac015281816106da0152610a820152600081816103d70152610a480152600061105101526142896000f3fe608060405234801561001057600080fd5b50600436106101c35760003560e01c80635f3ae0d5116100f95780639276cfcc11610097578063a9059cbb11610071578063a9059cbb1461048f578063c4a942cb146104a2578063d505accf146104c9578063dd62ed3e146104dc57600080fd5b80639276cfcc146104395780639367e1711461046057806395d89b411461048757600080fd5b80637ecebe00116100d35780637ecebe00146103b75780637f52f0ba146103ca5780637fa417b3146103d257806384b0196e1461041e57600080fd5b80635f3ae0d51461038757806362ed7f441461039a57806370a08231146103a457600080fd5b806323b872dd116101665780633644e515116101405780633644e515146102e05780633f377a6c146102e85780634f09aac71461033957806357f913b81461036057600080fd5b806323b872dd146102ab5780632940907e146102be578063313ce567146102d157600080fd5b80630e81dfed116101a25780630e81dfed1461023657806315085d9e1461026757806318160ddd1461027a5780631fd07a33146102a157600080fd5b80627421a9146101c857806306fdde03146101fe578063095ea7b314610213575b600080fd5b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b545b6040519081526020015b60405180910390f35b610206610541565b6040516101f591906135a1565b6102266102213660046135dd565b6105fc565b60405190151581526020016101f5565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c5467ffffffffffffffff166101eb565b61022661027536600461361f565b610616565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02546101eb565b6102a9610720565b005b6102266102b9366004613654565b610971565b6102a96102cc366004613691565b610997565b604051601281526020016101f5565b6101eb610b50565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c5468010000000000000000900467ffffffffffffffff1660405167ffffffffffffffff90911681526020016101f5565b6101eb7f000000000000000000000000000000000000000000000000000000000000000081565b6101eb7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b81565b61022661039536600461370e565b610b5f565b6101eb6203345081565b6101eb6103b23660046137f3565b610c64565b6101eb6103c53660046137f3565b610cb6565b6101eb603281565b6103f97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b610426610cc1565b6040516101f5979695949392919061380e565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987d546101eb565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987e546101eb565b610206610dbd565b61022661049d3660046135dd565b610e0e565b6101eb7f000000000000000000000000000000000000000000000000000000000000000081565b6102a96104d73660046138cf565b610e1c565b6101eb6104ea366004613942565b73ffffffffffffffffffffffffffffffffffffffff91821660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b606060007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b905080600301805461057890613975565b80601f01602080910402602001604051908101604052809291908181526020018280546105a490613975565b80156105f15780601f106105c6576101008083540402835291602001916105f1565b820191906000526020600020905b8154815290600101906020018083116105d457829003601f168201915b505050505091505090565b60003361060a818585610fe8565b60019150505b92915050565b60007f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b8161067d604085013560608601357f000000000000000000000000000000000000000000000000000000000000000061067288806139c2565b909390929091610ffa565b600383015460018401549192506107189183906106d09068010000000000000000900467ffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611021565b6106fe88606001357f0000000000000000000000000000000000000000000000000000000000000000611021565b61070b60208a018a6139c2565b909490939092909161102d565b949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff1660008115801561076b5750825b905060008267ffffffffffffffff1660011480156107885750303b155b905081158015610796575080155b156107cd576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001178555831561082e5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6108373361104b565b6108ab6040518060400160405280600981526020017f53505620546f6b656e00000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f53505600000000000000000000000000000000000000000000000000000000008152506110df565b6108e96040518060400160405280600981526020017f53505620546f6b656e00000000000000000000000000000000000000000000008152506110f5565b6109086108f86012600a613b74565b610903906032613b83565b61113c565b831561096a5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2906020015b60405180910390a15b5050505050565b60003361097f858285611195565b61098a858585611284565b60019150505b9392505050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b60006109c38361132f565b600283015490915081818111610a13576040517fcaf4b72c000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044015b60405180910390fd5b50610a419050837f00000000000000000000000000000000000000000000000000000000000000003361135e565b50610a6c837f00000000000000000000000000000000000000000000000000000000000000006113dc565b506000610a788461151f565b90506000610aa6857f000000000000000000000000000000000000000000000000000000000000000061153f565b6001850180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff86160217905560028501849055600385018190559050610b00336115de565b610b086116a3565b6040805167ffffffffffffffff84168152602081018590529081018290527f218fc5ee66940d7f36a8a17a58b427168a3a941a67ceb8eb8ca0559fe328117a90606001610961565b6000610b5a611754565b905090565b60008080610b6f8888600161175e565b9092509050806040850135808214610bbc576040517fc6ab5c5e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610a0a565b5050610bc784610616565b8190610c02576040517f924ddc04000000000000000000000000000000000000000000000000000000008152600401610a0a91815260200190565b506000610c128360200151611985565b9050610c558b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508592508b91508a90506119ef565b9b9a5050505050505050505050565b6000807f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020939093525050604090205490565b600061061082611a07565b600060608082808083817fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1008054909150158015610d0057506001810154155b610d66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4549503731323a20556e696e697469616c697a656400000000000000000000006044820152606401610a0a565b610d6e611a30565b610d76611a81565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009c939b5091995046985030975095509350915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060917f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace009161057890613975565b60003361060a818585611284565b83421115610e59576040517f6279130200000000000000000000000000000000000000000000000000000000815260048101859052602401610a0a565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610ed28c73ffffffffffffffffffffffffffffffffffffffff1660009081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610f3a82611aab565b90506000610f4a82878787611af3565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fd1576040517f4b800e4600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301528b166024820152604401610a0a565b610fdc8a8a8a610fe8565b50505050505050505050565b610ff58383836001611b21565b505050565b600061101786868661100c8787611c8d565b611d1e611dd0611e89565b9695505050505050565b60006109908284613bf8565b60008061103d8888878787611f80565b909514979650505050505050565b61108e817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6110dc576040517fe000635700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610a0a565b50565b6110e7611f9d565b6110f18282612006565b5050565b6110fd611f9d565b6110dc816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250612069565b807f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b556040518181527f118c84ede6afa8ddc451b5838c702591a7b7a641049d07152609dd18ecda0e0c9060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff83811660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561127e578181101561126f576040517ffb8f41b200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024810182905260448101839052606401610a0a565b61127e84848484036000611b21565b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166112d4576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff8216611324576040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b610ff58383836120dc565b600061133e60208301836139c2565b602d81811061134f5761134f613c0c565b60200291909101359392505050565b60008061136a856122ad565b9050600061137886866122ba565b905061138482856122d5565b81148061139a57506113978260006122d5565b81145b6113d0576040517f01265e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195945050505050565b60006113e78361151f565b6113f2906001613c3b565b67ffffffffffffffff166114096020850185613c5b565b67ffffffffffffffff161461144a576040517f56e3013800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821663ea50d0e46114736040860186613c85565b61148060208801886139c2565b6040518563ffffffff1660e01b815260040161149f9493929190613cea565b602060405180830381865afa1580156114bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e09190613d85565b611516576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600192915050565b600061152e60208301836139c2565b602c81811061134f5761134f613c0c565b60008061154c848461233f565b905061159461155e6020860186613c5b565b67ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810181169015011590565b156115ca576115c3846115a8600184613da7565b6115b3906020613b83565b6115be90602e613dba565b612378565b91506115d7565b6115d48185612439565b91505b5092915050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b805461160b83826124c8565b60018201805467ffffffffffffffff1690600061162783613dcd565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508273ffffffffffffffffffffffffffffffffffffffff167fbb3dce316c712fb2d056f7fa51a217f3d2a78d741e08da11b1315c935a1575c78260405161169691815260200190565b60405180910390a2505050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c547f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b9067ffffffffffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffccbb0016110dc5780546117299061090390600290613bf8565b60010180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000169055565b6000610b5a612524565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290605084146117ca576040517f2764198c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160c08101909152806117e460246004888a613dfa565b6117ed91613e24565b815260200161180060446024888a613dfa565b61180991613e24565b815260200161181c60046000888a613dfa565b61182591613e60565b60e01c815260200161183b60486044888a613dfa565b61184491613e60565b60e01c815260200161185a6050604c888a613dfa565b61186391613e60565b60e01c8152602001611879604c6048888a613dfa565b61188291613e60565b7fffffffff0000000000000000000000000000000000000000000000000000000016905291506118b28585612598565b9050821561197d576118cd826040015163ffffffff16612678565b63ffffffff16604083015281516118e390611985565b825260208201516118f390611985565b6020830152606082015161190c9063ffffffff16612678565b63ffffffff16606083015260a08201516119289060e01c612678565b60e01b7fffffffff000000000000000000000000000000000000000000000000000000001660a083015260808201516119669063ffffffff16612678565b63ffffffff16608083015261197a81611985565b90505b935093915050565b600081151960c01c70010000000000000000000000000000000102602081811b8218601081811b8218600881811b8218808916821b9189901c1617808216831b921c1617808216831b921c1617808216604090811b91901c90911617608081811b91901c17610610565b6000836119fd8685856126b1565b1495945050505050565b6000807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00610c89565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060917fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1009161057890613975565b606060007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100610567565b6000610610611ab8611754565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b600080600080611b05888888886127c1565b925092509250611b1582826128bb565b50909695505050505050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0073ffffffffffffffffffffffffffffffffffffffff8516611b92576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff8416611be2576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff80861660009081526001830160209081526040808320938816835292905220839055811561096a578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051611c7e91815260200190565b60405180910390a35050505050565b6000610990611c9c84846129bf565b611d1984600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b6129cb565b6040517f6c656166310000000000000000000000000000000000000000000000000000006020820152602581018290526000906002906045015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611d9091613ec5565b602060405180830381855afa158015611dad573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106109190613ee1565b6040517f6e6f646531000000000000000000000000000000000000000000000000000000602082015260258101839052604581018290526000906002906065015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e4991613ec5565b602060405180830381855afa158015611e66573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109909190613ee1565b600080611e99868563ffffffff16565b905084875b600081118015611ed0575060008a8a611eb8600185613da7565b818110611ec757611ec7613c0c565b90506020020135145b15611ee557611ede81613efa565b9050611e9e565b805b8015611f71576000611efa600183613da7565b90508084901c600116600103611f3757611f308c8c83818110611f1f57611f1f613c0c565b90506020020135868963ffffffff16565b9450611f60565b611f5d858d8d84818110611f4d57611f4d613c0c565b905060200201358963ffffffff16565b94505b50611f6a81613efa565b9050611ee7565b50919998505050505050505050565b6000611017868686611f928688612ae0565b612b6e612bac611e89565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16612004576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61200e611f9d565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0361205a8482613f76565b506004810161127e8382613f76565b612071611f9d565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1026120bd8482613f76565b50600381016120cc8382613f76565b5060008082556001909101555050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0073ffffffffffffffffffffffffffffffffffffffff8416612137578181600201600082825461212c9190613dba565b909155506121e99050565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208290526040902054828110156121bd576040517fe450d38c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024810182905260448101849052606401610a0a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526020839052604090209083900390555b73ffffffffffffffffffffffffffffffffffffffff8316612214576002810180548390039055612240565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020829052604090208054830190555b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161229f91815260200190565b60405180910390a350505050565b6000610610826000612378565b60006109908360016122cb85612bf1565b6115be9190613dba565b6040517f61646472657373000000000000000000000000000000000000000000000000006020820152602781018390527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166047820152600090600290605b01611e11565b600061236d826123526020860186613c5b565b67ffffffffffffffff166123669190613bf8565b6001612c09565b610990906001613dba565b60408051602080825281830190925260009182919060208201818036833701905050905060005b6020811015612424576123b560208601866139c2565b6123bf8387613dba565b8181106123ce576123ce613c0c565b9050602002013560001c60f81b8282815181106123ed576123ed613c0c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161239f565b50808060200190518101906115d49190613ee1565b6000805b612448600185613da7565b8110156115d7576000612460846115b3846020613b83565b90508015801561246e575082155b1561247957506124c0565b600080848103612497578261248d85612cb3565b90925090506124b0565b60008390036124aa578461248d85612cb3565b50819050835b6124ba8282612bac565b94505050505b60010161243d565b73ffffffffffffffffffffffffffffffffffffffff8216612518576040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b6110f1600083836120dc565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61254f612ce8565b612557612d64565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60008060028085856040516125ae92919061408f565b602060405180830381855afa1580156125cb573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906125ee9190613ee1565b60405160200161260091815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261263891613ec5565b602060405180830381855afa158015612655573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906115d49190613ee1565b600061061082601881811b63ff00000016600883811b62ff0000169190911761ff009184901c919091161760ff9290911c919091161790565b825160009083906060835b828110156127b5576001861615612716578781815181106126df576126df613c0c565b602002602001015184604051602001612702929190918252602082015260400190565b60405160208183030381529060405261275b565b8388828151811061272957612729613c0c565b602002602001015160405160200161274b929190918252602082015260400190565b6040516020818303038152906040525b915061276682612dba565b1561279d576040517f4d3d606a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127a6826131f7565b600196871c96909450016126bc565b50919695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156127fc57506000915060039050826128b1565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612850573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166128a7575060009250600191508290506128b1565b9250600091508190505b9450945094915050565b60008260038111156128cf576128cf61409f565b036128d8575050565b60018260038111156128ec576128ec61409f565b03612923576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028260038111156129375761293761409f565b03612971576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610a0a565b60038260038111156129855761298561409f565b036110f1576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610a0a565b600061099082846140ce565b600080612aca8460007f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f33333333333333333333333333333333333333333333333333333333333333337f555555555555555555555555555555555555555555555555555555555555555584151960c01c70010000000000000000000000000000000102602081811b8218601081811b8218600881811b8218808c16821b918c901c1617808216831b921c1617808216831b921c1617808216604090811b91901c90911617608081811b91901c17600181811c831692909116901b17600281811c831692909116901b17600481811c831692909116901b1792915050565b9050612ad883610100613da7565b1c9392505050565b600061099083612b6384600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b611d19906001613dba565b6040517f6c65616632000000000000000000000000000000000000000000000000000000602082015260258101829052600090600290604501611d58565b6040517f6e6f64653200000000000000000000000000000000000000000000000000000060208201526025810183905260458101829052600090600290606501611e11565b6000612bfe826020613b83565b61061090602e613dba565b600080612c8984600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b9050612cab612c978461325c565b8015612ca6575084826001901b105b151590565b019392505050565b600081600003612cc7576106106000612b6e565b6000612cdc612cd7600185613da7565b612cb3565b90506109908182612bac565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10081612d14611a30565b805190915015612d2c57805160209091012092915050565b81548015612d3b579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10081612d90611a81565b805190915015612da857805160209091012092915050565b60018201548015612d3b579392505050565b6000603c82511015612dce57506000919050565b600082600081518110612de357612de3613c0c565b016020015160f81c90506001811080612dfc5750600281115b15612e0a5750600092915050565b50815160009083906001908110612e2357612e23613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612e5757506000919050565b815160009083906002908110612e6f57612e6f613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612ea357506000919050565b815160009083906003908110612ebb57612ebb613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612eef57506000919050565b6004600080612efe8584613289565b67ffffffffffffffff909116925060ff1690506000828103612f7f57506001612f26846140e2565b9350858481518110612f3a57612f3a613c0c565b60209101015160f81c600114612f565750600095945050505050565b612f5f846140e2565b9350612f6b8685613289565b67ffffffffffffffff909116935060ff1691505b612f898285613dba565b9350600060048751612f9b9190613da7565b90508085612faa866029613b83565b612fb49190613dba565b10612fc6575060009695505050505050565b6000805b8581101561304857612fdd602088613dba565b9650612fea600488613dba565b9650612ff68988613289565b60ff16955067ffffffffffffffff1691506130118583613dba565b61301b9088613dba565b96508287106130335750600098975050505050505050565b61303e600488613dba565b9650600101612fca565b5060006130558988613289565b60ff16955067ffffffffffffffff1690508287613073836009613b83565b61307d9190613dba565b11156130925750600098975050505050505050565b61309c8588613dba565b965060005b81811015613107576130b4600889613dba565b97506130c08a89613289565b60ff16965067ffffffffffffffff1692506130db8684613dba565b6130e59089613dba565b9750838811156130ff575060009998505050505050505050565b6001016130a1565b5083156131d25760005b868110156131d05760006131258b8a613289565b60ff16975067ffffffffffffffff169050613140878a613dba565b98508461314d8a83613dba565b1115613164575060009a9950505050505050505050565b60005b818110156131c657600061317b8d8c613289565b60ff16995067ffffffffffffffff169050613196818a613dba565b6131a0908c613dba565b9a50868b11156131bd575060009c9b505050505050505050505050565b50600101613167565b5050600101613111565b505b8287146131e85750600098975050505050505050565b50600198975050505050505050565b60006002808360405161320a9190613ec5565b602060405180830381855afa158015613227573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061324a9190613ee1565b604051602001611d5891815260200190565b600060028260038111156132725761327261409f565b61327c919061411a565b60ff166001149050919050565b6000806132a161329a846001613dba565b85516133df565b60008484815181106132b5576132b5613c0c565b016020015160f81c905060fd8110156132d65760ff169150600190506133d8565b8060ff1660fd0361333c576132f66132ef856003613dba565b86516133df565b61332b61331a613307866001613dba565b613312876003613dba565b889190613419565b6133239061413c565b60f01c61349d565b61ffff169250600391506133d89050565b8060ff1660fe03613395576133556132ef856005613dba565b613382613371613366866001613dba565b613312876005613dba565b61337a906141a8565b60e01c612678565b63ffffffff169250600591506133d89050565b6133a36132ef856009613dba565b6133d06133bf6133b4866001613dba565b613312876009613dba565b6133c890614212565b60c01c6134b8565b925060099150505b9250929050565b808211156110f1576040517f6c95098b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608351828111613428578092505b838111613433578093505b508183101561099057506040518282038484017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830181165b828101518582015281018061346e57505050806020830101600081526020810160405250808252509392505050565b6000600882811c60ff1661ff009184901b9190911617610610565b6000603882811b67ff0000000000000016602884811b66ff0000000000001691909117601885811b65ff00000000001691909117600886811b64ff00000000169190911763ff0000009187901c919091161762ff00009186901c919091161761ff009185901c919091161760ff9184901c9190911617610610565b60005b8381101561354e578181015183820152602001613536565b50506000910152565b6000815180845261356f816020860160208601613533565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109906020830184613557565b803573ffffffffffffffffffffffffffffffffffffffff811681146135d857600080fd5b919050565b600080604083850312156135f057600080fd5b6135f9836135b4565b946020939093013593505050565b60006080828403121561361957600080fd5b50919050565b60006020828403121561363157600080fd5b813567ffffffffffffffff81111561364857600080fd5b6115d484828501613607565b60008060006060848603121561366957600080fd5b613672846135b4565b9250613680602085016135b4565b929592945050506040919091013590565b6000602082840312156136a357600080fd5b813567ffffffffffffffff8111156136ba57600080fd5b82016060818503121561099057600080fd5b60008083601f8401126136de57600080fd5b50813567ffffffffffffffff8111156136f657600080fd5b6020830191508360208285010111156133d857600080fd5b600080600080600080600060a0888a03121561372957600080fd5b873567ffffffffffffffff81111561374057600080fd5b8801601f81018a1361375157600080fd5b803567ffffffffffffffff81111561376857600080fd5b8a60208260051b840101111561377d57600080fd5b60209182019850965088013567ffffffffffffffff81111561379e57600080fd5b6137aa8a828b016136cc565b9096509450506040880135925060608801359150608088013567ffffffffffffffff8111156137d857600080fd5b6137e48a828b01613607565b91505092959891949750929550565b60006020828403121561380557600080fd5b610990826135b4565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e06020820152600061384960e0830189613557565b828103604084015261385b8189613557565b6060840188905273ffffffffffffffffffffffffffffffffffffffff8716608085015260a0840186905283810360c08501528451808252602080870193509091019060005b818110156138be5783518352602093840193909201916001016138a0565b50909b9a5050505050505050505050565b600080600080600080600060e0888a0312156138ea57600080fd5b6138f3886135b4565b9650613901602089016135b4565b95506040880135945060608801359350608088013560ff8116811461392557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561395557600080fd5b61395e836135b4565b915061396c602084016135b4565b90509250929050565b600181811c9082168061398957607f821691505b602082108103613619577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139f757600080fd5b83018035915067ffffffffffffffff821115613a1257600080fd5b6020019150600581901b36038213156133d857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001815b600184111561197d57808504811115613a7857613a78613a2a565b6001841615613a8657908102905b60019390931c928002613a5d565b600082613aa357506001610610565b81613ab057506000610610565b8160018114613ac65760028114613ad057613aec565b6001915050610610565b60ff841115613ae157613ae1613a2a565b50506001821b610610565b5060208310610133831016604e8410600b8410161715613b0f575081810a610610565b613b3a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613a59565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613b6c57613b6c613a2a565b029392505050565b600061099060ff841683613a94565b808202811582820484141761061057610610613a2a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613c0757613c07613bc9565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff818116838216019081111561061057610610613a2a565b600060208284031215613c6d57600080fd5b813567ffffffffffffffff8116811461099057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613cba57600080fd5b83018035915067ffffffffffffffff821115613cd557600080fd5b6020019150368190038213156133d857600080fd5b604081528360408201528385606083013760006060858301015260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820160608382030160208401528360608201527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841115613d6c57600080fd5b8360051b80866080840137016080019695505050505050565b600060208284031215613d9757600080fd5b8151801515811461099057600080fd5b8181038181111561061057610610613a2a565b8082018082111561061057610610613a2a565b600067ffffffffffffffff821667ffffffffffffffff8103613df157613df1613a2a565b60010192915050565b60008085851115613e0a57600080fd5b83861115613e1757600080fd5b5050820193919092039150565b80356020831015610610577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081169060048410156115d7577fffffffff00000000000000000000000000000000000000000000000000000000808560040360031b1b82161691505092915050565b60008251613ed7818460208701613533565b9190910192915050565b600060208284031215613ef357600080fd5b5051919050565b600081613f0957613f09613a2a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f821115610ff557806000526020600020601f840160051c81016020851015613f565750805b601f840160051c820191505b8181101561096a5760008155600101613f62565b815167ffffffffffffffff811115613f9057613f90613b9a565b613fa481613f9e8454613975565b84613f2f565b6020601f821160018114613ff65760008315613fc05750848201515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b17845561096a565b6000848152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08516915b828110156140445787850151825560209485019460019092019101614024565b508482101561408057868401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b60f8161c191681555b50505050600190811b01905550565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000826140dd576140dd613bc9565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361411357614113613a2a565b5060010190565b600060ff83168061412d5761412d613bc9565b8060ff84160691505092915050565b805160208201517fffff0000000000000000000000000000000000000000000000000000000000008116919060028210156141a1577fffff000000000000000000000000000000000000000000000000000000000000808360020360031b1b82161692505b5050919050565b805160208201517fffffffff000000000000000000000000000000000000000000000000000000008116919060048210156141a1577fffffffff0000000000000000000000000000000000000000000000000000000060049290920360031b82901b161692915050565b805160208201517fffffffffffffffff0000000000000000000000000000000000000000000000008116919060088210156141a1577fffffffffffffffff00000000000000000000000000000000000000000000000060089290920360031b82901b16169291505056fea164736f6c634300081c000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c35760003560e01c80635f3ae0d5116100f95780639276cfcc11610097578063a9059cbb11610071578063a9059cbb1461048f578063c4a942cb146104a2578063d505accf146104c9578063dd62ed3e146104dc57600080fd5b80639276cfcc146104395780639367e1711461046057806395d89b411461048757600080fd5b80637ecebe00116100d35780637ecebe00146103b75780637f52f0ba146103ca5780637fa417b3146103d257806384b0196e1461041e57600080fd5b80635f3ae0d51461038757806362ed7f441461039a57806370a08231146103a457600080fd5b806323b872dd116101665780633644e515116101405780633644e515146102e05780633f377a6c146102e85780634f09aac71461033957806357f913b81461036057600080fd5b806323b872dd146102ab5780632940907e146102be578063313ce567146102d157600080fd5b80630e81dfed116101a25780630e81dfed1461023657806315085d9e1461026757806318160ddd1461027a5780631fd07a33146102a157600080fd5b80627421a9146101c857806306fdde03146101fe578063095ea7b314610213575b600080fd5b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b545b6040519081526020015b60405180910390f35b610206610541565b6040516101f591906135a1565b6102266102213660046135dd565b6105fc565b60405190151581526020016101f5565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c5467ffffffffffffffff166101eb565b61022661027536600461361f565b610616565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02546101eb565b6102a9610720565b005b6102266102b9366004613654565b610971565b6102a96102cc366004613691565b610997565b604051601281526020016101f5565b6101eb610b50565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c5468010000000000000000900467ffffffffffffffff1660405167ffffffffffffffff90911681526020016101f5565b6101eb7f000000000000000000000000000000000000000000000000000000000000000081565b6101eb7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b81565b61022661039536600461370e565b610b5f565b6101eb6203345081565b6101eb6103b23660046137f3565b610c64565b6101eb6103c53660046137f3565b610cb6565b6101eb603281565b6103f97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f5565b610426610cc1565b6040516101f5979695949392919061380e565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987d546101eb565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987e546101eb565b610206610dbd565b61022661049d3660046135dd565b610e0e565b6101eb7f000000000000000000000000000000000000000000000000000000000000000081565b6102a96104d73660046138cf565b610e1c565b6101eb6104ea366004613942565b73ffffffffffffffffffffffffffffffffffffffff91821660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b606060007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b905080600301805461057890613975565b80601f01602080910402602001604051908101604052809291908181526020018280546105a490613975565b80156105f15780601f106105c6576101008083540402835291602001916105f1565b820191906000526020600020905b8154815290600101906020018083116105d457829003601f168201915b505050505091505090565b60003361060a818585610fe8565b60019150505b92915050565b60007f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b8161067d604085013560608601357f000000000000000000000000000000000000000000000000000000000000000061067288806139c2565b909390929091610ffa565b600383015460018401549192506107189183906106d09068010000000000000000900467ffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611021565b6106fe88606001357f0000000000000000000000000000000000000000000000000000000000000000611021565b61070b60208a018a6139c2565b909490939092909161102d565b949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff1660008115801561076b5750825b905060008267ffffffffffffffff1660011480156107885750303b155b905081158015610796575080155b156107cd576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001178555831561082e5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6108373361104b565b6108ab6040518060400160405280600981526020017f53505620546f6b656e00000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f53505600000000000000000000000000000000000000000000000000000000008152506110df565b6108e96040518060400160405280600981526020017f53505620546f6b656e00000000000000000000000000000000000000000000008152506110f5565b6109086108f86012600a613b74565b610903906032613b83565b61113c565b831561096a5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2906020015b60405180910390a15b5050505050565b60003361097f858285611195565b61098a858585611284565b60019150505b9392505050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b60006109c38361132f565b600283015490915081818111610a13576040517fcaf4b72c000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044015b60405180910390fd5b50610a419050837f00000000000000000000000000000000000000000000000000000000000000003361135e565b50610a6c837f00000000000000000000000000000000000000000000000000000000000000006113dc565b506000610a788461151f565b90506000610aa6857f000000000000000000000000000000000000000000000000000000000000000061153f565b6001850180547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff86160217905560028501849055600385018190559050610b00336115de565b610b086116a3565b6040805167ffffffffffffffff84168152602081018590529081018290527f218fc5ee66940d7f36a8a17a58b427168a3a941a67ceb8eb8ca0559fe328117a90606001610961565b6000610b5a611754565b905090565b60008080610b6f8888600161175e565b9092509050806040850135808214610bbc576040517fc6ab5c5e00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610a0a565b5050610bc784610616565b8190610c02576040517f924ddc04000000000000000000000000000000000000000000000000000000008152600401610a0a91815260200190565b506000610c128360200151611985565b9050610c558b8b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508592508b91508a90506119ef565b9b9a5050505050505050505050565b6000807f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020939093525050604090205490565b600061061082611a07565b600060608082808083817fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1008054909150158015610d0057506001810154155b610d66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4549503731323a20556e696e697469616c697a656400000000000000000000006044820152606401610a0a565b610d6e611a30565b610d76611a81565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009c939b5091995046985030975095509350915050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060917f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace009161057890613975565b60003361060a818585611284565b83421115610e59576040517f6279130200000000000000000000000000000000000000000000000000000000815260048101859052602401610a0a565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610ed28c73ffffffffffffffffffffffffffffffffffffffff1660009081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610f3a82611aab565b90506000610f4a82878787611af3565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fd1576040517f4b800e4600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80831660048301528b166024820152604401610a0a565b610fdc8a8a8a610fe8565b50505050505050505050565b610ff58383836001611b21565b505050565b600061101786868661100c8787611c8d565b611d1e611dd0611e89565b9695505050505050565b60006109908284613bf8565b60008061103d8888878787611f80565b909514979650505050505050565b61108e817f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b6110dc576040517fe000635700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610a0a565b50565b6110e7611f9d565b6110f18282612006565b5050565b6110fd611f9d565b6110dc816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250612069565b807f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b556040518181527f118c84ede6afa8ddc451b5838c702591a7b7a641049d07152609dd18ecda0e0c9060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff83811660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81101561127e578181101561126f576040517ffb8f41b200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024810182905260448101839052606401610a0a565b61127e84848484036000611b21565b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166112d4576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff8216611324576040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b610ff58383836120dc565b600061133e60208301836139c2565b602d81811061134f5761134f613c0c565b60200291909101359392505050565b60008061136a856122ad565b9050600061137886866122ba565b905061138482856122d5565b81148061139a57506113978260006122d5565b81145b6113d0576040517f01265e6500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600195945050505050565b60006113e78361151f565b6113f2906001613c3b565b67ffffffffffffffff166114096020850185613c5b565b67ffffffffffffffff161461144a576040517f56e3013800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821663ea50d0e46114736040860186613c85565b61148060208801886139c2565b6040518563ffffffff1660e01b815260040161149f9493929190613cea565b602060405180830381865afa1580156114bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e09190613d85565b611516576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600192915050565b600061152e60208301836139c2565b602c81811061134f5761134f613c0c565b60008061154c848461233f565b905061159461155e6020860186613c5b565b67ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810181169015011590565b156115ca576115c3846115a8600184613da7565b6115b3906020613b83565b6115be90602e613dba565b612378565b91506115d7565b6115d48185612439565b91505b5092915050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b805461160b83826124c8565b60018201805467ffffffffffffffff1690600061162783613dcd565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508273ffffffffffffffffffffffffffffffffffffffff167fbb3dce316c712fb2d056f7fa51a217f3d2a78d741e08da11b1315c935a1575c78260405161169691815260200190565b60405180910390a2505050565b7f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987c547f1bd9574fa2d2b70f178f484f2cf807c49fe88c9b73ae1c727aa7a826b356987b9067ffffffffffffffff167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffccbb0016110dc5780546117299061090390600290613bf8565b60010180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000169055565b6000610b5a612524565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290605084146117ca576040517f2764198c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160c08101909152806117e460246004888a613dfa565b6117ed91613e24565b815260200161180060446024888a613dfa565b61180991613e24565b815260200161181c60046000888a613dfa565b61182591613e60565b60e01c815260200161183b60486044888a613dfa565b61184491613e60565b60e01c815260200161185a6050604c888a613dfa565b61186391613e60565b60e01c8152602001611879604c6048888a613dfa565b61188291613e60565b7fffffffff0000000000000000000000000000000000000000000000000000000016905291506118b28585612598565b9050821561197d576118cd826040015163ffffffff16612678565b63ffffffff16604083015281516118e390611985565b825260208201516118f390611985565b6020830152606082015161190c9063ffffffff16612678565b63ffffffff16606083015260a08201516119289060e01c612678565b60e01b7fffffffff000000000000000000000000000000000000000000000000000000001660a083015260808201516119669063ffffffff16612678565b63ffffffff16608083015261197a81611985565b90505b935093915050565b600081151960c01c70010000000000000000000000000000000102602081811b8218601081811b8218600881811b8218808916821b9189901c1617808216831b921c1617808216831b921c1617808216604090811b91901c90911617608081811b91901c17610610565b6000836119fd8685856126b1565b1495945050505050565b6000807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00610c89565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060917fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1009161057890613975565b606060007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100610567565b6000610610611ab8611754565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b600080600080611b05888888886127c1565b925092509250611b1582826128bb565b50909695505050505050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0073ffffffffffffffffffffffffffffffffffffffff8516611b92576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff8416611be2576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b73ffffffffffffffffffffffffffffffffffffffff80861660009081526001830160209081526040808320938816835292905220839055811561096a578373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051611c7e91815260200190565b60405180910390a35050505050565b6000610990611c9c84846129bf565b611d1984600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b6129cb565b6040517f6c656166310000000000000000000000000000000000000000000000000000006020820152602581018290526000906002906045015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611d9091613ec5565b602060405180830381855afa158015611dad573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106109190613ee1565b6040517f6e6f646531000000000000000000000000000000000000000000000000000000602082015260258101839052604581018290526000906002906065015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611e4991613ec5565b602060405180830381855afa158015611e66573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109909190613ee1565b600080611e99868563ffffffff16565b905084875b600081118015611ed0575060008a8a611eb8600185613da7565b818110611ec757611ec7613c0c565b90506020020135145b15611ee557611ede81613efa565b9050611e9e565b805b8015611f71576000611efa600183613da7565b90508084901c600116600103611f3757611f308c8c83818110611f1f57611f1f613c0c565b90506020020135868963ffffffff16565b9450611f60565b611f5d858d8d84818110611f4d57611f4d613c0c565b905060200201358963ffffffff16565b94505b50611f6a81613efa565b9050611ee7565b50919998505050505050505050565b6000611017868686611f928688612ae0565b612b6e612bac611e89565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16612004576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61200e611f9d565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0361205a8482613f76565b506004810161127e8382613f76565b612071611f9d565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1026120bd8482613f76565b50600381016120cc8382613f76565b5060008082556001909101555050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0073ffffffffffffffffffffffffffffffffffffffff8416612137578181600201600082825461212c9190613dba565b909155506121e99050565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208290526040902054828110156121bd576040517fe450d38c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024810182905260448101849052606401610a0a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526020839052604090209083900390555b73ffffffffffffffffffffffffffffffffffffffff8316612214576002810180548390039055612240565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020829052604090208054830190555b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161229f91815260200190565b60405180910390a350505050565b6000610610826000612378565b60006109908360016122cb85612bf1565b6115be9190613dba565b6040517f61646472657373000000000000000000000000000000000000000000000000006020820152602781018390527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b166047820152600090600290605b01611e11565b600061236d826123526020860186613c5b565b67ffffffffffffffff166123669190613bf8565b6001612c09565b610990906001613dba565b60408051602080825281830190925260009182919060208201818036833701905050905060005b6020811015612424576123b560208601866139c2565b6123bf8387613dba565b8181106123ce576123ce613c0c565b9050602002013560001c60f81b8282815181106123ed576123ed613c0c565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010161239f565b50808060200190518101906115d49190613ee1565b6000805b612448600185613da7565b8110156115d7576000612460846115b3846020613b83565b90508015801561246e575082155b1561247957506124c0565b600080848103612497578261248d85612cb3565b90925090506124b0565b60008390036124aa578461248d85612cb3565b50819050835b6124ba8282612bac565b94505050505b60010161243d565b73ffffffffffffffffffffffffffffffffffffffff8216612518576040517fec442f0500000000000000000000000000000000000000000000000000000000815260006004820152602401610a0a565b6110f1600083836120dc565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61254f612ce8565b612557612d64565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60008060028085856040516125ae92919061408f565b602060405180830381855afa1580156125cb573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906125ee9190613ee1565b60405160200161260091815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261263891613ec5565b602060405180830381855afa158015612655573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906115d49190613ee1565b600061061082601881811b63ff00000016600883811b62ff0000169190911761ff009184901c919091161760ff9290911c919091161790565b825160009083906060835b828110156127b5576001861615612716578781815181106126df576126df613c0c565b602002602001015184604051602001612702929190918252602082015260400190565b60405160208183030381529060405261275b565b8388828151811061272957612729613c0c565b602002602001015160405160200161274b929190918252602082015260400190565b6040516020818303038152906040525b915061276682612dba565b1561279d576040517f4d3d606a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127a6826131f7565b600196871c96909450016126bc565b50919695505050505050565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156127fc57506000915060039050826128b1565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015612850573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166128a7575060009250600191508290506128b1565b9250600091508190505b9450945094915050565b60008260038111156128cf576128cf61409f565b036128d8575050565b60018260038111156128ec576128ec61409f565b03612923576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028260038111156129375761293761409f565b03612971576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610a0a565b60038260038111156129855761298561409f565b036110f1576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610a0a565b600061099082846140ce565b600080612aca8460007f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f33333333333333333333333333333333333333333333333333333333333333337f555555555555555555555555555555555555555555555555555555555555555584151960c01c70010000000000000000000000000000000102602081811b8218601081811b8218600881811b8218808c16821b918c901c1617808216831b921c1617808216831b921c1617808216604090811b91901c90911617608081811b91901c17600181811c831692909116901b17600281811c831692909116901b17600481811c831692909116901b1792915050565b9050612ad883610100613da7565b1c9392505050565b600061099083612b6384600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b611d19906001613dba565b6040517f6c65616632000000000000000000000000000000000000000000000000000000602082015260258101829052600090600290604501611d58565b6040517f6e6f64653200000000000000000000000000000000000000000000000000000060208201526025810183905260458101829052600090600290606501611e11565b6000612bfe826020613b83565b61061090602e613dba565b600080612c8984600160806fffffffffffffffffffffffffffffffff83110291821c604067ffffffffffffffff82110290811c602063ffffffff82110290811c601061ffff82110290811c600860ff82110290811c6004600f82110290811c6002600382110290811c969096119490960192909201010192909201010190565b9050612cab612c978461325c565b8015612ca6575084826001901b105b151590565b019392505050565b600081600003612cc7576106106000612b6e565b6000612cdc612cd7600185613da7565b612cb3565b90506109908182612bac565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10081612d14611a30565b805190915015612d2c57805160209091012092915050565b81548015612d3b579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10081612d90611a81565b805190915015612da857805160209091012092915050565b60018201548015612d3b579392505050565b6000603c82511015612dce57506000919050565b600082600081518110612de357612de3613c0c565b016020015160f81c90506001811080612dfc5750600281115b15612e0a5750600092915050565b50815160009083906001908110612e2357612e23613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612e5757506000919050565b815160009083906002908110612e6f57612e6f613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612ea357506000919050565b815160009083906003908110612ebb57612ebb613c0c565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614612eef57506000919050565b6004600080612efe8584613289565b67ffffffffffffffff909116925060ff1690506000828103612f7f57506001612f26846140e2565b9350858481518110612f3a57612f3a613c0c565b60209101015160f81c600114612f565750600095945050505050565b612f5f846140e2565b9350612f6b8685613289565b67ffffffffffffffff909116935060ff1691505b612f898285613dba565b9350600060048751612f9b9190613da7565b90508085612faa866029613b83565b612fb49190613dba565b10612fc6575060009695505050505050565b6000805b8581101561304857612fdd602088613dba565b9650612fea600488613dba565b9650612ff68988613289565b60ff16955067ffffffffffffffff1691506130118583613dba565b61301b9088613dba565b96508287106130335750600098975050505050505050565b61303e600488613dba565b9650600101612fca565b5060006130558988613289565b60ff16955067ffffffffffffffff1690508287613073836009613b83565b61307d9190613dba565b11156130925750600098975050505050505050565b61309c8588613dba565b965060005b81811015613107576130b4600889613dba565b97506130c08a89613289565b60ff16965067ffffffffffffffff1692506130db8684613dba565b6130e59089613dba565b9750838811156130ff575060009998505050505050505050565b6001016130a1565b5083156131d25760005b868110156131d05760006131258b8a613289565b60ff16975067ffffffffffffffff169050613140878a613dba565b98508461314d8a83613dba565b1115613164575060009a9950505050505050505050565b60005b818110156131c657600061317b8d8c613289565b60ff16995067ffffffffffffffff169050613196818a613dba565b6131a0908c613dba565b9a50868b11156131bd575060009c9b505050505050505050505050565b50600101613167565b5050600101613111565b505b8287146131e85750600098975050505050505050565b50600198975050505050505050565b60006002808360405161320a9190613ec5565b602060405180830381855afa158015613227573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061324a9190613ee1565b604051602001611d5891815260200190565b600060028260038111156132725761327261409f565b61327c919061411a565b60ff166001149050919050565b6000806132a161329a846001613dba565b85516133df565b60008484815181106132b5576132b5613c0c565b016020015160f81c905060fd8110156132d65760ff169150600190506133d8565b8060ff1660fd0361333c576132f66132ef856003613dba565b86516133df565b61332b61331a613307866001613dba565b613312876003613dba565b889190613419565b6133239061413c565b60f01c61349d565b61ffff169250600391506133d89050565b8060ff1660fe03613395576133556132ef856005613dba565b613382613371613366866001613dba565b613312876005613dba565b61337a906141a8565b60e01c612678565b63ffffffff169250600591506133d89050565b6133a36132ef856009613dba565b6133d06133bf6133b4866001613dba565b613312876009613dba565b6133c890614212565b60c01c6134b8565b925060099150505b9250929050565b808211156110f1576040517f6c95098b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608351828111613428578092505b838111613433578093505b508183101561099057506040518282038484017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830181165b828101518582015281018061346e57505050806020830101600081526020810160405250808252509392505050565b6000600882811c60ff1661ff009184901b9190911617610610565b6000603882811b67ff0000000000000016602884811b66ff0000000000001691909117601885811b65ff00000000001691909117600886811b64ff00000000169190911763ff0000009187901c919091161762ff00009186901c919091161761ff009185901c919091161760ff9184901c9190911617610610565b60005b8381101561354e578181015183820152602001613536565b50506000910152565b6000815180845261356f816020860160208601613533565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109906020830184613557565b803573ffffffffffffffffffffffffffffffffffffffff811681146135d857600080fd5b919050565b600080604083850312156135f057600080fd5b6135f9836135b4565b946020939093013593505050565b60006080828403121561361957600080fd5b50919050565b60006020828403121561363157600080fd5b813567ffffffffffffffff81111561364857600080fd5b6115d484828501613607565b60008060006060848603121561366957600080fd5b613672846135b4565b9250613680602085016135b4565b929592945050506040919091013590565b6000602082840312156136a357600080fd5b813567ffffffffffffffff8111156136ba57600080fd5b82016060818503121561099057600080fd5b60008083601f8401126136de57600080fd5b50813567ffffffffffffffff8111156136f657600080fd5b6020830191508360208285010111156133d857600080fd5b600080600080600080600060a0888a03121561372957600080fd5b873567ffffffffffffffff81111561374057600080fd5b8801601f81018a1361375157600080fd5b803567ffffffffffffffff81111561376857600080fd5b8a60208260051b840101111561377d57600080fd5b60209182019850965088013567ffffffffffffffff81111561379e57600080fd5b6137aa8a828b016136cc565b9096509450506040880135925060608801359150608088013567ffffffffffffffff8111156137d857600080fd5b6137e48a828b01613607565b91505092959891949750929550565b60006020828403121561380557600080fd5b610990826135b4565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e06020820152600061384960e0830189613557565b828103604084015261385b8189613557565b6060840188905273ffffffffffffffffffffffffffffffffffffffff8716608085015260a0840186905283810360c08501528451808252602080870193509091019060005b818110156138be5783518352602093840193909201916001016138a0565b50909b9a5050505050505050505050565b600080600080600080600060e0888a0312156138ea57600080fd5b6138f3886135b4565b9650613901602089016135b4565b95506040880135945060608801359350608088013560ff8116811461392557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561395557600080fd5b61395e836135b4565b915061396c602084016135b4565b90509250929050565b600181811c9082168061398957607f821691505b602082108103613619577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126139f757600080fd5b83018035915067ffffffffffffffff821115613a1257600080fd5b6020019150600581901b36038213156133d857600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6001815b600184111561197d57808504811115613a7857613a78613a2a565b6001841615613a8657908102905b60019390931c928002613a5d565b600082613aa357506001610610565b81613ab057506000610610565b8160018114613ac65760028114613ad057613aec565b6001915050610610565b60ff841115613ae157613ae1613a2a565b50506001821b610610565b5060208310610133831016604e8410600b8410161715613b0f575081810a610610565b613b3a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613a59565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613b6c57613b6c613a2a565b029392505050565b600061099060ff841683613a94565b808202811582820484141761061057610610613a2a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082613c0757613c07613bc9565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff818116838216019081111561061057610610613a2a565b600060208284031215613c6d57600080fd5b813567ffffffffffffffff8116811461099057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613cba57600080fd5b83018035915067ffffffffffffffff821115613cd557600080fd5b6020019150368190038213156133d857600080fd5b604081528360408201528385606083013760006060858301015260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116820160608382030160208401528360608201527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841115613d6c57600080fd5b8360051b80866080840137016080019695505050505050565b600060208284031215613d9757600080fd5b8151801515811461099057600080fd5b8181038181111561061057610610613a2a565b8082018082111561061057610610613a2a565b600067ffffffffffffffff821667ffffffffffffffff8103613df157613df1613a2a565b60010192915050565b60008085851115613e0a57600080fd5b83861115613e1757600080fd5b5050820193919092039150565b80356020831015610610577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b80357fffffffff0000000000000000000000000000000000000000000000000000000081169060048410156115d7577fffffffff00000000000000000000000000000000000000000000000000000000808560040360031b1b82161691505092915050565b60008251613ed7818460208701613533565b9190910192915050565b600060208284031215613ef357600080fd5b5051919050565b600081613f0957613f09613a2a565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b601f821115610ff557806000526020600020601f840160051c81016020851015613f565750805b601f840160051c820191505b8181101561096a5760008155600101613f62565b815167ffffffffffffffff811115613f9057613f90613b9a565b613fa481613f9e8454613975565b84613f2f565b6020601f821160018114613ff65760008315613fc05750848201515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b17845561096a565b6000848152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08516915b828110156140445787850151825560209485019460019092019101614024565b508482101561408057868401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b60f8161c191681555b50505050600190811b01905550565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000826140dd576140dd613bc9565b500690565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361411357614113613a2a565b5060010190565b600060ff83168061412d5761412d613bc9565b8060ff84160691505092915050565b805160208201517fffff0000000000000000000000000000000000000000000000000000000000008116919060028210156141a1577fffff000000000000000000000000000000000000000000000000000000000000808360020360031b1b82161692505b5050919050565b805160208201517fffffffff000000000000000000000000000000000000000000000000000000008116919060048210156141a1577fffffffff0000000000000000000000000000000000000000000000000000000060049290920360031b82901b161692915050565b805160208201517fffffffffffffffff0000000000000000000000000000000000000000000000008116919060088210156141a1577fffffffffffffffff00000000000000000000000000000000000000000000000060089290920360031b82901b16169291505056fea164736f6c634300081c000a", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/src/examples/test/helpers/block-helpers.ts b/src/examples/test/helpers/block-helpers.ts new file mode 100644 index 0000000..bb93e17 --- /dev/null +++ b/src/examples/test/helpers/block-helpers.ts @@ -0,0 +1,91 @@ +import * as fs from "fs"; +import path from "path"; +import { randomInt } from "crypto"; + +import { BlockHeaderData, ReorgBlocksData } from "./types"; + +export function getRandomBlockHeaderData(pathToDataFile: string, minHeight: number, maxHeight: number) { + const randHeight = randomInt(minHeight, maxHeight + 1); + + return getBlockHeaderData(pathToDataFile, randHeight); +} + +export function getBlocksDataFilePath(fileName: string): string { + return path.join(__dirname, "../data", fileName); +} + +export function getReorgBlockHeaderData( + pathToDataFile: string, + height: number, + isMainchain: boolean = true, +): BlockHeaderData { + const blocksData = JSON.parse(fs.readFileSync(pathToDataFile, "utf-8")) as ReorgBlocksData; + const firstElementHeight = isMainchain + ? blocksData.mainchainHeaders[0].height + : blocksData.forkChainHeaders[0].height; + + return isMainchain + ? formatBlockHeaderData(blocksData.mainchainHeaders[height - Number(firstElementHeight)]) + : formatBlockHeaderData(blocksData.forkChainHeaders[height - Number(firstElementHeight)]); +} + +export function getReorgBlockHeaderDataBatch( + pathToDataFile: string, + height: number, + batchSize: number, + isMainchain: boolean = true, +): BlockHeaderData[] { + const allBlocksDataArr = JSON.parse(fs.readFileSync(pathToDataFile, "utf-8")) as ReorgBlocksData; + const firstElementHeight = isMainchain + ? allBlocksDataArr.mainchainHeaders[0].height + : allBlocksDataArr.forkChainHeaders[0].height; + + const blocksData = []; + + for (let i = 0; i < batchSize; i++) { + blocksData.push( + isMainchain + ? formatBlockHeaderData(allBlocksDataArr.mainchainHeaders[height + i - Number(firstElementHeight)]) + : formatBlockHeaderData(allBlocksDataArr.forkChainHeaders[height + i - Number(firstElementHeight)]), + ); + } + + return blocksData; +} + +export function getBlockHeaderData(pathToDataFile: string, height: number): BlockHeaderData { + const allBlocksDataArr = JSON.parse(fs.readFileSync(pathToDataFile, "utf-8")) as BlockHeaderData[]; + const firstElementHeight = allBlocksDataArr[0].height; + + return formatBlockHeaderData(allBlocksDataArr[height - Number(firstElementHeight)]); +} + +export function getBlockHeaderDataBatch(pathToDataFile: string, height: number, batchSize: number): BlockHeaderData[] { + const allBlocksDataArr = JSON.parse(fs.readFileSync(pathToDataFile, "utf-8")) as BlockHeaderData[]; + const firstElementHeight = allBlocksDataArr[0].height; + + const blocksData = []; + + for (let i = 0; i < batchSize; i++) { + blocksData.push(formatBlockHeaderData(allBlocksDataArr[height + i - Number(firstElementHeight)])); + } + + return blocksData; +} + +export function formatBlockHeaderData(headerData: BlockHeaderData): BlockHeaderData { + headerData.blockHash = addHexPrefix(headerData.blockHash); + headerData.rawHeader = addHexPrefix(headerData.rawHeader); + headerData.parsedBlockHeader.hash = addHexPrefix(headerData.parsedBlockHeader.hash); + headerData.parsedBlockHeader.previousblockhash = addHexPrefix(headerData.parsedBlockHeader.previousblockhash); + headerData.parsedBlockHeader.nextblockhash = addHexPrefix(headerData.parsedBlockHeader.previousblockhash); + headerData.parsedBlockHeader.merkleroot = addHexPrefix(headerData.parsedBlockHeader.merkleroot); + headerData.parsedBlockHeader.bits = addHexPrefix(headerData.parsedBlockHeader.bits); + headerData.parsedBlockHeader.chainwork = addHexPrefix(headerData.parsedBlockHeader.chainwork); + + return headerData; +} + +function addHexPrefix(str: string): string { + return `0x${str}`; +} diff --git a/src/examples/test/helpers/history-proof.ts b/src/examples/test/helpers/history-proof.ts new file mode 100644 index 0000000..a6fa912 --- /dev/null +++ b/src/examples/test/helpers/history-proof.ts @@ -0,0 +1,73 @@ +import * as fs from "fs"; +import { ethers } from "hardhat"; +import path from "path"; + +import { SimpleMerkleTree } from "@openzeppelin/merkle-tree"; +import { HexString, BytesLike } from "@openzeppelin/merkle-tree/dist/bytes"; + +export function getHistoryProofDirPath(provedBlocksCount: bigint, isDefaultAddr: boolean = true): string { + const fileNameSuffix = isDefaultAddr ? `_d` : `_c`; + + return path.join(__dirname, `../data/history_proof`, `${provedBlocksCount.toString()}${fileNameSuffix}`); +} + +export function getHistoryProofFromFile(proofDirPath: string, proofFileName: string = "proof_fields.json"): string { + const filePath = path.join(proofDirPath, proofFileName); + const proofDataArr = JSON.parse(fs.readFileSync(filePath, "utf-8")) as string[]; + + return "0x" + proofDataArr.map((el: string) => el.slice(2)).join(""); +} + +export function getHistoryProofPublicInputsFromFile( + proofDirPath: string, + publicInputsFileName: string = "public_inputs_fields.json", +): string[] { + const filePath = path.join(proofDirPath, publicInputsFileName); + const publicInputsDataArr = JSON.parse(fs.readFileSync(filePath, "utf-8")) as string[]; + + return publicInputsDataArr; +} + +export function getLevel1TreeRootsFromFile( + proofDirPath: string, + level1TreeRootsFileName: string = "level1TreeRoots.json", +): string[] { + const filePath = path.join(proofDirPath, level1TreeRootsFileName); + const level1TreeRoots = JSON.parse(fs.readFileSync(filePath, "utf-8")) as string[]; + + return level1TreeRoots; +} + +export function buildLevel2MerkleTree(level1Hashes: string[]): SimpleMerkleTree { + const realValuesLength = Math.pow(2, Math.ceil(Math.log2(level1Hashes.length))); + const valuesPadded = [ + ...level1Hashes, + ...new Array(realValuesLength - level1Hashes.length).fill(ethers.ZeroHash), + ]; + + const leaves = valuesPadded.map((value) => hashLevel2TreeLeaf(value)).reverse(); + + return SimpleMerkleTree.of(leaves, { nodeHash: hashLevel2TreeNode, sortLeaves: false }); +} + +export function buildLevel1MerkleTree(blockHashes: string[]): SimpleMerkleTree { + const leaves = blockHashes.map((blockHash) => hashLevel1TreeLeaf(blockHash)).reverse(); + + return SimpleMerkleTree.of(leaves, { nodeHash: hashLevel1TreeNode, sortLeaves: false }); +} + +export function hashLevel2TreeNode(left: BytesLike, right: BytesLike): HexString { + return ethers.solidityPackedSha256(["string", "bytes32", "bytes32"], ["node2", left, right]); +} + +export function hashLevel2TreeLeaf(value: string): string { + return ethers.solidityPackedSha256(["string", "bytes32"], ["leaf2", value]); +} + +export function hashLevel1TreeNode(left: BytesLike, right: BytesLike): HexString { + return ethers.solidityPackedSha256(["string", "bytes32", "bytes32"], ["node1", left, right]); +} + +export function hashLevel1TreeLeaf(value: string): string { + return ethers.solidityPackedSha256(["string", "bytes32"], ["leaf1", value]); +} diff --git a/src/examples/test/helpers/index.ts b/src/examples/test/helpers/index.ts new file mode 100644 index 0000000..7f9dd25 --- /dev/null +++ b/src/examples/test/helpers/index.ts @@ -0,0 +1,5 @@ +export * from "./reverter"; +export * from "./block-helpers"; +export * from "./history-proof"; +export * from "./parse-proof-helpers"; +export * from "./types"; diff --git a/src/examples/test/helpers/parse-proof-helpers.ts b/src/examples/test/helpers/parse-proof-helpers.ts new file mode 100644 index 0000000..c37f751 --- /dev/null +++ b/src/examples/test/helpers/parse-proof-helpers.ts @@ -0,0 +1,206 @@ +import { sha256, ZeroHash } from "ethers"; + +export class MerkleRawProofParser { + private txidReversed: string; + private txCountInBlock: number; + private hashes: string[]; + private flagPath: string; + private maxDepth: number; + private nodeCountPerLevel: number[]; + private txIndex: number; + private siblings: string[]; + + constructor(txid: string, rawProof: string) { + this.txidReversed = reverseBytes(txid); + + const withoutHeader = rawProof.slice(160); + + const txCountOffset = 8; + let offset = txCountOffset; + + const txCountRaw = withoutHeader.slice(0, offset); + this.txCountInBlock = parseInt(reverseBytes(txCountRaw), 16); + const [hashCount, hashCountSize] = parseCuint(withoutHeader, offset); + + offset += hashCountSize; + + const rawHashes = withoutHeader.slice(offset, offset + Number(hashCount) * 64); + + this.hashes = []; + for (let i = 0; i < hashCount; i++) { + this.hashes.push(addHexPrefix(rawHashes.slice(i * 64, (i + 1) * 64))); + } + + offset = offset + Number(hashCount) * 64; + + const [byteFlagsCount, byteFlagsCountSize] = parseCuint(withoutHeader, offset); + + offset += byteFlagsCountSize; + + const byteFlags = withoutHeader.slice(offset, offset + 2 * Number(byteFlagsCount)); + + this.flagPath = this.processFlags(byteFlags); + this.maxDepth = Math.ceil(Math.log2(this.txCountInBlock)); + this.nodeCountPerLevel = this.getNodeCountPerLevel(this.txCountInBlock, this.maxDepth); + + [this.txIndex, this.siblings] = this.processTree(0, 0, 0, 0, 0, []); + } + + getTxidReversed(): string { + return this.txidReversed; + } + + getTxIndex(): number { + return this.txIndex; + } + + getSiblings(): string[] { + return this.siblings; + } + + private processFlags(flagBytes: string): string { + let directions = ""; + + for (let i = 0; i < flagBytes.length; i += 2) { + directions += reverseByte(flagBytes.substring(i, i + 2)); + } + + return directions; + } + + private getNodeCountPerLevel(txCount: number, depth: number): number[] { + let result: number[] = []; + let levelSize = txCount; + + for (let i = depth; i >= 0; i--) { + result[depth] = levelSize; + + levelSize = Math.ceil(levelSize / 2); + depth--; + } + + return result; + } + + private calculateSiblings(leaf: string, txIndex: number, sortedHashes: string[]): string[] { + let computedHash = leaf; + + for (let i = 0; i < sortedHashes.length; i++) { + if (sortedHashes[i] == ZeroHash) { + sortedHashes[i] = computedHash; + } + + const pairToHash = + (txIndex & 1) == 0 + ? computedHash.slice(2) + sortedHashes[i].slice(2) + : sortedHashes[i].slice(2) + computedHash.slice(2); + + computedHash = sha256(sha256(addHexPrefix(pairToHash))); + + txIndex = txIndex / 2; + } + + return sortedHashes; + } + + private processTree( + depth: number, + currentFlag: number, + txIndex: number, + currentHash: number, + nodePosition: number, + sortedHashes: string[], + ): [number, string[]] { + if (depth == this.maxDepth && this.flagPath.at(currentFlag) == "1") { + // this is the tx we searched for + const leaf = this.hashes[currentHash]; + + if (this.isNodeWithoutPair(depth, nodePosition)) { + sortedHashes.push(this.hashes[currentHash]); + } else if (this.hasSiblingAtRight(nodePosition, currentHash)) { + sortedHashes.push(this.hashes[currentHash + 1]); + } + + sortedHashes.reverse(); + + const siblings = this.calculateSiblings(leaf, txIndex, sortedHashes); + + return [txIndex, siblings]; + } + + if (depth == this.maxDepth) { + // this is neighbour of the tx we searched for + sortedHashes.push(this.hashes[currentHash]); + + return this.processTree(depth, currentFlag + 1, txIndex + 1, currentHash + 1, nodePosition + 1, sortedHashes); + } + + if (this.flagPath.at(currentFlag) == "1") { + if (this.isNodeWithoutPair(depth, nodePosition)) { + sortedHashes.push(ZeroHash); + } else if (this.isLeftNode(depth, nodePosition)) { + const rightNodeHash = this.hashes.pop(); + + if (!rightNodeHash) throw Error(`No hashes left at depth ${depth}`); + + sortedHashes.push(rightNodeHash); + } + + return this.processTree(depth + 1, currentFlag + 1, txIndex, currentHash, nodePosition * 2, sortedHashes); + } + + const txSkipped = 2 ** (this.maxDepth - depth); + + sortedHashes.push(this.hashes[currentHash]); + + return this.processTree( + depth, + currentFlag + 1, + txIndex + txSkipped, + currentHash + 1, + nodePosition + 1, + sortedHashes, + ); + } + + private nodesCountIsOdd(level: number): boolean { + return (this.nodeCountPerLevel[level]! & 1) == 1; + } + + private isNodeWithoutPair(depth: number, nodePosition: number): boolean { + return depth != 0 && this.nodesCountIsOdd(depth) && nodePosition + 1 == this.nodeCountPerLevel[depth]; + } + + private isLeftNode(depth: number, nodePosition: number): boolean { + return depth != 0 && (nodePosition & 1) == 0; + } + + private hasSiblingAtRight(nodePosition: number, currentHash: number): boolean { + return (nodePosition & 1) == 0 && currentHash + 1 < this.hashes.length; + } +} + +function reverseBytes(str: string) { + if (str.slice(0, 2) == "0x") str = str.slice(2); + + return "0x" + Buffer.from(str, "hex").reverse().toString("hex"); +} + +function reverseByte(byte: string): string { + const binary = parseInt(byte, 16).toString(2); + const padded = binary.padStart(8, "0"); + return padded.split("").reverse().join(""); +} + +function parseCuint(data: string, offset: number): [number, number] { + const firstByte = parseInt(data.slice(offset, offset + 2), 16); + + if (firstByte < 0xfd) return [parseInt(data.slice(offset, offset + 2), 16), 2]; + if (firstByte == 0xfd) return [parseInt(data.slice(offset + 2, offset + 6), 16), 6]; + if (firstByte == 0xfe) return [parseInt(data.slice(offset + 2, offset + 10), 16), 10]; + return [parseInt(data.slice(offset + 2, offset + 18), 16), 18]; +} + +function addHexPrefix(str: string): string { + return `0x${str}`; +} diff --git a/src/examples/test/helpers/reverter.ts b/src/examples/test/helpers/reverter.ts new file mode 100644 index 0000000..255b5d7 --- /dev/null +++ b/src/examples/test/helpers/reverter.ts @@ -0,0 +1,14 @@ +import { network } from "hardhat"; + +export class Reverter { + private snapshotId: any; + + revert = async () => { + await network.provider.send("evm_revert", [this.snapshotId]); + await this.snapshot(); + }; + + snapshot = async () => { + this.snapshotId = await network.provider.send("evm_snapshot", []); + }; +} diff --git a/src/examples/test/helpers/types.ts b/src/examples/test/helpers/types.ts new file mode 100644 index 0000000..883c2db --- /dev/null +++ b/src/examples/test/helpers/types.ts @@ -0,0 +1,38 @@ +import { BigNumberish } from "ethers"; + +export type ReorgBlocksData = { + mainchainHeaders: BlockHeaderData[]; + forkChainHeaders: BlockHeaderData[]; +}; + +export type BlockHeaderData = { + height: BigNumberish; + blockHash: string; + rawHeader: string; + parsedBlockHeader: ParsedBlockHeaderData; +}; + +export type ParsedBlockHeaderData = { + hash: string; + confirmations: BigNumberish; + height: BigNumberish; + version: BigNumberish; + versionHex: BigNumberish; + merkleroot: string; + time: BigNumberish; + mediantime: BigNumberish; + nonce: BigNumberish; + bits: string; + difficulty: BigNumberish; + chainwork: string; + nTx: BigNumberish; + previousblockhash: string; + nextblockhash: string; +}; + +export enum BlockStatus { + Unknown = 0, + Pending = 1, + Stale = 2, + Confirmed = 3, +} diff --git a/src/examples/tsconfig.json b/src/examples/tsconfig.json new file mode 100644 index 0000000..ef6d5d6 --- /dev/null +++ b/src/examples/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "paths": { + "@/*": ["./*"], + "@zkit": ["./generated-types/zkit"], + "@ethers-v6": ["./generated-types/ethers"], + "@test-helpers": ["./test/helpers"], + "@scripts": ["./scripts"] + } + } +}