Source Code
Overview
DEV Balance
0 DEV
More Info
ContractCreator
Multichain Info
N/A
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
9887134 | 3 mins ago | 0 DEV | ||||
9887099 | 7 mins ago | 0 DEV | ||||
9887063 | 11 mins ago | 0 DEV | ||||
9887032 | 14 mins ago | 0 DEV | ||||
9886994 | 17 mins ago | 0 DEV | ||||
9886960 | 21 mins ago | 0 DEV | ||||
9886926 | 24 mins ago | 0 DEV | ||||
9886888 | 28 mins ago | 0 DEV | ||||
9886855 | 31 mins ago | 0 DEV | ||||
9886818 | 35 mins ago | 0 DEV | ||||
9886783 | 39 mins ago | 0 DEV | ||||
9886748 | 42 mins ago | 0 DEV | ||||
9886712 | 46 mins ago | 0 DEV | ||||
9886676 | 49 mins ago | 0 DEV | ||||
9886642 | 53 mins ago | 0 DEV | ||||
9886606 | 56 mins ago | 0 DEV | ||||
9886570 | 1 hr ago | 0 DEV | ||||
9886538 | 1 hr ago | 0 DEV | ||||
9886500 | 1 hr ago | 0 DEV | ||||
9886467 | 1 hr ago | 0 DEV | ||||
9886432 | 1 hr ago | 0 DEV | ||||
9886393 | 1 hr ago | 0 DEV | ||||
9886361 | 1 hr ago | 0 DEV | ||||
9886325 | 1 hr ago | 0 DEV | ||||
9886287 | 1 hr ago | 0 DEV |
Loading...
Loading
Contract Name:
BlockSpecimenProofChain
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./IOperationalStaking.sol"; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract BlockSpecimenProofChain is OwnableUpgradeable { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set; IOperationalStaking _stakingInterface; // staking contract (deprecated) bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE"); bytes32 public constant BLOCK_SPECIMEN_PRODUCER_ROLE = keccak256("BLOCK_SPECIMEN_PRODUCER_ROLE"); bytes32 public constant AUDITOR_ROLE = keccak256("AUDITOR_ROLE"); uint256 private constant _DIVIDER = 10 ** 18; // 18 decimals used for scaling uint256 private _blockSpecimenQuorum; // The value is represented as a uint <= 10**18. The threshold value will later be divided by 10**18 to represent it as a percentage. e.g.) 10**18 == 100%; 5 * 10**17 == 50%; uint256 private _secondsPerBlockCurrentChain; // average block time on the chain where the ProofChain is deployed uint128 private _blockSpecimenRewardAllocation; // the reward allocated per block hash uint128 private _bspRequiredStake; // how much a validator should have staked in order to run an operator uint64 private _blockSpecimenSessionDuration; // the length of a session in blocks uint64 private _minSubmissionsRequired; // min number of participants who submitted the agreed specimen hash in order for the quorum to be achieved EnumerableSetUpgradeable.Bytes32Set private _roleNames; // set of all role names EnumerableSetUpgradeable.AddressSet private _blockSpecimenProducers; // currently enabled block specimen producer operators EnumerableSetUpgradeable.AddressSet private _governors; // governor operators EnumerableSetUpgradeable.AddressSet private _auditors; // auditor operators mapping(address => uint128) public validatorIDs; // maps an operator address to validatorId mapping(uint128 => EnumerableSetUpgradeable.AddressSet) private _validatorOperators; // operator addresses that validator owns mapping(address => bytes32) public operatorRoles; // operator address => role mapping(uint128 => uint128) private _validatorActiveOperatorsCounters; // how many operators are enabled per validator given validator id mapping(uint64 => mapping(uint64 => BlockSpecimenSession)) private _sessions; // chainId => blockHeight mapping(uint64 => ChainData) private _chainData; // by chain id mapping(bytes32 => string[]) private _urls; // hash => urls mapping(uint128 => address) private _validatorAddresses; // validatorId => validator address (deprecated) mapping(uint128 => bool) private _validatorEnabled; // validatorId => enabled? address private _stakingManager; struct ChainData { uint256 blockOnTargetChain; // block number on the chain for which BSP are produced which is mapped to the current chain block uint256 blockOnCurrentChain; // block number on the chain where the ProofChain is deployed. it is mapped to the target chain block uint256 secondsPerBlockTargetChain; // average block time on the chain for which BSP is generated uint128 allowedThreshold; // block offsett threshold, used to handle minor de-synchronization over time uint128 maxSubmissionsPerBlockHeight; // max number of block hashes allowed to submit per block height uint64 nthBlock; // block divisor } struct BlockProperties { mapping(bytes32 => address[]) participants; // specimen hash => operators who submitted the specimen hash bytes32[] specimenHashes; // raw specimen hashes } struct SessionParticipantData { uint128 stake; // stake at the time when an operator submitted the first specimen hash (deprecate now (always 0)) uint128 submissionCounter; // how many specimen hashes an operator has submitted } struct BlockSpecimenSession { mapping(bytes32 => BlockProperties) blockProperties; // block hash => block properties bytes32[] blockHashesRaw; mapping(address => SessionParticipantData) participantsData; // stake and submission counter, pack these together to save gas uint64 sessionDeadline; // the last block when an operator can submit a specimen hash bool isSessionDone; // marker for session finalization } event OperatorAdded(address operator, uint128 validatorId, bytes32 role); event OperatorRemoved(address operator, uint128 validatorId, uint128 activeOperatorCount, bytes32 role); event ValidatorEnabled(uint128 validatorId); event ValidatorDisabled(uint128 validatorId); event BlockSpecimenProductionProofSubmitted( uint64 chainId, uint64 blockHeight, bytes32 blockHash, bytes32 specimenHash, // SHA-256 content-hash of specimen object file; string storageURL // URL of specimen storage ); event SessionStarted(uint64 indexed chainId, uint64 indexed blockHeight, uint64 deadline); event QuorumNotReached(uint64 indexed chainId, uint64 blockHeight); event BlockSpecimenRewardChanged(uint128 newBlockSpecimenRewardAllocation); event MinimumRequiredStakeChanged(uint128 newStakeRequirement); event StakingManagerChanged(address newStakingManager); event SpecimenSessionQuorumChanged(uint256 newQuorumThreshold); event SpecimenSessionDurationChanged(uint64 newSessionDuration); event SpecimenSessionMinSubmissionChanged(uint64 minSubmissions); event NthBlockChanged(uint64 indexed chainId, uint64 indexed nthBlock); event MaxSubmissionsPerBlockHeightChanged(uint256 maxSubmissions); event ChainSyncDataChanged(uint64 indexed chainId, uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain); event SecondsPerBlockCurrentChainChanged(uint64 indexed secondsPerBlockCurrentChain); event BlockHeightSubmissionThresholdChanged(uint64 indexed chainId, uint64 threshold); event BlockSpecimenQuorum(uint64 indexed chainId, uint64 indexed blockHeight, uint256 validatorBitMap, bytes32 indexed blockHash, bytes32 specimenHash); modifier onlyGovernor() { require(_governors.contains(msg.sender), "Sender is not GOVERNANCE_ROLE"); _; } modifier onlyStakingManager() { require(msg.sender == _stakingManager, "Sender is not staking manager"); _; } function initialize(address initialGovernor, address stakingManager) public initializer { require(initialGovernor != address(0), "Invalid governor address"); __Ownable_init(); _governors.add(msg.sender); _roleNames.add(GOVERNANCE_ROLE); _roleNames.add(BLOCK_SPECIMEN_PRODUCER_ROLE); _roleNames.add(AUDITOR_ROLE); setQuorumThreshold(_DIVIDER / 2); // 50% setBlockSpecimenReward(10 ** 14); // 0.0001 setBlockSpecimenSessionDuration(240); // blocks setMinSubmissionsRequired(2); setStakingManagerAddress(stakingManager); _governors.remove(msg.sender); operatorRoles[initialGovernor] = GOVERNANCE_ROLE; _governors.add(initialGovernor); emit OperatorAdded(initialGovernor, 0, GOVERNANCE_ROLE); } function disableValidator(uint128 validatorId) external onlyStakingManager { // when remove/disable bsp is called, it emits an event, which might then cause bridge agent to // disable this. require(validatorId < 256, "validatorId out of range"); _validatorEnabled[validatorId] = false; emit ValidatorDisabled(validatorId); } /** * Enables the given operator on the staking contract */ function enableValidator(uint128 validatorId) external onlyStakingManager { // when addBsp is done, it emits an event, which might then cause bridge agent // to enable this. require(validatorId < 256, "validatorId out of range"); _validatorEnabled[validatorId] = true; emit ValidatorEnabled(validatorId); } /** * Disables the operator instance. * If all addresses of the operator are disabled, then the operator (validator) instance will get disabled on the staking contract */ function _removeBSPOperatorFromActiveInstances(address operator) internal { _blockSpecimenProducers.remove(operator); uint128 validatorId = validatorIDs[operator]; _validatorActiveOperatorsCounters[validatorId]--; } /** * Adds the given address to the block specimen producers set */ function addBSPOperator(address operator, uint128 validatorId) external onlyGovernor { require(operator != address(0), "Invalid operator address"); require(operatorRoles[operator] == 0, "Operator already exists"); require(validatorId <= 255, "Validator ID cannot be greater than 255"); operatorRoles[operator] = BLOCK_SPECIMEN_PRODUCER_ROLE; validatorIDs[operator] = validatorId; _validatorOperators[validatorId].add(operator); _blockSpecimenProducers.add(operator); _validatorActiveOperatorsCounters[validatorId]++; emit OperatorAdded(operator, validatorId, BLOCK_SPECIMEN_PRODUCER_ROLE); } /** * Removes the given address from the block specimen producers set */ function removeBSPOperator(address operator) external onlyGovernor { require(operatorRoles[operator] == BLOCK_SPECIMEN_PRODUCER_ROLE, "Operator is not BSP"); require(_blockSpecimenProducers.contains(operator), "Operator not found in active instances"); _removeBSPOperatorFromActiveInstances(operator); uint128 validatorID = validatorIDs[operator]; _validatorOperators[validatorID].remove(operator); validatorIDs[operator] = 0; operatorRoles[operator] = 0; emit OperatorRemoved(operator, validatorID, _validatorActiveOperatorsCounters[validatorID], BLOCK_SPECIMEN_PRODUCER_ROLE); } /** * Adds the given address to the auditors set */ function addAuditor(address auditor) external onlyGovernor { require(auditor != address(0), "Invalid auditor address"); require(operatorRoles[auditor] == 0, "Operator already exists"); operatorRoles[auditor] = AUDITOR_ROLE; _auditors.add(auditor); emit OperatorAdded(auditor, 0, AUDITOR_ROLE); } /** * Removes the given address from the auditors set */ function removeAuditor(address auditor) external onlyGovernor { require(operatorRoles[auditor] == AUDITOR_ROLE, "Operator is not auditor"); operatorRoles[auditor] = 0; _auditors.remove(auditor); emit OperatorRemoved(auditor, 0, 0, AUDITOR_ROLE); } /** * Adds the given address to the governors set */ function addGovernor(address governor) external onlyOwner { require(governor != address(0), "Invalid governor address"); require(operatorRoles[governor] == 0, "Operator already exists"); operatorRoles[governor] = GOVERNANCE_ROLE; _governors.add(governor); emit OperatorAdded(governor, 0, GOVERNANCE_ROLE); } /** * Removes the given address from the governors set */ function removeGovernor(address governor) external onlyOwner { require(operatorRoles[governor] == GOVERNANCE_ROLE, "Operator is not governor"); operatorRoles[governor] = 0; _governors.remove(governor); emit OperatorRemoved(governor, 0, 0, GOVERNANCE_ROLE); } /** * Updates the address of the staking manager */ function setStakingManagerAddress(address stakingManagerAddress) public onlyGovernor { require(stakingManagerAddress != address(0), "Invalid address"); _stakingManager = stakingManagerAddress; emit StakingManagerChanged(stakingManagerAddress); } /** * Update the Block Specimen Quorum Threshold. */ function setQuorumThreshold(uint256 quorum) public onlyGovernor { require(quorum <= _DIVIDER, "Quorum cannot be greater than 100%"); _blockSpecimenQuorum = quorum; emit SpecimenSessionQuorumChanged(quorum); } /** * Update block divisor */ function setNthBlock(uint64 chainId, uint64 n) public onlyGovernor { require(n > 0, "Nth block cannot be 0"); _chainData[chainId].nthBlock = n; emit NthBlockChanged(chainId, n); } /** * Update the reward allocation per block specimen. */ function setBlockSpecimenReward(uint128 newBlockSpecimenReward) public onlyGovernor { require(newBlockSpecimenReward <= 1000 * _DIVIDER, "Block specimen reward cannot be greater than 1000*DIVIDER"); _blockSpecimenRewardAllocation = newBlockSpecimenReward; emit BlockSpecimenRewardChanged(newBlockSpecimenReward); } /** * Update the duration of a specimen session in blocks */ function setBlockSpecimenSessionDuration(uint64 newSessionDuration) public onlyGovernor { require(newSessionDuration > 0, "Session duration cannot be 0"); _blockSpecimenSessionDuration = newSessionDuration; emit SpecimenSessionDurationChanged(newSessionDuration); } /** * Update the minimum # of submissions required in order to reach quorum */ function setMinSubmissionsRequired(uint64 minSubmissions) public onlyGovernor { require(minSubmissions >= 1, "Minimum submissions must be at least 1"); require(minSubmissions <= 255, "Maximum allowed minimum submissions is 255"); _minSubmissionsRequired = minSubmissions; emit SpecimenSessionMinSubmissionChanged(minSubmissions); } /** * Update the max # of submissions per operator per block height */ function setMaxSubmissionsPerBlockHeight(uint64 chainId, uint64 maxSubmissions) public onlyGovernor { require(maxSubmissions > 0, "Max submissions cannot be 0"); require(maxSubmissions <= 3, "Max submissions cannot be more than 3"); require(_chainData[chainId].nthBlock != 0, "Invalid chain ID"); _chainData[chainId].maxSubmissionsPerBlockHeight = maxSubmissions; emit MaxSubmissionsPerBlockHeightChanged(maxSubmissions); } /** * Update chain sync data */ function setChainSyncData(uint64 chainId, uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain) external onlyGovernor { ChainData storage cd = _chainData[chainId]; require(secondsPerBlockTargetChain > 0, "Seconds per block cannot be 0"); cd.blockOnTargetChain = blockOnTargetChain; cd.blockOnCurrentChain = blockOnCurrentChain; cd.secondsPerBlockTargetChain = secondsPerBlockTargetChain; emit ChainSyncDataChanged(chainId, blockOnTargetChain, blockOnCurrentChain, secondsPerBlockTargetChain); } /** * Update block height submission threshold for live sync */ function setBlockHeightSubmissionsThreshold(uint64 chainId, uint64 threshold) external onlyGovernor { require(threshold > 0, "Threshold cannot be 0"); _chainData[chainId].allowedThreshold = threshold; emit BlockHeightSubmissionThresholdChanged(chainId, threshold); } /** * Update seconds per block on the chain where the ProofChain is deployed */ function setSecondsPerBlockCurrentChain(uint64 secondsPerBlockCurrentChain) external onlyGovernor { require(secondsPerBlockCurrentChain > 0, "Seconds per block cannot be 0"); _secondsPerBlockCurrentChain = secondsPerBlockCurrentChain; emit SecondsPerBlockCurrentChainChanged(secondsPerBlockCurrentChain); } /** * Block Specimen Producers submit their block specimen proofs using this function. */ function submitBlockSpecimenProof(uint64 chainId, uint64 blockHeight, bytes32 blockHash, bytes32 specimenHash, string calldata storageURL) external { require(_isValidBlockHash(blockHash), "Invalid block hash"); require(_isValidSpecimenHash(specimenHash), "Invalid specimen hash"); require(_isValidStorageURL(storageURL), "Invalid storage URL"); require(_blockSpecimenProducers.contains(msg.sender), "Sender is not BLOCK_SPECIMEN_PRODUCER_ROLE"); ChainData storage cd = _chainData[chainId]; require(cd.nthBlock != 0, "Invalid chain ID"); require(blockHeight % cd.nthBlock == 0, "Invalid block height"); BlockSpecimenSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; SessionParticipantData storage participantsData = session.participantsData[msg.sender]; // if this is the first specimen to be submitted for a block, initialize a new session if (sessionDeadline == 0) { require(!session.isSessionDone, "Session submissions have closed"); uint256 currentBlockOnTargetChain = cd.blockOnTargetChain + (((block.number - cd.blockOnCurrentChain) * _secondsPerBlockCurrentChain) / cd.secondsPerBlockTargetChain); uint256 lowerBound = currentBlockOnTargetChain >= cd.allowedThreshold ? currentBlockOnTargetChain - (cd.allowedThreshold / 2) : 0; uint256 upperBound = currentBlockOnTargetChain + (cd.allowedThreshold / 2); require(lowerBound <= blockHeight && blockHeight <= upperBound, "Block height is out of bounds for live sync"); session.sessionDeadline = uint64(block.number + _blockSpecimenSessionDuration); emit SessionStarted(chainId, blockHeight, session.sessionDeadline); uint128 validatorID = validatorIDs[msg.sender]; require(_validatorEnabled[validatorID], "Validator is not enabled"); session.blockHashesRaw.push(blockHash); BlockProperties storage bh = session.blockProperties[blockHash]; bh.specimenHashes.push(specimenHash); bh.participants[specimenHash].push(msg.sender); participantsData.submissionCounter++; } else { require(block.number <= sessionDeadline, "Session submissions have closed"); require(participantsData.submissionCounter < cd.maxSubmissionsPerBlockHeight, "Max submissions limit exceeded"); BlockProperties storage bh = session.blockProperties[blockHash]; bytes32[] storage specimenHashes = bh.specimenHashes; uint128 validatorID = validatorIDs[msg.sender]; require(_validatorEnabled[validatorID], "Validator is not enabled"); // check if it was submitted for the same block hash // this should be at about (nValidators * maxSubmissionsPerBlockHeight) iterations // which would typically be less than 50 for (uint256 j = 0; j < specimenHashes.length && j < 50; j++) { address[] storage specimenHashParticipants = bh.participants[specimenHashes[j]]; for (uint256 k = 0; k < specimenHashParticipants.length; k++) require(specimenHashParticipants[k] != msg.sender, "Operator already submitted for the provided block hash"); } address[] storage participants = bh.participants[specimenHash]; if (specimenHashes.length != 0) { if (participants.length == 0) specimenHashes.push(specimenHash); } else { session.blockHashesRaw.push(blockHash); specimenHashes.push(specimenHash); } participants.push(msg.sender); participantsData.submissionCounter++; } _urls[specimenHash].push(storageURL); emit BlockSpecimenProductionProofSubmitted(chainId, blockHeight, blockHash, specimenHash, storageURL); } /** * This is the new finalize function that works with staking contract in ethereum */ function finalizeSpecimenSession(uint64 chainId, uint64 blockHeight) public { BlockSpecimenSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; require(block.number > sessionDeadline, "Session not past deadline"); require(!session.isSessionDone, "Session cannot be finalized"); require(sessionDeadline != 0, "Session not started"); uint256 contributorsN; bytes32 specimenHash; uint256 max; bytes32 agreedBlockHash; bytes32 agreedSpecimenHash; bytes32[] storage blockHashesRaw = session.blockHashesRaw; bytes32 rawBlockHash; uint256 blockSpecimenHashesLength = blockHashesRaw.length; // find the block hash and specimen hashes that the quorum agrees on by finding the specimen hash with the highest number of participants for (uint256 i = 0; i < blockSpecimenHashesLength; i++) { rawBlockHash = blockHashesRaw[i]; BlockProperties storage bh = session.blockProperties[rawBlockHash]; for (uint256 j = 0; j < bh.specimenHashes.length; j++) { specimenHash = bh.specimenHashes[j]; uint256 len = bh.participants[specimenHash].length; contributorsN += len; if (len > max) { max = len; agreedBlockHash = rawBlockHash; agreedSpecimenHash = specimenHash; } } } // check if the number of submissions is sufficient and if the quorum is achieved if (_minSubmissionsRequired <= max && (max * _DIVIDER) / contributorsN >= _blockSpecimenQuorum) { _finalizeWithParticipants(session, chainId, blockHeight, agreedBlockHash, agreedSpecimenHash); } else emit QuorumNotReached(chainId, blockHeight); // prevent further session finalization calls session.isSessionDone = true; session.sessionDeadline = 0; } function _finalizeWithParticipants(BlockSpecimenSession storage session, uint64 chainId, uint64 blockHeight, bytes32 agreedBlockHash, bytes32 agreedSpecimenHash) internal { address[] storage participants = session.blockProperties[agreedBlockHash].participants[agreedSpecimenHash]; uint256 validatorBitMap; // sets the ith bit to 1 if the ith validator submits the agreed specimen hash mapping(address => SessionParticipantData) storage participantsData = session.participantsData; for (uint256 i = 0; i < participants.length; i++) { address participant = participants[i]; SessionParticipantData storage pd = participantsData[participant]; validatorBitMap |= (1 << (255 - validatorIDs[participant])); // release gas if possible if (pd.submissionCounter > 0) { pd.submissionCounter = 0; } } emit BlockSpecimenQuorum(chainId, blockHeight, validatorBitMap, agreedBlockHash, agreedSpecimenHash); // release gas // clear blockProperties map for (uint256 i = 0; i < session.blockHashesRaw.length; i++) { bytes32 key = session.blockHashesRaw[i]; BlockProperties storage bp = session.blockProperties[key]; for (uint256 j = 0; j < bp.specimenHashes.length; j++) { bytes32 specimenHash = bp.specimenHashes[j]; address[] memory participantsTemp = bp.participants[specimenHash]; for (uint256 k = 0; k < participantsTemp.length; k++) { delete session.participantsData[participantsTemp[k]]; } delete bp.participants[specimenHash]; } delete session.blockProperties[session.blockHashesRaw[i]]; } delete session.blockHashesRaw; } /** * Returns contract meta data */ function getMetadata() public view returns ( address stakingManager, uint128 blockSpecimenRewardAllocation, uint64 blockSpecimenSessionDuration, uint64 minSubmissionsRequired, uint256 blockSpecimenQuorum, uint256 secondsPerBlockCurrentChain ) { return ( address(_stakingManager), _blockSpecimenRewardAllocation, _blockSpecimenSessionDuration, _minSubmissionsRequired, _blockSpecimenQuorum, _secondsPerBlockCurrentChain ); } /** * Returns data used for chain sync */ function getChainData( uint64 chainId ) external view returns ( uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain, uint128 allowedThreshold, uint128 maxSubmissionsPerBlockHeight, uint64 nthBlock ) { ChainData memory cd = _chainData[chainId]; return (cd.blockOnTargetChain, cd.blockOnCurrentChain, cd.secondsPerBlockTargetChain, cd.allowedThreshold, cd.maxSubmissionsPerBlockHeight, cd.nthBlock); } /** * Returns all bsp operator addresses (disabled and enabled) of a given validator */ function getOperators(uint128 validatorId) external view returns (address[] memory) { return _validatorOperators[validatorId].values(); } /** * Returns all enabled operators by role type */ function getAllOperators() external view returns (address[] memory _bsps, address[] memory __governors, address[] memory __auditors) { return (_blockSpecimenProducers.values(), _governors.values(), _auditors.values()); } /** * returns enabled operator count for a validator */ function getEnabledOperatorCount(uint128 validatorId) external view returns (uint128) { return _validatorActiveOperatorsCounters[validatorId]; } /** * Returns required stake and enabled block specimen producer operators */ function getBSPRoleData() external view returns (uint128 requiredStake, address[] memory activeMembers) { return (_bspRequiredStake, _blockSpecimenProducers.values()); } /** * Returns true if the given operator is enabled. * Returns false if the operator is disabled or does not exist */ function isEnabled(address operator) external view returns (bool) { return _blockSpecimenProducers.contains(operator); } /** * Returns true if the given validator is enabled. * Returns false if the validator is disabled or does not exist */ function isValidatorEnabled(uint128 validatorId) external view returns (bool) { return _validatorEnabled[validatorId]; } /** * Returns IPFS urls where specimens reside */ function getURLS(bytes32 specimenhash) external view returns (string[] memory) { return _urls[specimenhash]; } /** * This function is called to check whether the sesion is open for the given chain id and block height */ function isSessionOpen(uint64 chainId, uint64 blockHeight, address operator) public view returns (bool) { BlockSpecimenSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; SessionParticipantData storage participantsData = session.participantsData[operator]; bool submissionLimitExceeded = participantsData.submissionCounter == _chainData[chainId].maxSubmissionsPerBlockHeight; return (!submissionLimitExceeded && block.number <= sessionDeadline) || (sessionDeadline == 0 && !session.isSessionDone); } function _isValidBlockHash(bytes32 blockHash) internal pure returns (bool) { bytes32 zeroHash = bytes32(0); // Check if the input is a valid hash require(blockHash != zeroHash, "Invalid block hash"); return true; } function _isValidSpecimenHash(bytes32 specimenHash) internal pure returns (bool) { bytes32 zeroHash = bytes32(0); // Check if the input is a valid hash require(specimenHash != zeroHash, "Invalid specimen hash"); return true; } function _isValidStorageURL(string memory storageURL) internal pure returns (bool) { // Check if the input is not an empty string return bytes(storageURL).length > 0; } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.13; // blank interface contract which earlier at interface of OperationalStaking.sol which needed to be exposed to proof chain contracts. // but now this is not needed anymore -- the functions are removed, but due to the upgrade rules of smart contract, we cannot remove the interface. interface IOperationalStaking {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"threshold","type":"uint64"}],"name":"BlockHeightSubmissionThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"specimenHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"storageURL","type":"string"}],"name":"BlockSpecimenProductionProofSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"validatorBitMap","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"specimenHash","type":"bytes32"}],"name":"BlockSpecimenQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newBlockSpecimenRewardAllocation","type":"uint128"}],"name":"BlockSpecimenRewardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"}],"name":"ChainSyncDataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxSubmissions","type":"uint256"}],"name":"MaxSubmissionsPerBlockHeightChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newStakeRequirement","type":"uint128"}],"name":"MinimumRequiredStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"nthBlock","type":"uint64"}],"name":"NthBlockChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"activeOperatorCount","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"OperatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"blockHeight","type":"uint64"}],"name":"QuorumNotReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"secondsPerBlockCurrentChain","type":"uint64"}],"name":"SecondsPerBlockCurrentChainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"deadline","type":"uint64"}],"name":"SessionStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newSessionDuration","type":"uint64"}],"name":"SpecimenSessionDurationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"minSubmissions","type":"uint64"}],"name":"SpecimenSessionMinSubmissionChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newQuorumThreshold","type":"uint256"}],"name":"SpecimenSessionQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingManager","type":"address"}],"name":"StakingManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"ValidatorDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"ValidatorEnabled","type":"event"},{"inputs":[],"name":"AUDITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCK_SPECIMEN_PRODUCER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNANCE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auditor","type":"address"}],"name":"addAuditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"addBSPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governor","type":"address"}],"name":"addGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"disableValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"enableValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"}],"name":"finalizeSpecimenSession","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllOperators","outputs":[{"internalType":"address[]","name":"_bsps","type":"address[]"},{"internalType":"address[]","name":"__governors","type":"address[]"},{"internalType":"address[]","name":"__auditors","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBSPRoleData","outputs":[{"internalType":"uint128","name":"requiredStake","type":"uint128"},{"internalType":"address[]","name":"activeMembers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"getChainData","outputs":[{"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"},{"internalType":"uint128","name":"allowedThreshold","type":"uint128"},{"internalType":"uint128","name":"maxSubmissionsPerBlockHeight","type":"uint128"},{"internalType":"uint64","name":"nthBlock","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"getEnabledOperatorCount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetadata","outputs":[{"internalType":"address","name":"stakingManager","type":"address"},{"internalType":"uint128","name":"blockSpecimenRewardAllocation","type":"uint128"},{"internalType":"uint64","name":"blockSpecimenSessionDuration","type":"uint64"},{"internalType":"uint64","name":"minSubmissionsRequired","type":"uint64"},{"internalType":"uint256","name":"blockSpecimenQuorum","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockCurrentChain","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"getOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"specimenhash","type":"bytes32"}],"name":"getURLS","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"initialGovernor","type":"address"},{"internalType":"address","name":"stakingManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"isEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"},{"internalType":"address","name":"operator","type":"address"}],"name":"isSessionOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"isValidatorEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operatorRoles","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auditor","type":"address"}],"name":"removeAuditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"removeBSPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governor","type":"address"}],"name":"removeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"threshold","type":"uint64"}],"name":"setBlockHeightSubmissionsThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"newBlockSpecimenReward","type":"uint128"}],"name":"setBlockSpecimenReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newSessionDuration","type":"uint64"}],"name":"setBlockSpecimenSessionDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"}],"name":"setChainSyncData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"maxSubmissions","type":"uint64"}],"name":"setMaxSubmissionsPerBlockHeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"minSubmissions","type":"uint64"}],"name":"setMinSubmissionsRequired","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"n","type":"uint64"}],"name":"setNthBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quorum","type":"uint256"}],"name":"setQuorumThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"secondsPerBlockCurrentChain","type":"uint64"}],"name":"setSecondsPerBlockCurrentChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManagerAddress","type":"address"}],"name":"setStakingManagerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"specimenHash","type":"bytes32"},{"internalType":"string","name":"storageURL","type":"string"}],"name":"submitBlockSpecimenProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorIDs","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613a8c806100206000396000f3fe608060405234801561001057600080fd5b50600436106101cd5760003560e01c80630d92f4ed146101d2578063151fd8f3146102115780631fd55ae9146102265780632ba719ad1461023c5780632c58ed421461024f57806337e15bce146102625780633c4a25d014610275578063429a481b1461028857806342e45079146102c457806343b845b5146102d75780634524c7e114610303578063485cc9551461031657806354cfa69f1461032957806367585e44146103f757806367d07ad71461040a5780636ab9d8e81461041d5780636e1d616e1461044b578063715018a6146104605780637a5b4f591461046857806389587f05146104f65780638da5cb5b146105095780639015d3711461051e57806393742b561461053157806399146284146105445780639c49d8ee14610557578063ba75fd2f1461056c578063cc96e4131461057f578063cf64a01d14610592578063d269550a146105a5578063d3a8b2a8146105b8578063d5839da9146105d8578063d911c632146105f8578063e32014091461060f578063e429cef114610622578063e6116cfd14610635578063edff4b6114610648578063eecdac881461065b578063f2fde38b1461066e578063f36c8f5c14610681575b600080fd5b6101fb6101e03660046130de565b6072602052600090815260409020546001600160801b031681565b60405161020891906130f9565b60405180910390f35b61022461021f366004613124565b610696565b005b61022e610f80565b60405161020892919061320d565b61022461024a366004613239565b610fab565b61022461025d366004613254565b611036565b6102246102703660046130de565b61111d565b6102246102833660046130de565b6111e2565b6102b461029636600461329e565b6001600160801b03166000908152607a602052604090205460ff1690565b6040519015158152602001610208565b6102246102d236600461329e565b6112ab565b6101fb6102e536600461329e565b6001600160801b039081166000908152607560205260409020541690565b6102246103113660046132b9565b61134f565b6102246103243660046132d2565b61140d565b6103b5610337366004613239565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610208565b610224610405366004613254565b61165b565b610224610418366004613239565b6117f2565b61043d61042b3660046130de565b60746020526000908152604090205481565b604051908152602001610208565b61043d600080516020613a1783398151915281565b6102246118bc565b6104aa607b546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610208565b61022461050436600461329e565b6118d0565b6105116119d0565b60405161020891906132fc565b6102b461052c3660046130de565b6119df565b61022461053f366004613239565b6119f2565b610224610552366004613310565b611b43565b61043d6000805160206139d783398151915281565b6102b461057a366004613349565b611c03565b61022461058d36600461338c565b611cc3565b6102246105a03660046130de565b611ec7565b6102246105b3366004613254565b612080565b6105cb6105c636600461329e565b612335565b60405161020891906133b6565b6105eb6105e63660046132b9565b612359565b60405161020891906133c9565b610600612445565b60405161020893929190613464565b61022461061d366004613254565b612473565b6102246106303660046130de565b612545565b6102246106433660046130de565b612657565b61022461065636600461329e565b612744565b6102246106693660046130de565b6127eb565b61022461067c3660046130de565b6128ba565b61043d6000805160206139f783398151915281565b61069f84612933565b6106c45760405162461bcd60e51b81526004016106bb906134a7565b60405180910390fd5b6106cd8361295c565b6106e95760405162461bcd60e51b81526004016106bb906134d3565b61072882828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061297c92505050565b61076a5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081cdd1bdc9859d948155493606a1b60448201526064016106bb565b610775606c33612982565b6107d45760405162461bcd60e51b815260206004820152602a60248201527f53656e646572206973206e6f7420424c4f434b5f53504543494d454e5f50524f60448201526944554345525f524f4c4560b01b60648201526084016106bb565b6001600160401b038087166000908152607760205260408120600481015490921690036108135760405162461bcd60e51b81526004016106bb90613502565b600481015461082b906001600160401b031687613542565b6001600160401b0316156108785760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106bb565b6001600160401b0380881660009081526076602090815260408083208a85168452825280832060038101543385526002820190935290832090939190911691829003610c32576003830154600160401b900460ff16156108ea5760405162461bcd60e51b81526004016106bb90613568565b6000846002015460675486600101544361090491906135b5565b61090e91906135cc565b61091891906135eb565b855461092491906135ff565b60038601549091506000906001600160801b0316821015610946576000610973565b6003860154610960906002906001600160801b0316613617565b610973906001600160801b0316836135b5565b6003870154909150600090610993906002906001600160801b0316613617565b6109a6906001600160801b0316846135ff565b90508b6001600160401b031682111580156109ca5750808c6001600160401b031611155b610a2a5760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106bb565b606954610a40906001600160401b0316436135ff565b8660030160006101000a8154816001600160401b0302191690836001600160401b031602179055508b6001600160401b03168d6001600160401b03167f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c8860030160009054906101000a90046001600160401b0316604051610ac2919061363d565b60405180910390a3336000908152607260209081526040808320546001600160801b0316808452607a9092529091205460ff16610b115760405162461bcd60e51b81526004016106bb90613651565b866001018c908060018154018082558091505060019003906000526020600020016000909190919091505560008760000160008e81526020019081526020016000209050806001018c90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008d8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555085600001601081819054906101000a90046001600160801b031680929190610c0390613683565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050610f09565b816001600160401b0316431115610c5b5760405162461bcd60e51b81526004016106bb90613568565b600384015481546001600160801b03600160801b928390048116929091041610610cc75760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106bb565b60008881526020848152604080832033845260728352818420546001600160801b0316808552607a90935292205460018301919060ff16610d1a5760405162461bcd60e51b81526004016106bb90613651565b60005b825481108015610d2d5750603281105b15610e37576000846000016000858481548110610d4c57610d4c6136b1565b90600052602060002001548152602001908152602001600020905060005b8154811015610e2257336001600160a01b0316828281548110610d8f57610d8f6136b1565b6000918252602090912001546001600160a01b031603610e105760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106bb565b80610e1a816136c7565b915050610d6a565b50508080610e2f906136c7565b915050610d1d565b5060008a8152602084905260409020825415610e71578054600003610e6c578254600181018455600084815260209020018b90555b610e9e565b600180880180548083018255600091825260208083209091018f9055855492830186558582529020018b90555b80546001810182556000828152602090200180546001600160a01b0319163317905584546001600160801b03600160801b90910416856010610edf83613683565b91906101000a8154816001600160801b0302191690836001600160801b0316021790555050505050505b6000878152607860209081526040822080546001810182559083529120610f329101878761300f565b507fd79027d5232050798063d67d05f9e1545ea5b954e2334b09db548e63823fa1b18a8a8a8a8a8a604051610f6c969594939291906136e0565b60405180910390a150505050505050505050565b606854600090606090600160801b90046001600160801b0316610fa3606c61299e565b915091509091565b610fb6606e33612982565b610fd25760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b031611610ffb5760405162461bcd60e51b81526004016106bb90613773565b6001600160401b03811660678190556040517f52eb144349cf62d6190a9e1cbb6a601848aa63df834dd2a2e75bb0be3fef86f490600090a250565b611041606e33612982565b61105d5760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116110ae5760405162461bcd60e51b815260206004820152601560248201527405468726573686f6c642063616e6e6f74206265203605c1b60448201526064016106bb565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a99061111190849061363d565b60405180910390a25050565b611128606e33612982565b6111445760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b03811661118c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016106bb565b607b80546001600160a01b0319166001600160a01b0383161790556040517ff725afeae606c3f3c4c0ac3963e5c76a046bc4f386be98100c54e55bf5aeab36906111d79083906132fc565b60405180910390a150565b6111ea6129ab565b6001600160a01b0381166112105760405162461bcd60e51b81526004016106bb906137aa565b6001600160a01b038116600090815260746020526040902054156112465760405162461bcd60e51b81526004016106bb906137dc565b6001600160a01b03811660009081526074602052604090206000805160206139f7833981519152905561127a606e82612a0a565b506000805160206139b78339815191528160006000805160206139f78339815191526040516111d79392919061380d565b607b546001600160a01b031633146112d55760405162461bcd60e51b81526004016106bb90613837565b610100816001600160801b0316106112ff5760405162461bcd60e51b81526004016106bb9061386e565b6001600160801b0381166000908152607a602052604090819020805460ff19169055517ff97fbe9a37a2eae093c44e9bbcd9afde23ba64215e8fd80b9c49b1fbd4d58e54906111d79083906130f9565b61135a606e33612982565b6113765760405162461bcd60e51b81526004016106bb9061373c565b670de0b6b3a76400008111156113d95760405162461bcd60e51b815260206004820152602260248201527f51756f72756d2063616e6e6f742062652067726561746572207468616e203130604482015261302560f01b60648201526084016106bb565b60668190556040518181527eec8eefea39d742ff523b872c1931ff4d509ab873041c5d6e237d5f0fc053f8906020016111d7565b600054610100900460ff161580801561142d5750600054600160ff909116105b806114475750303b158015611447575060005460ff166001145b6114aa5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106bb565b6000805460ff1916600117905580156114cd576000805461ff0019166101001790555b6001600160a01b0383166114f35760405162461bcd60e51b81526004016106bb906137aa565b6114fb612a1f565b611506606e33612a0a565b50611520606a6000805160206139f7833981519152612a4e565b5061153a606a6000805160206139d7833981519152612a4e565b50611554606a600080516020613a17833981519152612a4e565b5061156b6103116002670de0b6b3a76400006135eb565b61157a655af3107a40006118d0565b61158460f06117f2565b61158e60026119f2565b6115978261111d565b6115a2606e33612a5a565b506001600160a01b03831660009081526074602052604090206000805160206139f783398151915290556115d7606e84612a0a565b506000805160206139b78339815191528360006000805160206139f78339815191526040516116089392919061380d565b60405180910390a18015611656576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b611666606e33612982565b6116825760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116116d95760405162461bcd60e51b815260206004820152601b60248201527a04d6178207375626d697373696f6e732063616e6e6f74206265203602c1b60448201526064016106bb565b6003816001600160401b031611156117415760405162461bcd60e51b815260206004820152602560248201527f4d6178207375626d697373696f6e732063616e6e6f74206265206d6f7265207460448201526468616e203360d81b60648201526084016106bb565b6001600160401b03808316600090815260776020526040812060040154909116900361177f5760405162461bcd60e51b81526004016106bb90613502565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a030906117e690839061363d565b60405180910390a15050565b6117fd606e33612982565b6118195760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116118715760405162461bcd60e51b815260206004820152601c60248201527b053657373696f6e206475726174696f6e2063616e6e6f7420626520360241b60448201526064016106bb565b606980546001600160401b0319166001600160401b0383161790556040517f94bc488f4d9a985dd5f9d11e8f0a614a62828888eb65b704a90fa852be937549906111d790839061363d565b6118c46129ab565b6118ce6000612a6f565b565b6118db606e33612982565b6118f75760405162461bcd60e51b81526004016106bb9061373c565b61190b670de0b6b3a76400006103e86135cc565b816001600160801b031611156119855760405162461bcd60e51b815260206004820152603960248201527f426c6f636b2073706563696d656e207265776172642063616e6e6f742062652060448201527833b932b0ba32b9103a3430b71018981818152224ab24a222a960391b60648201526084016106bb565b606880546001600160801b0319166001600160801b0383161790556040517f01eb821dd596243f2f8c5f6c7478e281b855ac12a9f4be2c486cb2778a0bb81e906111d79083906130f9565b6033546001600160a01b031690565b60006119ec606c83612982565b92915050565b6119fd606e33612982565b611a195760405162461bcd60e51b81526004016106bb9061373c565b6001816001600160401b03161015611a825760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d207375626d697373696f6e73206d757374206265206174206c60448201526565617374203160d01b60648201526084016106bb565b60ff816001600160401b03161115611aef5760405162461bcd60e51b815260206004820152602a60248201527f4d6178696d756d20616c6c6f776564206d696e696d756d207375626d697373696044820152696f6e732069732032353560b01b60648201526084016106bb565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517f28312bbddd51eea4439db773218c441a4057f6ed285c642a569f1dcdba1cc047906111d790839061363d565b611b4e606e33612982565b611b6a5760405162461bcd60e51b81526004016106bb9061373c565b6001600160401b038416600090815260776020526040902081611b9f5760405162461bcd60e51b81526004016106bb90613773565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b03908116929091041614801581611c8e5750826001600160401b03164311155b80611cb757506001600160401b038316158015611cb757506003840154600160401b900460ff16155b98975050505050505050565b611cce606e33612982565b611cea5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b038216611d3b5760405162461bcd60e51b8152602060048201526018602482015277496e76616c6964206f70657261746f72206164647265737360401b60448201526064016106bb565b6001600160a01b03821660009081526074602052604090205415611d715760405162461bcd60e51b81526004016106bb906137dc565b60ff816001600160801b03161115611ddb5760405162461bcd60e51b815260206004820152602760248201527f56616c696461746f722049442063616e6e6f742062652067726561746572207460448201526668616e2032353560c81b60648201526084016106bb565b6001600160a01b03821660009081526074602090815260408083206000805160206139d783398151915290556072825280832080546001600160801b0319166001600160801b038616908117909155835260739091529020611e3d9083612a0a565b50611e49606c83612a0a565b506001600160801b03808216600090815260756020526040812080549092169190611e7383613683565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550506000805160206139b783398151915282826000805160206139d78339815191526040516117e69392919061380d565b611ed2606e33612982565b611eee5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b0381166000908152607460205260409020546000805160206139d783398151915214611f595760405162461bcd60e51b815260206004820152601360248201527204f70657261746f72206973206e6f742042535606c1b60448201526064016106bb565b611f64606c82612982565b611fbf5760405162461bcd60e51b815260206004820152602660248201527f4f70657261746f72206e6f7420666f756e6420696e2061637469766520696e7360448201526574616e63657360d01b60648201526084016106bb565b611fc881612ac1565b6001600160a01b0381166000908152607260209081526040808320546001600160801b031680845260739092529091206120029083612a5a565b506001600160a01b038216600090815260726020908152604080832080546001600160801b0319169055607482528083208390556001600160801b038481168452607590925291829020549151600080516020613a37833981519152926117e69286928692909116906000805160206139d7833981519152906138a0565b6001600160401b0380831660009081526076602090815260408083208585168452909152902060038101549091164381106120f95760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106bb565b6003820154600160401b900460ff16156121535760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106bb565b806001600160401b03166000036121a25760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106bb565b6001820180546000918291829182918291908290815b81811015612275578381815481106121d2576121d26136b1565b6000918252602080832090910154808352908d905260408220909450905b600182015481101561226057816001018181548110612211576122116136b1565b600091825260208083209091015480835290849052604090912054909a50612239818d6135ff565b9b508981111561224d578099508598508a97505b5080612258816136c7565b9150506121f0565b5050808061226d906136c7565b9150506121b8565b50606954600160401b90046001600160401b031686108015906122b65750606654886122a9670de0b6b3a7640000896135cc565b6122b391906135eb565b10155b156122cd576122c88a8d8d8888612b3a565b61230f565b8b6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218c604051612306919061363d565b60405180910390a25b505050600390960180546001600160481b031916600160401b1790555050505050505050565b6001600160801b03811660009081526073602052604090206060906119ec9061299e565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561243a5783829060005260206000200180546123ad906138d0565b80601f01602080910402602001604051908101604052809291908181526020018280546123d9906138d0565b80156124265780601f106123fb57610100808354040283529160200191612426565b820191906000526020600020905b81548152906001019060200180831161240957829003601f168201915b50505050508152602001906001019061238e565b505050509050919050565b6060806060612454606c61299e565b61245e606e61299e565b612468607061299e565b925092509250909192565b61247e606e33612982565b61249a5760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116124eb5760405162461bcd60e51b815260206004820152601560248201527404e746820626c6f636b2063616e6e6f74206265203605c1b60448201526064016106bb565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b612550606e33612982565b61256c5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b0381166125bc5760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642061756469746f72206164647265737360481b60448201526064016106bb565b6001600160a01b038116600090815260746020526040902054156125f25760405162461bcd60e51b81526004016106bb906137dc565b6001600160a01b0381166000908152607460205260409020600080516020613a178339815191529055612626607082612a0a565b506000805160206139b7833981519152816000600080516020613a178339815191526040516111d79392919061380d565b612662606e33612982565b61267e5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b038116600090815260746020526040902054600080516020613a17833981519152146126ed5760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106bb565b6001600160a01b038116600090815260746020526040812055612711607082612a5a565b50600080516020613a3783398151915281600080600080516020613a178339815191526040516111d794939291906138a0565b607b546001600160a01b0316331461276e5760405162461bcd60e51b81526004016106bb90613837565b610100816001600160801b0316106127985760405162461bcd60e51b81526004016106bb9061386e565b6001600160801b0381166000908152607a602052604090819020805460ff19166001179055517f553b029ba5c74688a5da732136d246f722502db24ed6b4aaf1cdc9f2f9ef23ef906111d79083906130f9565b6127f36129ab565b6001600160a01b0381166000908152607460205260409020546000805160206139f7833981519152146128635760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106bb565b6001600160a01b038116600090815260746020526040812055612887606e82612a5a565b50600080516020613a37833981519152816000806000805160206139f78339815191526040516111d794939291906138a0565b6128c26129ab565b6001600160a01b0381166129275760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106bb565b61293081612a6f565b50565b600080826129535760405162461bcd60e51b81526004016106bb906134a7565b50600192915050565b600080826129535760405162461bcd60e51b81526004016106bb906134d3565b51151590565b6000612997836001600160a01b038416612e2e565b9392505050565b6060600061299783612e46565b336129b46119d0565b6001600160a01b0316146118ce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106bb565b6000612997836001600160a01b038416612ea2565b600054610100900460ff16612a465760405162461bcd60e51b81526004016106bb9061390a565b6118ce612eec565b60006129978383612ea2565b6000612997836001600160a01b038416612f1c565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612acc606c82612a5a565b506001600160a01b0381166000908152607260209081526040808320546001600160801b039081168085526075909352908320805492939290911691612b1183613955565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b60008281526020868152604080832084845290915281209060028701815b8354811015612bfd576000848281548110612b7557612b756136b1565b60009182526020808320909101546001600160a01b0316808352858252604080842060729093529092205491925090612bb8906001600160801b031660ff613978565b815460016001600160801b039283161b9690961795600160801b90041615612be85780546001600160801b031681555b50508080612bf5906136c7565b915050612b58565b5084866001600160401b0316886001600160401b03167f858deae9d885ee978c04934ceabf15ebe77ae274f3af6a05ecf3bd9880b08e1e8588604051612c4d929190918252602082015260400190565b60405180910390a460005b6001890154811015612e15576000896001018281548110612c7b57612c7b6136b1565b6000918252602080832090910154808352908c905260408220909250905b6001820154811015612db7576000826001018281548110612cbc57612cbc6136b1565b6000918252602080832090910154808352858252604080842080548251818602810186019093528083529295509092909190830182828015612d2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d09575b5050505050905060005b8151811015612d8a578e6002016000838381518110612d5257612d526136b1565b6020908102919091018101516001600160a01b0316825281019190915260400160009081205580612d82816136c7565b915050612d31565b506000828152602085905260408120612da291613093565b50508080612daf906136c7565b915050612c99565b508a60000160008c6001018581548110612dd357612dd36136b1565b906000526020600020015481526020019081526020016000206000600182016000612dfe9190613093565b505050508080612e0d906136c7565b915050612c58565b50612e24600189016000613093565b5050505050505050565b60009081526001919091016020526040902054151590565b606081600001805480602002602001604051908101604052809291908181526020018280548015612e9657602002820191906000526020600020905b815481526020019060010190808311612e82575b50505050509050919050565b6000612eae8383612e2e565b612ee4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556119ec565b5060006119ec565b600054610100900460ff16612f135760405162461bcd60e51b81526004016106bb9061390a565b6118ce33612a6f565b60008181526001830160205260408120548015613005576000612f406001836135b5565b8554909150600090612f54906001906135b5565b9050818114612fb9576000866000018281548110612f7457612f746136b1565b9060005260206000200154905080876000018481548110612f9757612f976136b1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612fca57612fca6139a0565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506119ec565b60009150506119ec565b82805461301b906138d0565b90600052602060002090601f01602090048101928261303d5760008555613083565b82601f106130565782800160ff19823516178555613083565b82800160010185558215613083579182015b82811115613083578235825591602001919060010190613068565b5061308f9291506130ad565b5090565b508054600082559060005260206000209081019061293091905b5b8082111561308f57600081556001016130ae565b80356001600160a01b03811681146130d957600080fd5b919050565b6000602082840312156130f057600080fd5b612997826130c2565b6001600160801b0391909116815260200190565b80356001600160401b03811681146130d957600080fd5b60008060008060008060a0878903121561313d57600080fd5b6131468761310d565b95506131546020880161310d565b9450604087013593506060870135925060808701356001600160401b038082111561317e57600080fd5b818901915089601f83011261319257600080fd5b8135818111156131a157600080fd5b8a60208285010111156131b357600080fd5b6020830194508093505050509295509295509295565b600081518084526020808501945080840160005b838110156132025781516001600160a01b0316875295820195908201906001016131dd565b509495945050505050565b6001600160801b0383168152604060208201819052600090613231908301846131c9565b949350505050565b60006020828403121561324b57600080fd5b6129978261310d565b6000806040838503121561326757600080fd5b6132708361310d565b915061327e6020840161310d565b90509250929050565b80356001600160801b03811681146130d957600080fd5b6000602082840312156132b057600080fd5b61299782613287565b6000602082840312156132cb57600080fd5b5035919050565b600080604083850312156132e557600080fd5b6132ee836130c2565b915061327e602084016130c2565b6001600160a01b0391909116815260200190565b6000806000806080858703121561332657600080fd5b61332f8561310d565b966020860135965060408601359560600135945092505050565b60008060006060848603121561335e57600080fd5b6133678461310d565b92506133756020850161310d565b9150613383604085016130c2565b90509250925092565b6000806040838503121561339f57600080fd5b6133a8836130c2565b915061327e60208401613287565b60208152600061299760208301846131c9565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561345657888603603f1901855282518051808852835b81811015613426578281018a01518982018b0152890161340b565b8181111561343657848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133f1565b509398975050505050505050565b60608152600061347760608301866131c9565b828103602084015261348981866131c9565b9050828103604084015261349d81856131c9565b9695505050505050565b602080825260129082015271092dcecc2d8d2c840c4d8dec6d640d0c2e6d60731b604082015260600190565b602080825260159082015274092dcecc2d8d2c840e6e0cac6d2dacadc40d0c2e6d605b1b604082015260600190565b60208082526010908201526f125b9d985b1a590818da185a5b88125160821b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b038381168061355c5761355c61352c565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156135c7576135c761359f565b500390565b60008160001904831182151516156135e6576135e661359f565b500290565b6000826135fa576135fa61352c565b500490565b600082198211156136125761361261359f565b500190565b60006001600160801b03838116806136315761363161352c565b92169190910492915050565b6001600160401b0391909116815260200190565b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b60006001600160801b038281166002600160801b031981016136a7576136a761359f565b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016136d9576136d961359f565b5060010190565b6001600160401b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601d908201527f5365636f6e64732070657220626c6f636b2063616e6e6f742062652030000000604082015260600190565b602080825260189082015277496e76616c696420676f7665726e6f72206164647265737360401b604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6020808252601d908201527f53656e646572206973206e6f74207374616b696e67206d616e61676572000000604082015260600190565b60208082526018908201527776616c696461746f724964206f7574206f662072616e676560401b604082015260600190565b6001600160a01b039490941684526001600160801b03928316602085015291166040830152606082015260800190565b600181811c908216806138e457607f821691505b60208210810361390457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b0382168061396e5761396e61359f565b6000190192915050565b60006001600160801b03838116908316818110156139985761399861359f565b039392505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4298d0bb2de1c65f6d2cbc3401e3d5d5086bfe815cb57e521dafd0ebdbef6ee85c71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb159a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f5ca6d116f31cc5d708ae73029e1d63d1be48afdfd99819a3405bfbaf229748d90a26469706673582212204c0c27b00009a60128989c4cee2e5c6b763207fbae31d9d0a1857059c61e061d64736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cd5760003560e01c80630d92f4ed146101d2578063151fd8f3146102115780631fd55ae9146102265780632ba719ad1461023c5780632c58ed421461024f57806337e15bce146102625780633c4a25d014610275578063429a481b1461028857806342e45079146102c457806343b845b5146102d75780634524c7e114610303578063485cc9551461031657806354cfa69f1461032957806367585e44146103f757806367d07ad71461040a5780636ab9d8e81461041d5780636e1d616e1461044b578063715018a6146104605780637a5b4f591461046857806389587f05146104f65780638da5cb5b146105095780639015d3711461051e57806393742b561461053157806399146284146105445780639c49d8ee14610557578063ba75fd2f1461056c578063cc96e4131461057f578063cf64a01d14610592578063d269550a146105a5578063d3a8b2a8146105b8578063d5839da9146105d8578063d911c632146105f8578063e32014091461060f578063e429cef114610622578063e6116cfd14610635578063edff4b6114610648578063eecdac881461065b578063f2fde38b1461066e578063f36c8f5c14610681575b600080fd5b6101fb6101e03660046130de565b6072602052600090815260409020546001600160801b031681565b60405161020891906130f9565b60405180910390f35b61022461021f366004613124565b610696565b005b61022e610f80565b60405161020892919061320d565b61022461024a366004613239565b610fab565b61022461025d366004613254565b611036565b6102246102703660046130de565b61111d565b6102246102833660046130de565b6111e2565b6102b461029636600461329e565b6001600160801b03166000908152607a602052604090205460ff1690565b6040519015158152602001610208565b6102246102d236600461329e565b6112ab565b6101fb6102e536600461329e565b6001600160801b039081166000908152607560205260409020541690565b6102246103113660046132b9565b61134f565b6102246103243660046132d2565b61140d565b6103b5610337366004613239565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610208565b610224610405366004613254565b61165b565b610224610418366004613239565b6117f2565b61043d61042b3660046130de565b60746020526000908152604090205481565b604051908152602001610208565b61043d600080516020613a1783398151915281565b6102246118bc565b6104aa607b546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610208565b61022461050436600461329e565b6118d0565b6105116119d0565b60405161020891906132fc565b6102b461052c3660046130de565b6119df565b61022461053f366004613239565b6119f2565b610224610552366004613310565b611b43565b61043d6000805160206139d783398151915281565b6102b461057a366004613349565b611c03565b61022461058d36600461338c565b611cc3565b6102246105a03660046130de565b611ec7565b6102246105b3366004613254565b612080565b6105cb6105c636600461329e565b612335565b60405161020891906133b6565b6105eb6105e63660046132b9565b612359565b60405161020891906133c9565b610600612445565b60405161020893929190613464565b61022461061d366004613254565b612473565b6102246106303660046130de565b612545565b6102246106433660046130de565b612657565b61022461065636600461329e565b612744565b6102246106693660046130de565b6127eb565b61022461067c3660046130de565b6128ba565b61043d6000805160206139f783398151915281565b61069f84612933565b6106c45760405162461bcd60e51b81526004016106bb906134a7565b60405180910390fd5b6106cd8361295c565b6106e95760405162461bcd60e51b81526004016106bb906134d3565b61072882828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061297c92505050565b61076a5760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081cdd1bdc9859d948155493606a1b60448201526064016106bb565b610775606c33612982565b6107d45760405162461bcd60e51b815260206004820152602a60248201527f53656e646572206973206e6f7420424c4f434b5f53504543494d454e5f50524f60448201526944554345525f524f4c4560b01b60648201526084016106bb565b6001600160401b038087166000908152607760205260408120600481015490921690036108135760405162461bcd60e51b81526004016106bb90613502565b600481015461082b906001600160401b031687613542565b6001600160401b0316156108785760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106bb565b6001600160401b0380881660009081526076602090815260408083208a85168452825280832060038101543385526002820190935290832090939190911691829003610c32576003830154600160401b900460ff16156108ea5760405162461bcd60e51b81526004016106bb90613568565b6000846002015460675486600101544361090491906135b5565b61090e91906135cc565b61091891906135eb565b855461092491906135ff565b60038601549091506000906001600160801b0316821015610946576000610973565b6003860154610960906002906001600160801b0316613617565b610973906001600160801b0316836135b5565b6003870154909150600090610993906002906001600160801b0316613617565b6109a6906001600160801b0316846135ff565b90508b6001600160401b031682111580156109ca5750808c6001600160401b031611155b610a2a5760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106bb565b606954610a40906001600160401b0316436135ff565b8660030160006101000a8154816001600160401b0302191690836001600160401b031602179055508b6001600160401b03168d6001600160401b03167f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c8860030160009054906101000a90046001600160401b0316604051610ac2919061363d565b60405180910390a3336000908152607260209081526040808320546001600160801b0316808452607a9092529091205460ff16610b115760405162461bcd60e51b81526004016106bb90613651565b866001018c908060018154018082558091505060019003906000526020600020016000909190919091505560008760000160008e81526020019081526020016000209050806001018c90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008d8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555085600001601081819054906101000a90046001600160801b031680929190610c0390613683565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050610f09565b816001600160401b0316431115610c5b5760405162461bcd60e51b81526004016106bb90613568565b600384015481546001600160801b03600160801b928390048116929091041610610cc75760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106bb565b60008881526020848152604080832033845260728352818420546001600160801b0316808552607a90935292205460018301919060ff16610d1a5760405162461bcd60e51b81526004016106bb90613651565b60005b825481108015610d2d5750603281105b15610e37576000846000016000858481548110610d4c57610d4c6136b1565b90600052602060002001548152602001908152602001600020905060005b8154811015610e2257336001600160a01b0316828281548110610d8f57610d8f6136b1565b6000918252602090912001546001600160a01b031603610e105760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106bb565b80610e1a816136c7565b915050610d6a565b50508080610e2f906136c7565b915050610d1d565b5060008a8152602084905260409020825415610e71578054600003610e6c578254600181018455600084815260209020018b90555b610e9e565b600180880180548083018255600091825260208083209091018f9055855492830186558582529020018b90555b80546001810182556000828152602090200180546001600160a01b0319163317905584546001600160801b03600160801b90910416856010610edf83613683565b91906101000a8154816001600160801b0302191690836001600160801b0316021790555050505050505b6000878152607860209081526040822080546001810182559083529120610f329101878761300f565b507fd79027d5232050798063d67d05f9e1545ea5b954e2334b09db548e63823fa1b18a8a8a8a8a8a604051610f6c969594939291906136e0565b60405180910390a150505050505050505050565b606854600090606090600160801b90046001600160801b0316610fa3606c61299e565b915091509091565b610fb6606e33612982565b610fd25760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b031611610ffb5760405162461bcd60e51b81526004016106bb90613773565b6001600160401b03811660678190556040517f52eb144349cf62d6190a9e1cbb6a601848aa63df834dd2a2e75bb0be3fef86f490600090a250565b611041606e33612982565b61105d5760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116110ae5760405162461bcd60e51b815260206004820152601560248201527405468726573686f6c642063616e6e6f74206265203605c1b60448201526064016106bb565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a99061111190849061363d565b60405180910390a25050565b611128606e33612982565b6111445760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b03811661118c5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016106bb565b607b80546001600160a01b0319166001600160a01b0383161790556040517ff725afeae606c3f3c4c0ac3963e5c76a046bc4f386be98100c54e55bf5aeab36906111d79083906132fc565b60405180910390a150565b6111ea6129ab565b6001600160a01b0381166112105760405162461bcd60e51b81526004016106bb906137aa565b6001600160a01b038116600090815260746020526040902054156112465760405162461bcd60e51b81526004016106bb906137dc565b6001600160a01b03811660009081526074602052604090206000805160206139f7833981519152905561127a606e82612a0a565b506000805160206139b78339815191528160006000805160206139f78339815191526040516111d79392919061380d565b607b546001600160a01b031633146112d55760405162461bcd60e51b81526004016106bb90613837565b610100816001600160801b0316106112ff5760405162461bcd60e51b81526004016106bb9061386e565b6001600160801b0381166000908152607a602052604090819020805460ff19169055517ff97fbe9a37a2eae093c44e9bbcd9afde23ba64215e8fd80b9c49b1fbd4d58e54906111d79083906130f9565b61135a606e33612982565b6113765760405162461bcd60e51b81526004016106bb9061373c565b670de0b6b3a76400008111156113d95760405162461bcd60e51b815260206004820152602260248201527f51756f72756d2063616e6e6f742062652067726561746572207468616e203130604482015261302560f01b60648201526084016106bb565b60668190556040518181527eec8eefea39d742ff523b872c1931ff4d509ab873041c5d6e237d5f0fc053f8906020016111d7565b600054610100900460ff161580801561142d5750600054600160ff909116105b806114475750303b158015611447575060005460ff166001145b6114aa5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106bb565b6000805460ff1916600117905580156114cd576000805461ff0019166101001790555b6001600160a01b0383166114f35760405162461bcd60e51b81526004016106bb906137aa565b6114fb612a1f565b611506606e33612a0a565b50611520606a6000805160206139f7833981519152612a4e565b5061153a606a6000805160206139d7833981519152612a4e565b50611554606a600080516020613a17833981519152612a4e565b5061156b6103116002670de0b6b3a76400006135eb565b61157a655af3107a40006118d0565b61158460f06117f2565b61158e60026119f2565b6115978261111d565b6115a2606e33612a5a565b506001600160a01b03831660009081526074602052604090206000805160206139f783398151915290556115d7606e84612a0a565b506000805160206139b78339815191528360006000805160206139f78339815191526040516116089392919061380d565b60405180910390a18015611656576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b611666606e33612982565b6116825760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116116d95760405162461bcd60e51b815260206004820152601b60248201527a04d6178207375626d697373696f6e732063616e6e6f74206265203602c1b60448201526064016106bb565b6003816001600160401b031611156117415760405162461bcd60e51b815260206004820152602560248201527f4d6178207375626d697373696f6e732063616e6e6f74206265206d6f7265207460448201526468616e203360d81b60648201526084016106bb565b6001600160401b03808316600090815260776020526040812060040154909116900361177f5760405162461bcd60e51b81526004016106bb90613502565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a030906117e690839061363d565b60405180910390a15050565b6117fd606e33612982565b6118195760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116118715760405162461bcd60e51b815260206004820152601c60248201527b053657373696f6e206475726174696f6e2063616e6e6f7420626520360241b60448201526064016106bb565b606980546001600160401b0319166001600160401b0383161790556040517f94bc488f4d9a985dd5f9d11e8f0a614a62828888eb65b704a90fa852be937549906111d790839061363d565b6118c46129ab565b6118ce6000612a6f565b565b6118db606e33612982565b6118f75760405162461bcd60e51b81526004016106bb9061373c565b61190b670de0b6b3a76400006103e86135cc565b816001600160801b031611156119855760405162461bcd60e51b815260206004820152603960248201527f426c6f636b2073706563696d656e207265776172642063616e6e6f742062652060448201527833b932b0ba32b9103a3430b71018981818152224ab24a222a960391b60648201526084016106bb565b606880546001600160801b0319166001600160801b0383161790556040517f01eb821dd596243f2f8c5f6c7478e281b855ac12a9f4be2c486cb2778a0bb81e906111d79083906130f9565b6033546001600160a01b031690565b60006119ec606c83612982565b92915050565b6119fd606e33612982565b611a195760405162461bcd60e51b81526004016106bb9061373c565b6001816001600160401b03161015611a825760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d207375626d697373696f6e73206d757374206265206174206c60448201526565617374203160d01b60648201526084016106bb565b60ff816001600160401b03161115611aef5760405162461bcd60e51b815260206004820152602a60248201527f4d6178696d756d20616c6c6f776564206d696e696d756d207375626d697373696044820152696f6e732069732032353560b01b60648201526084016106bb565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517f28312bbddd51eea4439db773218c441a4057f6ed285c642a569f1dcdba1cc047906111d790839061363d565b611b4e606e33612982565b611b6a5760405162461bcd60e51b81526004016106bb9061373c565b6001600160401b038416600090815260776020526040902081611b9f5760405162461bcd60e51b81526004016106bb90613773565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b03908116929091041614801581611c8e5750826001600160401b03164311155b80611cb757506001600160401b038316158015611cb757506003840154600160401b900460ff16155b98975050505050505050565b611cce606e33612982565b611cea5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b038216611d3b5760405162461bcd60e51b8152602060048201526018602482015277496e76616c6964206f70657261746f72206164647265737360401b60448201526064016106bb565b6001600160a01b03821660009081526074602052604090205415611d715760405162461bcd60e51b81526004016106bb906137dc565b60ff816001600160801b03161115611ddb5760405162461bcd60e51b815260206004820152602760248201527f56616c696461746f722049442063616e6e6f742062652067726561746572207460448201526668616e2032353560c81b60648201526084016106bb565b6001600160a01b03821660009081526074602090815260408083206000805160206139d783398151915290556072825280832080546001600160801b0319166001600160801b038616908117909155835260739091529020611e3d9083612a0a565b50611e49606c83612a0a565b506001600160801b03808216600090815260756020526040812080549092169190611e7383613683565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550506000805160206139b783398151915282826000805160206139d78339815191526040516117e69392919061380d565b611ed2606e33612982565b611eee5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b0381166000908152607460205260409020546000805160206139d783398151915214611f595760405162461bcd60e51b815260206004820152601360248201527204f70657261746f72206973206e6f742042535606c1b60448201526064016106bb565b611f64606c82612982565b611fbf5760405162461bcd60e51b815260206004820152602660248201527f4f70657261746f72206e6f7420666f756e6420696e2061637469766520696e7360448201526574616e63657360d01b60648201526084016106bb565b611fc881612ac1565b6001600160a01b0381166000908152607260209081526040808320546001600160801b031680845260739092529091206120029083612a5a565b506001600160a01b038216600090815260726020908152604080832080546001600160801b0319169055607482528083208390556001600160801b038481168452607590925291829020549151600080516020613a37833981519152926117e69286928692909116906000805160206139d7833981519152906138a0565b6001600160401b0380831660009081526076602090815260408083208585168452909152902060038101549091164381106120f95760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106bb565b6003820154600160401b900460ff16156121535760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106bb565b806001600160401b03166000036121a25760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106bb565b6001820180546000918291829182918291908290815b81811015612275578381815481106121d2576121d26136b1565b6000918252602080832090910154808352908d905260408220909450905b600182015481101561226057816001018181548110612211576122116136b1565b600091825260208083209091015480835290849052604090912054909a50612239818d6135ff565b9b508981111561224d578099508598508a97505b5080612258816136c7565b9150506121f0565b5050808061226d906136c7565b9150506121b8565b50606954600160401b90046001600160401b031686108015906122b65750606654886122a9670de0b6b3a7640000896135cc565b6122b391906135eb565b10155b156122cd576122c88a8d8d8888612b3a565b61230f565b8b6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218c604051612306919061363d565b60405180910390a25b505050600390960180546001600160481b031916600160401b1790555050505050505050565b6001600160801b03811660009081526073602052604090206060906119ec9061299e565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561243a5783829060005260206000200180546123ad906138d0565b80601f01602080910402602001604051908101604052809291908181526020018280546123d9906138d0565b80156124265780601f106123fb57610100808354040283529160200191612426565b820191906000526020600020905b81548152906001019060200180831161240957829003601f168201915b50505050508152602001906001019061238e565b505050509050919050565b6060806060612454606c61299e565b61245e606e61299e565b612468607061299e565b925092509250909192565b61247e606e33612982565b61249a5760405162461bcd60e51b81526004016106bb9061373c565b6000816001600160401b0316116124eb5760405162461bcd60e51b815260206004820152601560248201527404e746820626c6f636b2063616e6e6f74206265203605c1b60448201526064016106bb565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b612550606e33612982565b61256c5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b0381166125bc5760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642061756469746f72206164647265737360481b60448201526064016106bb565b6001600160a01b038116600090815260746020526040902054156125f25760405162461bcd60e51b81526004016106bb906137dc565b6001600160a01b0381166000908152607460205260409020600080516020613a178339815191529055612626607082612a0a565b506000805160206139b7833981519152816000600080516020613a178339815191526040516111d79392919061380d565b612662606e33612982565b61267e5760405162461bcd60e51b81526004016106bb9061373c565b6001600160a01b038116600090815260746020526040902054600080516020613a17833981519152146126ed5760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106bb565b6001600160a01b038116600090815260746020526040812055612711607082612a5a565b50600080516020613a3783398151915281600080600080516020613a178339815191526040516111d794939291906138a0565b607b546001600160a01b0316331461276e5760405162461bcd60e51b81526004016106bb90613837565b610100816001600160801b0316106127985760405162461bcd60e51b81526004016106bb9061386e565b6001600160801b0381166000908152607a602052604090819020805460ff19166001179055517f553b029ba5c74688a5da732136d246f722502db24ed6b4aaf1cdc9f2f9ef23ef906111d79083906130f9565b6127f36129ab565b6001600160a01b0381166000908152607460205260409020546000805160206139f7833981519152146128635760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106bb565b6001600160a01b038116600090815260746020526040812055612887606e82612a5a565b50600080516020613a37833981519152816000806000805160206139f78339815191526040516111d794939291906138a0565b6128c26129ab565b6001600160a01b0381166129275760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106bb565b61293081612a6f565b50565b600080826129535760405162461bcd60e51b81526004016106bb906134a7565b50600192915050565b600080826129535760405162461bcd60e51b81526004016106bb906134d3565b51151590565b6000612997836001600160a01b038416612e2e565b9392505050565b6060600061299783612e46565b336129b46119d0565b6001600160a01b0316146118ce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106bb565b6000612997836001600160a01b038416612ea2565b600054610100900460ff16612a465760405162461bcd60e51b81526004016106bb9061390a565b6118ce612eec565b60006129978383612ea2565b6000612997836001600160a01b038416612f1c565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612acc606c82612a5a565b506001600160a01b0381166000908152607260209081526040808320546001600160801b039081168085526075909352908320805492939290911691612b1183613955565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b60008281526020868152604080832084845290915281209060028701815b8354811015612bfd576000848281548110612b7557612b756136b1565b60009182526020808320909101546001600160a01b0316808352858252604080842060729093529092205491925090612bb8906001600160801b031660ff613978565b815460016001600160801b039283161b9690961795600160801b90041615612be85780546001600160801b031681555b50508080612bf5906136c7565b915050612b58565b5084866001600160401b0316886001600160401b03167f858deae9d885ee978c04934ceabf15ebe77ae274f3af6a05ecf3bd9880b08e1e8588604051612c4d929190918252602082015260400190565b60405180910390a460005b6001890154811015612e15576000896001018281548110612c7b57612c7b6136b1565b6000918252602080832090910154808352908c905260408220909250905b6001820154811015612db7576000826001018281548110612cbc57612cbc6136b1565b6000918252602080832090910154808352858252604080842080548251818602810186019093528083529295509092909190830182828015612d2757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d09575b5050505050905060005b8151811015612d8a578e6002016000838381518110612d5257612d526136b1565b6020908102919091018101516001600160a01b0316825281019190915260400160009081205580612d82816136c7565b915050612d31565b506000828152602085905260408120612da291613093565b50508080612daf906136c7565b915050612c99565b508a60000160008c6001018581548110612dd357612dd36136b1565b906000526020600020015481526020019081526020016000206000600182016000612dfe9190613093565b505050508080612e0d906136c7565b915050612c58565b50612e24600189016000613093565b5050505050505050565b60009081526001919091016020526040902054151590565b606081600001805480602002602001604051908101604052809291908181526020018280548015612e9657602002820191906000526020600020905b815481526020019060010190808311612e82575b50505050509050919050565b6000612eae8383612e2e565b612ee4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556119ec565b5060006119ec565b600054610100900460ff16612f135760405162461bcd60e51b81526004016106bb9061390a565b6118ce33612a6f565b60008181526001830160205260408120548015613005576000612f406001836135b5565b8554909150600090612f54906001906135b5565b9050818114612fb9576000866000018281548110612f7457612f746136b1565b9060005260206000200154905080876000018481548110612f9757612f976136b1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612fca57612fca6139a0565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506119ec565b60009150506119ec565b82805461301b906138d0565b90600052602060002090601f01602090048101928261303d5760008555613083565b82601f106130565782800160ff19823516178555613083565b82800160010185558215613083579182015b82811115613083578235825591602001919060010190613068565b5061308f9291506130ad565b5090565b508054600082559060005260206000209081019061293091905b5b8082111561308f57600081556001016130ae565b80356001600160a01b03811681146130d957600080fd5b919050565b6000602082840312156130f057600080fd5b612997826130c2565b6001600160801b0391909116815260200190565b80356001600160401b03811681146130d957600080fd5b60008060008060008060a0878903121561313d57600080fd5b6131468761310d565b95506131546020880161310d565b9450604087013593506060870135925060808701356001600160401b038082111561317e57600080fd5b818901915089601f83011261319257600080fd5b8135818111156131a157600080fd5b8a60208285010111156131b357600080fd5b6020830194508093505050509295509295509295565b600081518084526020808501945080840160005b838110156132025781516001600160a01b0316875295820195908201906001016131dd565b509495945050505050565b6001600160801b0383168152604060208201819052600090613231908301846131c9565b949350505050565b60006020828403121561324b57600080fd5b6129978261310d565b6000806040838503121561326757600080fd5b6132708361310d565b915061327e6020840161310d565b90509250929050565b80356001600160801b03811681146130d957600080fd5b6000602082840312156132b057600080fd5b61299782613287565b6000602082840312156132cb57600080fd5b5035919050565b600080604083850312156132e557600080fd5b6132ee836130c2565b915061327e602084016130c2565b6001600160a01b0391909116815260200190565b6000806000806080858703121561332657600080fd5b61332f8561310d565b966020860135965060408601359560600135945092505050565b60008060006060848603121561335e57600080fd5b6133678461310d565b92506133756020850161310d565b9150613383604085016130c2565b90509250925092565b6000806040838503121561339f57600080fd5b6133a8836130c2565b915061327e60208401613287565b60208152600061299760208301846131c9565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561345657888603603f1901855282518051808852835b81811015613426578281018a01518982018b0152890161340b565b8181111561343657848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133f1565b509398975050505050505050565b60608152600061347760608301866131c9565b828103602084015261348981866131c9565b9050828103604084015261349d81856131c9565b9695505050505050565b602080825260129082015271092dcecc2d8d2c840c4d8dec6d640d0c2e6d60731b604082015260600190565b602080825260159082015274092dcecc2d8d2c840e6e0cac6d2dacadc40d0c2e6d605b1b604082015260600190565b60208082526010908201526f125b9d985b1a590818da185a5b88125160821b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60006001600160401b038381168061355c5761355c61352c565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000828210156135c7576135c761359f565b500390565b60008160001904831182151516156135e6576135e661359f565b500290565b6000826135fa576135fa61352c565b500490565b600082198211156136125761361261359f565b500190565b60006001600160801b03838116806136315761363161352c565b92169190910492915050565b6001600160401b0391909116815260200190565b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b60006001600160801b038281166002600160801b031981016136a7576136a761359f565b6001019392505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016136d9576136d961359f565b5060010190565b6001600160401b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601d908201527f5365636f6e64732070657220626c6f636b2063616e6e6f742062652030000000604082015260600190565b602080825260189082015277496e76616c696420676f7665726e6f72206164647265737360401b604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6020808252601d908201527f53656e646572206973206e6f74207374616b696e67206d616e61676572000000604082015260600190565b60208082526018908201527776616c696461746f724964206f7574206f662072616e676560401b604082015260600190565b6001600160a01b039490941684526001600160801b03928316602085015291166040830152606082015260800190565b600181811c908216806138e457607f821691505b60208210810361390457634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b0382168061396e5761396e61359f565b6000190192915050565b60006001600160801b03838116908316818110156139985761399861359f565b039392505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4298d0bb2de1c65f6d2cbc3401e3d5d5086bfe815cb57e521dafd0ebdbef6ee85c71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb159a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f5ca6d116f31cc5d708ae73029e1d63d1be48afdfd99819a3405bfbaf229748d90a26469706673582212204c0c27b00009a60128989c4cee2e5c6b763207fbae31d9d0a1857059c61e061d64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.