Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16679751 | 128 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract contains unverified libraries: PoseidonUnit2L, PoseidonUnit3L
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
SmtLib
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; import {PoseidonUnit2L, PoseidonUnit3L} from "./Poseidon.sol"; import {ArrayUtils} from "./ArrayUtils.sol"; /// @title A sparse merkle tree implementation, which keeps tree history. // Note that this SMT implementation can manage duplicated roots in the history, // which may happen when some leaf change its value and then changes it back to the original value. // Leaves deletion is not supported, although it should be possible to implement it in the future // versions of this library, without changing the existing state variables // In this way all the SMT data may be preserved for the contracts already in production. library SmtLib { /** * @dev Max return array length for SMT root history requests */ uint256 public constant ROOT_INFO_LIST_RETURN_LIMIT = 1000; /** * @dev Max depth hard cap for SMT * We can't use depth > 256 because of bits number limitation in the uint256 data type. */ uint256 public constant MAX_DEPTH_HARD_CAP = 256; /** * @dev Enum of SMT node types */ enum NodeType { EMPTY, LEAF, MIDDLE } /** * @dev Sparse Merkle Tree data * Note that we count the SMT depth starting from 0, which is the root level. * * For example, the following tree has a maxDepth = 2: * * O <- root level (depth = 0) * / \ * O O <- depth = 1 * / \ / \ * O O O O <- depth = 2 */ struct Data { mapping(uint256 => Node) nodes; RootEntry[] rootEntries; mapping(uint256 => uint256[]) rootIndexes; // root => rootEntryIndex[] uint256 maxDepth; bool initialized; // This empty reserved space is put in place to allow future versions // of the SMT library to add new Data struct fields without shifting down // storage of upgradable contracts that use this struct as a state variable // (see https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps) uint256[45] __gap; } /** * @dev Struct of the node proof in the SMT. * @param root This SMT root. * @param existence A flag, which shows if the leaf index exists in the SMT. * @param siblings An array of SMT sibling node hashes. * @param index An index of the leaf in the SMT. * @param value A value of the leaf in the SMT. * @param auxExistence A flag, which shows if the auxiliary leaf exists in the SMT. * @param auxIndex An index of the auxiliary leaf in the SMT. * @param auxValue An value of the auxiliary leaf in the SMT. */ struct Proof { uint256 root; bool existence; uint256[] siblings; uint256 index; uint256 value; bool auxExistence; uint256 auxIndex; uint256 auxValue; } /** * @dev Struct for SMT root internal storage representation. * @param root SMT root. * @param createdAtTimestamp A time, when the root was saved to blockchain. * @param createdAtBlock A number of block, when the root was saved to blockchain. */ struct RootEntry { uint256 root; uint256 createdAtTimestamp; uint256 createdAtBlock; } /** * @dev Struct for public interfaces to represent SMT root info. * @param root This SMT root. * @param replacedByRoot A root, which replaced this root. * @param createdAtTimestamp A time, when the root was saved to blockchain. * @param replacedAtTimestamp A time, when the root was replaced by the next root in blockchain. * @param createdAtBlock A number of block, when the root was saved to blockchain. * @param replacedAtBlock A number of block, when the root was replaced by the next root in blockchain. */ struct RootEntryInfo { uint256 root; uint256 replacedByRoot; uint256 createdAtTimestamp; uint256 replacedAtTimestamp; uint256 createdAtBlock; uint256 replacedAtBlock; } /** * @dev Struct of SMT node. * @param NodeType type of node. * @param childLeft left child of node. * @param childRight right child of node. * @param Index index of node. * @param Value value of node. */ struct Node { NodeType nodeType; uint256 childLeft; uint256 childRight; uint256 index; uint256 value; } using BinarySearchSmtRoots for Data; using ArrayUtils for uint256[]; /** * @dev Reverts if root does not exist in SMT roots history. * @param root SMT root. */ modifier onlyExistingRoot(Data storage self, uint256 root) { require(rootExists(self, root), "Root does not exist"); _; } /** * @dev Add a leaf to the SMT * @param i Index of a leaf * @param v Value of a leaf */ function addLeaf(Data storage self, uint256 i, uint256 v) external onlyInitialized(self) { Node memory node = Node({ nodeType: NodeType.LEAF, childLeft: 0, childRight: 0, index: i, value: v }); uint256 prevRoot = getRoot(self); uint256 newRoot = _addLeaf(self, node, prevRoot, 0); _addEntry(self, newRoot, block.timestamp, block.number); } /** * @dev Get SMT root history length * @return SMT history length */ function getRootHistoryLength(Data storage self) external view returns (uint256) { return self.rootEntries.length; } /** * @dev Get SMT root history * @param startIndex start index of history * @param length history length * @return array of RootEntryInfo structs */ function getRootHistory( Data storage self, uint256 startIndex, uint256 length ) external view returns (RootEntryInfo[] memory) { (uint256 start, uint256 end) = ArrayUtils.calculateBounds( self.rootEntries.length, startIndex, length, ROOT_INFO_LIST_RETURN_LIMIT ); RootEntryInfo[] memory result = new RootEntryInfo[](end - start); for (uint256 i = start; i < end; i++) { result[i - start] = _getRootInfoByIndex(self, i); } return result; } /** * @dev Get the SMT node by hash * @param nodeHash Hash of a node * @return A node struct */ function getNode(Data storage self, uint256 nodeHash) public view returns (Node memory) { return self.nodes[nodeHash]; } /** * @dev Get the proof if a node with specific index exists or not exists in the SMT. * @param index A node index. * @return SMT proof struct. */ function getProof(Data storage self, uint256 index) external view returns (Proof memory) { return getProofByRoot(self, index, getRoot(self)); } /** * @dev Get the proof if a node with specific index exists or not exists in the SMT for some historical tree state. * @param index A node index * @param historicalRoot Historical SMT roof to get proof for. * @return Proof struct. */ function getProofByRoot( Data storage self, uint256 index, uint256 historicalRoot ) public view onlyExistingRoot(self, historicalRoot) returns (Proof memory) { uint256[] memory siblings = new uint256[](self.maxDepth); // Solidity does not guarantee that memory vars are zeroed out for (uint256 i = 0; i < self.maxDepth; i++) { siblings[i] = 0; } Proof memory proof = Proof({ root: historicalRoot, existence: false, siblings: siblings, index: index, value: 0, auxExistence: false, auxIndex: 0, auxValue: 0 }); uint256 nextNodeHash = historicalRoot; Node memory node; for (uint256 i = 0; i <= self.maxDepth; i++) { node = getNode(self, nextNodeHash); if (node.nodeType == NodeType.EMPTY) { break; } else if (node.nodeType == NodeType.LEAF) { if (node.index == proof.index) { proof.existence = true; proof.value = node.value; break; } else { proof.auxExistence = true; proof.auxIndex = node.index; proof.auxValue = node.value; proof.value = node.value; break; } } else if (node.nodeType == NodeType.MIDDLE) { if ((proof.index >> i) & 1 == 1) { nextNodeHash = node.childRight; proof.siblings[i] = node.childLeft; } else { nextNodeHash = node.childLeft; proof.siblings[i] = node.childRight; } } else { revert("Invalid node type"); } } return proof; } /** * @dev Get the proof if a node with specific index exists or not exists in the SMT by some historical timestamp. * @param index Node index. * @param timestamp The latest timestamp to get proof for. * @return Proof struct. */ function getProofByTime( Data storage self, uint256 index, uint256 timestamp ) public view returns (Proof memory) { RootEntryInfo memory rootInfo = getRootInfoByTime(self, timestamp); return getProofByRoot(self, index, rootInfo.root); } /** * @dev Get the proof if a node with specific index exists or not exists in the SMT by some historical block number. * @param index Node index. * @param blockNumber The latest block number to get proof for. * @return Proof struct. */ function getProofByBlock( Data storage self, uint256 index, uint256 blockNumber ) external view returns (Proof memory) { RootEntryInfo memory rootInfo = getRootInfoByBlock(self, blockNumber); return getProofByRoot(self, index, rootInfo.root); } function getRoot(Data storage self) public view onlyInitialized(self) returns (uint256) { return self.rootEntries[self.rootEntries.length - 1].root; } /** * @dev Get root info by some historical timestamp. * @param timestamp The latest timestamp to get the root info for. * @return Root info struct */ function getRootInfoByTime( Data storage self, uint256 timestamp ) public view returns (RootEntryInfo memory) { require(timestamp <= block.timestamp, "No future timestamps allowed"); return _getRootInfoByTimestampOrBlock( self, timestamp, BinarySearchSmtRoots.SearchType.TIMESTAMP ); } /** * @dev Get root info by some historical block number. * @param blockN The latest block number to get the root info for. * @return Root info struct */ function getRootInfoByBlock( Data storage self, uint256 blockN ) public view returns (RootEntryInfo memory) { require(blockN <= block.number, "No future blocks allowed"); return _getRootInfoByTimestampOrBlock(self, blockN, BinarySearchSmtRoots.SearchType.BLOCK); } /** * @dev Returns root info by root * @param root root * @return Root info struct */ function getRootInfo( Data storage self, uint256 root ) public view onlyExistingRoot(self, root) returns (RootEntryInfo memory) { uint256[] storage indexes = self.rootIndexes[root]; uint256 lastIndex = indexes[indexes.length - 1]; return _getRootInfoByIndex(self, lastIndex); } /** * @dev Retrieve duplicate root quantity by id and state. * If the root repeats more that once, the length may be greater than 1. * @param root A root. * @return Root root entries quantity. */ function getRootInfoListLengthByRoot( Data storage self, uint256 root ) public view returns (uint256) { return self.rootIndexes[root].length; } /** * @dev Retrieve root infos list of duplicated root by id and state. * If the root repeats more that once, the length list may be greater than 1. * @param root A root. * @param startIndex The index to start the list. * @param length The length of the list. * @return Root Root entries quantity. */ function getRootInfoListByRoot( Data storage self, uint256 root, uint256 startIndex, uint256 length ) public view onlyExistingRoot(self, root) returns (RootEntryInfo[] memory) { uint256[] storage indexes = self.rootIndexes[root]; (uint256 start, uint256 end) = ArrayUtils.calculateBounds( indexes.length, startIndex, length, ROOT_INFO_LIST_RETURN_LIMIT ); RootEntryInfo[] memory result = new RootEntryInfo[](end - start); for (uint256 i = start; i < end; i++) { result[i - start] = _getRootInfoByIndex(self, indexes[i]); } return result; } /** * @dev Checks if root exists * @param root root * return true if root exists */ function rootExists(Data storage self, uint256 root) public view returns (bool) { return self.rootIndexes[root].length > 0; } /** * @dev Sets max depth of the SMT * @param maxDepth max depth */ function setMaxDepth(Data storage self, uint256 maxDepth) public { require(maxDepth > 0, "Max depth must be greater than zero"); require(maxDepth > self.maxDepth, "Max depth can only be increased"); require(maxDepth <= MAX_DEPTH_HARD_CAP, "Max depth is greater than hard cap"); self.maxDepth = maxDepth; } /** * @dev Gets max depth of the SMT * return max depth */ function getMaxDepth(Data storage self) external view returns (uint256) { return self.maxDepth; } /** * @dev Initialize SMT with max depth and root entry of an empty tree. * @param maxDepth Max depth of the SMT. */ function initialize(Data storage self, uint256 maxDepth) external { require(!isInitialized(self), "Smt is already initialized"); setMaxDepth(self, maxDepth); _addEntry(self, 0, 0, 0); self.initialized = true; } modifier onlyInitialized(Data storage self) { require(isInitialized(self), "Smt is not initialized"); _; } function isInitialized(Data storage self) public view returns (bool) { return self.initialized; } function _addLeaf( Data storage self, Node memory newLeaf, uint256 nodeHash, uint256 depth ) internal returns (uint256) { if (depth > self.maxDepth) { revert("Max depth reached"); } Node memory node = self.nodes[nodeHash]; uint256 nextNodeHash; uint256 leafHash = 0; if (node.nodeType == NodeType.EMPTY) { leafHash = _addNode(self, newLeaf); } else if (node.nodeType == NodeType.LEAF) { leafHash = node.index == newLeaf.index ? _addNode(self, newLeaf) : _pushLeaf(self, newLeaf, node, depth); } else if (node.nodeType == NodeType.MIDDLE) { Node memory newNodeMiddle; if ((newLeaf.index >> depth) & 1 == 1) { nextNodeHash = _addLeaf(self, newLeaf, node.childRight, depth + 1); newNodeMiddle = Node({ nodeType: NodeType.MIDDLE, childLeft: node.childLeft, childRight: nextNodeHash, index: 0, value: 0 }); } else { nextNodeHash = _addLeaf(self, newLeaf, node.childLeft, depth + 1); newNodeMiddle = Node({ nodeType: NodeType.MIDDLE, childLeft: nextNodeHash, childRight: node.childRight, index: 0, value: 0 }); } leafHash = _addNode(self, newNodeMiddle); } return leafHash; } function _pushLeaf( Data storage self, Node memory newLeaf, Node memory oldLeaf, uint256 depth ) internal returns (uint256) { // no reason to continue if we are at max possible depth // as, anyway, we exceed the depth going down the tree if (depth >= self.maxDepth) { revert("Max depth reached"); } Node memory newNodeMiddle; bool newLeafBitAtDepth = (newLeaf.index >> depth) & 1 == 1; bool oldLeafBitAtDepth = (oldLeaf.index >> depth) & 1 == 1; // Check if we need to go deeper if diverge at the depth's bit if (newLeafBitAtDepth == oldLeafBitAtDepth) { uint256 nextNodeHash = _pushLeaf(self, newLeaf, oldLeaf, depth + 1); if (newLeafBitAtDepth) { // go right newNodeMiddle = Node(NodeType.MIDDLE, 0, nextNodeHash, 0, 0); } else { // go left newNodeMiddle = Node(NodeType.MIDDLE, nextNodeHash, 0, 0, 0); } return _addNode(self, newNodeMiddle); } if (newLeafBitAtDepth) { newNodeMiddle = Node({ nodeType: NodeType.MIDDLE, childLeft: _getNodeHash(oldLeaf), childRight: _getNodeHash(newLeaf), index: 0, value: 0 }); } else { newNodeMiddle = Node({ nodeType: NodeType.MIDDLE, childLeft: _getNodeHash(newLeaf), childRight: _getNodeHash(oldLeaf), index: 0, value: 0 }); } _addNode(self, newLeaf); return _addNode(self, newNodeMiddle); } function _addNode(Data storage self, Node memory node) internal returns (uint256) { uint256 nodeHash = _getNodeHash(node); // We don't have any guarantees if the hash function attached is good enough. // So, if the node hash already exists, we need to check // if the node in the tree exactly matches the one we are trying to add. if (self.nodes[nodeHash].nodeType != NodeType.EMPTY) { assert(self.nodes[nodeHash].nodeType == node.nodeType); assert(self.nodes[nodeHash].childLeft == node.childLeft); assert(self.nodes[nodeHash].childRight == node.childRight); assert(self.nodes[nodeHash].index == node.index); assert(self.nodes[nodeHash].value == node.value); return nodeHash; } self.nodes[nodeHash] = node; return nodeHash; } function _getNodeHash(Node memory node) internal pure returns (uint256) { uint256 nodeHash = 0; if (node.nodeType == NodeType.LEAF) { uint256[3] memory params = [node.index, node.value, uint256(1)]; nodeHash = PoseidonUnit3L.poseidon(params); } else if (node.nodeType == NodeType.MIDDLE) { nodeHash = PoseidonUnit2L.poseidon([node.childLeft, node.childRight]); } return nodeHash; // Note: expected to return 0 if NodeType.EMPTY, which is the only option left } function _getRootInfoByIndex( Data storage self, uint256 index ) internal view returns (RootEntryInfo memory) { bool isLastRoot = index == self.rootEntries.length - 1; RootEntry storage rootEntry = self.rootEntries[index]; return RootEntryInfo({ root: rootEntry.root, replacedByRoot: isLastRoot ? 0 : self.rootEntries[index + 1].root, createdAtTimestamp: rootEntry.createdAtTimestamp, replacedAtTimestamp: isLastRoot ? 0 : self.rootEntries[index + 1].createdAtTimestamp, createdAtBlock: rootEntry.createdAtBlock, replacedAtBlock: isLastRoot ? 0 : self.rootEntries[index + 1].createdAtBlock }); } function _getRootInfoByTimestampOrBlock( Data storage self, uint256 timestampOrBlock, BinarySearchSmtRoots.SearchType searchType ) internal view returns (RootEntryInfo memory) { (uint256 index, bool found) = self.binarySearchUint256(timestampOrBlock, searchType); // As far as we always have at least one root entry, we should always find it assert(found); return _getRootInfoByIndex(self, index); } function _addEntry( Data storage self, uint256 root, uint256 _timestamp, uint256 _block ) internal { self.rootEntries.push( RootEntry({root: root, createdAtTimestamp: _timestamp, createdAtBlock: _block}) ); self.rootIndexes[root].push(self.rootEntries.length - 1); } } /// @title A binary search for the sparse merkle tree root history // Implemented as a separate library for testing purposes library BinarySearchSmtRoots { /** * @dev Enum for the SMT history field selection */ enum SearchType { TIMESTAMP, BLOCK } /** * @dev Binary search method for the SMT history, * which searches for the index of the root entry saved by the given timestamp or block * @param value The timestamp or block to search for. * @param searchType The type of the search (timestamp or block). */ function binarySearchUint256( SmtLib.Data storage self, uint256 value, SearchType searchType ) internal view returns (uint256, bool) { if (self.rootEntries.length == 0) { return (0, false); } uint256 min = 0; uint256 max = self.rootEntries.length - 1; uint256 mid; while (min <= max) { mid = (max + min) / 2; uint256 midValue = fieldSelector(self.rootEntries[mid], searchType); if (midValue == value) { while (mid < self.rootEntries.length - 1) { uint256 nextValue = fieldSelector(self.rootEntries[mid + 1], searchType); if (nextValue == value) { mid++; } else { return (mid, true); } } return (mid, true); } else if (value > midValue) { min = mid + 1; } else if (value < midValue && mid > 0) { // mid > 0 is to avoid underflow max = mid - 1; } else { // This means that value < midValue && mid == 0. So we found nothing. return (0, false); } } // The case when the searched value does not exist and we should take the closest smaller value // Index in the "max" var points to the root entry with max value smaller than the searched value return (max, true); } /** * @dev Selects either timestamp or block field from the root entry struct * depending on the search type * @param rti The root entry to select the field from. * @param st The search type. */ function fieldSelector( SmtLib.RootEntry memory rti, SearchType st ) internal pure returns (uint256) { if (st == SearchType.BLOCK) { return rti.createdAtBlock; } else if (st == SearchType.TIMESTAMP) { return rti.createdAtTimestamp; } else { revert("Invalid search type"); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; /// @title A common functions for arrays. library ArrayUtils { /** * @dev Calculates bounds for the slice of the array. * @param arrLength An array length. * @param start A start index. * @param length A length of the slice. * @param limit A limit for the length. * @return The bounds for the slice of the array. */ function calculateBounds( uint256 arrLength, uint256 start, uint256 length, uint256 limit ) internal pure returns (uint256, uint256) { require(length > 0, "Length should be greater than 0"); require(length <= limit, "Length limit exceeded"); require(start < arrLength, "Start index out of bounds"); uint256 end = start + length; if (end > arrLength) { end = arrLength; } return (start, end); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.27; library PoseidonUnit1L { function poseidon(uint256[1] calldata) public pure returns (uint256) {} } library PoseidonUnit2L { function poseidon(uint256[2] calldata) public pure returns (uint256) {} } library PoseidonUnit3L { function poseidon(uint256[3] calldata) public pure returns (uint256) {} } library PoseidonUnit4L { function poseidon(uint256[4] calldata) public pure returns (uint256) {} } library PoseidonUnit5L { function poseidon(uint256[5] calldata) public pure returns (uint256) {} } library PoseidonUnit6L { function poseidon(uint256[6] calldata) public pure returns (uint256) {} } library SpongePoseidon { uint32 internal constant BATCH_SIZE = 6; function hash(uint256[] memory values) public pure returns (uint256) { uint256[BATCH_SIZE] memory frame = [uint256(0), 0, 0, 0, 0, 0]; bool dirty = false; uint256 fullHash = 0; uint32 k = 0; for (uint32 i = 0; i < values.length; i++) { dirty = true; frame[k] = values[i]; if (k == BATCH_SIZE - 1) { fullHash = PoseidonUnit6L.poseidon(frame); dirty = false; frame = [uint256(0), 0, 0, 0, 0, 0]; frame[0] = fullHash; k = 1; } else { k++; } } if (dirty) { // we haven't hashed something in the main sponge loop and need to do hash here fullHash = PoseidonUnit6L.poseidon(frame); } return fullHash; } } library PoseidonFacade { function poseidon1(uint256[1] calldata el) public pure returns (uint256) { return PoseidonUnit1L.poseidon(el); } function poseidon2(uint256[2] calldata el) public pure returns (uint256) { return PoseidonUnit2L.poseidon(el); } function poseidon3(uint256[3] calldata el) public pure returns (uint256) { return PoseidonUnit3L.poseidon(el); } function poseidon4(uint256[4] calldata el) public pure returns (uint256) { return PoseidonUnit4L.poseidon(el); } function poseidon5(uint256[5] calldata el) public pure returns (uint256) { return PoseidonUnit5L.poseidon(el); } function poseidon6(uint256[6] calldata el) public pure returns (uint256) { return PoseidonUnit6L.poseidon(el); } function poseidonSponge(uint256[] calldata el) public pure returns (uint256) { return SpongePoseidon.hash(el); } }
{ "evmVersion": "paris", "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/lib/Poseidon.sol": { "PoseidonUnit2L": "0x72f721d9d5f91353b505207c63b56cf3d9447edb", "PoseidonUnit3L": "0x5bc89782d5ebf62663df7ce5fb4bc7408926a240" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"MAX_DEPTH_HARD_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_INFO_LIST_RETURN_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
612f43610052600b82828239805160001a6073146045577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106101405760003560e01c806379f97125116100c2578063a751be2411610086578063a751be24146103f5578063c1d29f0114610413578063dc9a7c8c1461043c578063dea7633a1461046c578063e170cf6e1461049c578063ec145108146104cc57610140565b806379f971251461030c578063893f99f31461033c57806391761b751461036c57806392f5b06c1461039c5780639e43b813146103cc57610140565b806340a73d981161010957806340a73d981461022e5780635db40cda1461024c57806362e8f2151461027c578063792a470f146102ac57806379c17a96146102dc57610140565b806278f030146101455780630912610a14610175578063138271361461019e57806317c850f0146101ce57806321d60953146101fe575b600080fd5b61015f600480360381019061015a9190611f7a565b6104fc565b60405161016c9190611fc9565b60405180910390f35b81801561018157600080fd5b5061019c60048036038101906101979190611f7a565b61051f565b005b6101b860048036038101906101b39190611fe4565b6105fa565b6040516101c591906121c0565b60405180910390f35b6101e860048036038101906101e39190611f7a565b610629565b6040516101f5919061225d565b60405180910390f35b61021860048036038101906102139190611fe4565b610688565b60405161022591906123a2565b60405180910390f35b610236610765565b6040516102439190611fc9565b60405180910390f35b61026660048036038101906102619190611f7a565b61076b565b60405161027391906121c0565b60405180910390f35b610296600480360381019061029191906123c4565b61078e565b6040516102a39190611fc9565b60405180910390f35b6102c660048036038101906102c19190611fe4565b61079f565b6040516102d391906121c0565b60405180910390f35b6102f660048036038101906102f19190611fe4565b6107ce565b60405161030391906121c0565b60405180910390f35b610326600480360381019061032191906123c4565b610afa565b6040516103339190611fc9565b60405180910390f35b610356600480360381019061035191906123c4565b610b88565b6040516103639190611fc9565b60405180910390f35b610386600480360381019061038191906123f1565b610b96565b60405161039391906123a2565b60405180910390f35b6103b660048036038101906103b19190611f7a565b610cf5565b6040516103c39190612467565b60405180910390f35b8180156103d857600080fd5b506103f360048036038101906103ee9190611f7a565b610d1a565b005b6103fd610d9c565b60405161040a9190611fc9565b60405180910390f35b81801561041f57600080fd5b5061043a60048036038101906104359190611fe4565b610da2565b005b61045660048036038101906104519190611f7a565b610e5e565b604051610463919061225d565b60405180910390f35b61048660048036038101906104819190611f7a565b610ebd565b604051610493919061225d565b60405180910390f35b6104b660048036038101906104b19190611f7a565b610f71565b6040516104c39190612561565b60405180910390f35b6104e660048036038101906104e191906123c4565b611004565b6040516104f39190612467565b60405180910390f35b600082600201600083815260200190815260200160002080549050905092915050565b60008111610562576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610559906125ff565b60405180910390fd5b816003015481116105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f9061266b565b60405180910390fd5b6101008111156105ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e4906126fd565b60405180910390fd5b8082600301819055505050565b610602611e49565b600061060e8584610629565b905061061f858583600001516107ce565b9150509392505050565b610631611e92565b42821115610674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066b90612769565b60405180910390fd5b6106808383600061101f565b905092915050565b60606000806106a2866001018054905086866103e8611066565b91509150600082826106b491906127b8565b67ffffffffffffffff8111156106cd576106cc6127ec565b5b60405190808252806020026020018201604052801561070657816020015b6106f3611e92565b8152602001906001900390816106eb5790505b50905060008390505b8281101561075757610721888261115d565b82858361072e91906127b8565b8151811061073f5761073e61281b565b5b6020026020010181905250808060010191505061070f565b508093505050509392505050565b6103e881565b610773611e49565b610786838361078186610afa565b6107ce565b905092915050565b600081600101805490509050919050565b6107a7611e49565b60006107b38584610e5e565b90506107c4858583600001516107ce565b9150509392505050565b6107d6611e49565b83826107e28282610cf5565b610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081890612896565b60405180910390fd5b6000866003015467ffffffffffffffff811115610841576108406127ec565b5b60405190808252806020026020018201604052801561086f5781602001602082028036833780820191505090505b50905060005b87600301548110156108af5760008282815181106108965761089561281b565b5b6020026020010181815250508080600101915050610875565b5060006040518061010001604052808781526020016000151581526020018381526020018881526020016000815260200160001515815260200160008152602001600081525090506000869050610904611ec8565b60005b8a600301548111610ae95761091c8b84610f71565b91506000600281111561093257610931612482565b5b8260000151600281111561094957610948612482565b5b0315610ae9576001600281111561096357610962612482565b5b8260000151600281111561097a57610979612482565b5b036109f25783606001518260600151036109b25760018460200190151590811515815250508160800151846080018181525050610ae9565b60018460a001901515908115158152505081606001518460c001818152505081608001518460e00181815250508160800151846080018181525050610ae9565b600280811115610a0557610a04612482565b5b82600001516002811115610a1c57610a1b612482565b5b03610a9b57600180828660600151901c1603610a665781604001519250816020015184604001518281518110610a5557610a5461281b565b5b602002602001018181525050610a96565b81602001519250816040015184604001518281518110610a8957610a8861281b565b5b6020026020010181815250505b610ad6565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90612902565b60405180910390fd5b8080610ae190612922565b915050610907565b508296505050505050509392505050565b600081610b0681611004565b610b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3c906129b6565b60405180910390fd5b8260010160018460010180549050610b5d91906127b8565b81548110610b6e57610b6d61281b565b5b906000526020600020906003020160000154915050919050565b600081600301549050919050565b60608484610ba48282610cf5565b610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda90612896565b60405180910390fd5b60008760020160008881526020019081526020016000209050600080610c11838054905089896103e8611066565b9150915060008282610c2391906127b8565b67ffffffffffffffff811115610c3c57610c3b6127ec565b5b604051908082528060200260200182016040528015610c7557816020015b610c62611e92565b815260200190600190039081610c5a5790505b50905060008390505b82811015610ce357610cad8c868381548110610c9d57610c9c61281b565b5b906000526020600020015461115d565b828583610cba91906127b8565b81518110610ccb57610cca61281b565b5b60200260200101819052508080600101915050610c7e565b50809650505050505050949350505050565b6000808360020160008481526020019081526020016000208054905011905092915050565b610d2382611004565b15610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612a22565b60405180910390fd5b610d6d828261051f565b610d7b8260008060006112aa565b60018260040160006101000a81548160ff0219169083151502179055505050565b61010081565b82610dac81611004565b610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de2906129b6565b60405180910390fd5b60006040518060a0016040528060016002811115610e0c57610e0b612482565b5b815260200160008152602001600081526020018581526020018481525090506000610e3686610afa565b90506000610e478784846000611367565b9050610e55878242436112aa565b50505050505050565b610e66611e92565b43821115610ea9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea090612a8e565b60405180910390fd5b610eb58383600161101f565b905092915050565b610ec5611e92565b8282610ed18282610cf5565b610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0790612896565b60405180910390fd5b6000856002016000868152602001908152602001600020905060008160018380549050610f3d91906127b8565b81548110610f4e57610f4d61281b565b5b90600052602060002001549050610f65878261115d565b94505050505092915050565b610f79611ec8565b8260000160008381526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff166002811115610fbe57610fbd612482565b5b6002811115610fd057610fcf612482565b5b8152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905092915050565b60008160040160009054906101000a900460ff169050919050565b611027611e92565b60008061103f85858861160b9092919063ffffffff16565b915091508061105157611050612aae565b5b61105b868361115d565b925050509392505050565b600080600084116110ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a390612b29565b60405180910390fd5b828411156110ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e690612b95565b60405180910390fd5b858510611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890612c01565b60405180910390fd5b6000848661113f9190612c21565b90508681111561114d578690505b8581925092505094509492505050565b611165611e92565b60006001846001018054905061117b91906127b8565b8314905060008460010184815481106111975761119661281b565b5b906000526020600020906003020190506040518060c0016040528082600001548152602001836111fa57866001016001876111d29190612c21565b815481106111e3576111e261281b565b5b9060005260206000209060030201600001546111fd565b60005b8152602001826001015481526020018361124a57866001016001876112229190612c21565b815481106112335761123261281b565b5b90600052602060002090600302016001015461124d565b60005b8152602001826002015481526020018361129a57866001016001876112729190612c21565b815481106112835761128261281b565b5b90600052602060002090600302016002015461129d565b60005b8152509250505092915050565b83600101604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550508360020160008481526020019081526020016000206001856001018054905061133b91906127b8565b908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600084600301548211156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a790612ca1565b60405180910390fd5b60008560000160008581526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff1660028111156113f7576113f6612482565b5b600281111561140957611408612482565b5b81526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600080600090506000600281111561145257611451612482565b5b8360000151600281111561146957611468612482565b5b0361147f5761147888886117f8565b90506115fd565b6001600281111561149357611492612482565b5b836000015160028111156114aa576114a9612482565b5b036114e15786606001518360600151146114cf576114ca888885886119e9565b6114da565b6114d988886117f8565b5b90506115fc565b6002808111156114f4576114f3612482565b5b8360000151600281111561150b5761150a612482565b5b036115fb57611518611ec8565b600180878a60600151901c160361158d576115458989866040015160018a6115409190612c21565b611367565b92506040518060a0016040528060028081111561156557611564612482565b5b81526020018560200151815260200184815260200160008152602001600081525090506115ed565b6115a98989866020015160018a6115a49190612c21565b611367565b92506040518060a001604052806002808111156115c9576115c8612482565b5b81526020018481526020018560400151815260200160008152602001600081525090505b6115f789826117f8565b9150505b5b5b809350505050949350505050565b600080600085600101805490500361162957600080915091506117f0565b6000806001876001018054905061164091906127b8565b905060005b8183116117e5576002838361165a9190612c21565b6116649190612cf0565b905060006116be8960010183815481106116815761168061281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505088611be8565b905087810361178a575b600189600101805490506116dc91906127b8565b82101561177a5760006117478a6001016001856116f99190612c21565b8154811061170a5761170961281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505089611be8565b905088810361176357828061175b90612922565b935050611774565b8260019650965050505050506117f0565b506116c8565b81600195509550505050506117f0565b808811156117a65760018261179f9190612c21565b93506117df565b80881080156117b55750600082115b156117ce576001826117c791906127b8565b92506117de565b60008095509550505050506117f0565b5b50611645565b816001945094505050505b935093915050565b60008061180483611c9a565b90506000600281111561181a57611819612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff16600281111561185257611851612482565b5b1461196d578260000151600281111561186e5761186d612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff1660028111156118a6576118a5612482565b5b146118b4576118b3612aae565b5b826020015184600001600083815260200190815260200160002060010154146118e0576118df612aae565b5b8260400151846000016000838152602001908152602001600020600201541461190c5761190b612aae565b5b8260600151846000016000838152602001908152602001600020600301541461193857611937612aae565b5b8260800151846000016000838152602001908152602001600020600401541461196457611963612aae565b5b809150506119e3565b8284600001600083815260200190815260200160002060008201518160000160006101000a81548160ff021916908360028111156119ae576119ad612482565b5b021790555060208201518160010155604082015181600201556060820151816003015560808201518160040155905050809150505b92915050565b600084600301548210611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2890612ca1565b60405180910390fd5b611a39611ec8565b6000600180858860600151901c161490506000600180868860600151901c1614905080151582151503611b1f576000611a8089898960018a611a7b9190612c21565b6119e9565b90508215611acb576040518060a00160405280600280811115611aa657611aa5612482565b5b8152602001600081526020018281526020016000815260200160008152509350611b0a565b6040518060a00160405280600280811115611ae957611ae8612482565b5b81526020018281526020016000815260200160008152602001600081525093505b611b1489856117f8565b945050505050611be0565b8115611b77576040518060a00160405280600280811115611b4357611b42612482565b5b8152602001611b5188611c9a565b8152602001611b5f89611c9a565b81526020016000815260200160008152509250611bc5565b6040518060a00160405280600280811115611b9557611b94612482565b5b8152602001611ba389611c9a565b8152602001611bb188611c9a565b815260200160008152602001600081525092505b611bcf88886117f8565b50611bda88846117f8565b93505050505b949350505050565b6000600180811115611bfd57611bfc612482565b5b826001811115611c1057611c0f612482565b5b03611c215782604001519050611c94565b60006001811115611c3557611c34612482565b5b826001811115611c4857611c47612482565b5b03611c595782602001519050611c94565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8b90612d6d565b60405180910390fd5b92915050565b6000806000905060016002811115611cb557611cb4612482565b5b83600001516002811115611ccc57611ccb612482565b5b03611d795760006040518060600160405280856060015181526020018560800151815260200160018152509050735bc89782d5ebf62663df7ce5fb4bc7408926a2406325cc70e8826040518263ffffffff1660e01b8152600401611d309190612e11565b602060405180830381865af4158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e41565b915050611e40565b600280811115611d8c57611d8b612482565b5b83600001516002811115611da357611da2612482565b5b03611e3f577372f721d9d5f91353b505207c63b56cf3d9447edb6329a5f2f660405180604001604052808660200151815260200186604001518152506040518263ffffffff1660e01b8152600401611dfb9190612ef2565b602060405180830381865af4158015611e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3c9190612e41565b90505b5b80915050919050565b6040518061010001604052806000815260200160001515815260200160608152602001600081526020016000815260200160001515815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060006002811115611ee757611ee6612482565b5b8152602001600081526020016000815260200160008152602001600081525090565b600080fd5b6000819050919050565b611f2181611f0e565b8114611f2c57600080fd5b50565b600081359050611f3e81611f18565b92915050565b6000819050919050565b611f5781611f44565b8114611f6257600080fd5b50565b600081359050611f7481611f4e565b92915050565b60008060408385031215611f9157611f90611f09565b5b6000611f9f85828601611f2f565b9250506020611fb085828601611f65565b9150509250929050565b611fc381611f44565b82525050565b6000602082019050611fde6000830184611fba565b92915050565b600080600060608486031215611ffd57611ffc611f09565b5b600061200b86828701611f2f565b935050602061201c86828701611f65565b925050604061202d86828701611f65565b9150509250925092565b61204081611f44565b82525050565b60008115159050919050565b61205b81612046565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006120998383612037565b60208301905092915050565b6000602082019050919050565b60006120bd82612061565b6120c7818561206c565b93506120d28361207d565b8060005b838110156121035781516120ea888261208d565b97506120f5836120a5565b9250506001810190506120d6565b5085935050505092915050565b6000610100830160008301516121296000860182612037565b50602083015161213c6020860182612052565b506040830151848203604086015261215482826120b2565b91505060608301516121696060860182612037565b50608083015161217c6080860182612037565b5060a083015161218f60a0860182612052565b5060c08301516121a260c0860182612037565b5060e08301516121b560e0860182612037565b508091505092915050565b600060208201905081810360008301526121da8184612110565b905092915050565b60c0820160008201516121f86000850182612037565b50602082015161220b6020850182612037565b50604082015161221e6040850182612037565b5060608201516122316060850182612037565b5060808201516122446080850182612037565b5060a082015161225760a0850182612037565b50505050565b600060c08201905061227260008301846121e2565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60c0820160008201516122ba6000850182612037565b5060208201516122cd6020850182612037565b5060408201516122e06040850182612037565b5060608201516122f36060850182612037565b5060808201516123066080850182612037565b5060a082015161231960a0850182612037565b50505050565b600061232b83836122a4565b60c08301905092915050565b6000602082019050919050565b600061234f82612278565b6123598185612283565b935061236483612294565b8060005b8381101561239557815161237c888261231f565b975061238783612337565b925050600181019050612368565b5085935050505092915050565b600060208201905081810360008301526123bc8184612344565b905092915050565b6000602082840312156123da576123d9611f09565b5b60006123e884828501611f2f565b91505092915050565b6000806000806080858703121561240b5761240a611f09565b5b600061241987828801611f2f565b945050602061242a87828801611f65565b935050604061243b87828801611f65565b925050606061244c87828801611f65565b91505092959194509250565b61246181612046565b82525050565b600060208201905061247c6000830184612458565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106124c2576124c1612482565b5b50565b60008190506124d3826124b1565b919050565b60006124e3826124c5565b9050919050565b6124f3816124d8565b82525050565b60a08201600082015161250f60008501826124ea565b5060208201516125226020850182612037565b5060408201516125356040850182612037565b5060608201516125486060850182612037565b50608082015161255b6080850182612037565b50505050565b600060a08201905061257660008301846124f9565b92915050565b600082825260208201905092915050565b7f4d6178206465707468206d7573742062652067726561746572207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006125e960238361257c565b91506125f48261258d565b604082019050919050565b60006020820190508181036000830152612618816125dc565b9050919050565b7f4d61782064657074682063616e206f6e6c7920626520696e6372656173656400600082015250565b6000612655601f8361257c565b91506126608261261f565b602082019050919050565b6000602082019050818103600083015261268481612648565b9050919050565b7f4d61782064657074682069732067726561746572207468616e2068617264206360008201527f6170000000000000000000000000000000000000000000000000000000000000602082015250565b60006126e760228361257c565b91506126f28261268b565b604082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b7f4e6f206675747572652074696d657374616d707320616c6c6f77656400000000600082015250565b6000612753601c8361257c565b915061275e8261271d565b602082019050919050565b6000602082019050818103600083015261278281612746565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006127c382611f44565b91506127ce83611f44565b92508282039050818111156127e6576127e5612789565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f526f6f7420646f6573206e6f7420657869737400000000000000000000000000600082015250565b600061288060138361257c565b915061288b8261284a565b602082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f496e76616c6964206e6f64652074797065000000000000000000000000000000600082015250565b60006128ec60118361257c565b91506128f7826128b6565b602082019050919050565b6000602082019050818103600083015261291b816128df565b9050919050565b600061292d82611f44565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361295f5761295e612789565b5b600182019050919050565b7f536d74206973206e6f7420696e697469616c697a656400000000000000000000600082015250565b60006129a060168361257c565b91506129ab8261296a565b602082019050919050565b600060208201905081810360008301526129cf81612993565b9050919050565b7f536d7420697320616c726561647920696e697469616c697a6564000000000000600082015250565b6000612a0c601a8361257c565b9150612a17826129d6565b602082019050919050565b60006020820190508181036000830152612a3b816129ff565b9050919050565b7f4e6f2066757475726520626c6f636b7320616c6c6f7765640000000000000000600082015250565b6000612a7860188361257c565b9150612a8382612a42565b602082019050919050565b60006020820190508181036000830152612aa781612a6b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000612b13601f8361257c565b9150612b1e82612add565b602082019050919050565b60006020820190508181036000830152612b4281612b06565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b6000612b7f60158361257c565b9150612b8a82612b49565b602082019050919050565b60006020820190508181036000830152612bae81612b72565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b6000612beb60198361257c565b9150612bf682612bb5565b602082019050919050565b60006020820190508181036000830152612c1a81612bde565b9050919050565b6000612c2c82611f44565b9150612c3783611f44565b9250828201905080821115612c4f57612c4e612789565b5b92915050565b7f4d61782064657074682072656163686564000000000000000000000000000000600082015250565b6000612c8b60118361257c565b9150612c9682612c55565b602082019050919050565b60006020820190508181036000830152612cba81612c7e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612cfb82611f44565b9150612d0683611f44565b925082612d1657612d15612cc1565b5b828204905092915050565b7f496e76616c696420736561726368207479706500000000000000000000000000600082015250565b6000612d5760138361257c565b9150612d6282612d21565b602082019050919050565b60006020820190508181036000830152612d8681612d4a565b9050919050565b600060039050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612dc381612d8d565b612dcd8184612d98565b9250612dd882612da3565b8060005b83811015612e09578151612df0878261208d565b9650612dfb83612dad565b925050600181019050612ddc565b505050505050565b6000606082019050612e266000830184612dba565b92915050565b600081519050612e3b81611f4e565b92915050565b600060208284031215612e5757612e56611f09565b5b6000612e6584828501612e2c565b91505092915050565b600060029050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612ea481612e6e565b612eae8184612e79565b9250612eb982612e84565b8060005b83811015612eea578151612ed1878261208d565b9650612edc83612e8e565b925050600181019050612ebd565b505050505050565b6000604082019050612f076000830184612e9b565b9291505056fea26469706673582212205abbe031e31994d755b34f8c95303d957ba6b4e7ac64a9fa5d1846ab9c21a73b64736f6c634300081b0033
Deployed Bytecode
0x73682364078e26c1626abd2b95109d2019e241f0f630146080604052600436106101405760003560e01c806379f97125116100c2578063a751be2411610086578063a751be24146103f5578063c1d29f0114610413578063dc9a7c8c1461043c578063dea7633a1461046c578063e170cf6e1461049c578063ec145108146104cc57610140565b806379f971251461030c578063893f99f31461033c57806391761b751461036c57806392f5b06c1461039c5780639e43b813146103cc57610140565b806340a73d981161010957806340a73d981461022e5780635db40cda1461024c57806362e8f2151461027c578063792a470f146102ac57806379c17a96146102dc57610140565b806278f030146101455780630912610a14610175578063138271361461019e57806317c850f0146101ce57806321d60953146101fe575b600080fd5b61015f600480360381019061015a9190611f7a565b6104fc565b60405161016c9190611fc9565b60405180910390f35b81801561018157600080fd5b5061019c60048036038101906101979190611f7a565b61051f565b005b6101b860048036038101906101b39190611fe4565b6105fa565b6040516101c591906121c0565b60405180910390f35b6101e860048036038101906101e39190611f7a565b610629565b6040516101f5919061225d565b60405180910390f35b61021860048036038101906102139190611fe4565b610688565b60405161022591906123a2565b60405180910390f35b610236610765565b6040516102439190611fc9565b60405180910390f35b61026660048036038101906102619190611f7a565b61076b565b60405161027391906121c0565b60405180910390f35b610296600480360381019061029191906123c4565b61078e565b6040516102a39190611fc9565b60405180910390f35b6102c660048036038101906102c19190611fe4565b61079f565b6040516102d391906121c0565b60405180910390f35b6102f660048036038101906102f19190611fe4565b6107ce565b60405161030391906121c0565b60405180910390f35b610326600480360381019061032191906123c4565b610afa565b6040516103339190611fc9565b60405180910390f35b610356600480360381019061035191906123c4565b610b88565b6040516103639190611fc9565b60405180910390f35b610386600480360381019061038191906123f1565b610b96565b60405161039391906123a2565b60405180910390f35b6103b660048036038101906103b19190611f7a565b610cf5565b6040516103c39190612467565b60405180910390f35b8180156103d857600080fd5b506103f360048036038101906103ee9190611f7a565b610d1a565b005b6103fd610d9c565b60405161040a9190611fc9565b60405180910390f35b81801561041f57600080fd5b5061043a60048036038101906104359190611fe4565b610da2565b005b61045660048036038101906104519190611f7a565b610e5e565b604051610463919061225d565b60405180910390f35b61048660048036038101906104819190611f7a565b610ebd565b604051610493919061225d565b60405180910390f35b6104b660048036038101906104b19190611f7a565b610f71565b6040516104c39190612561565b60405180910390f35b6104e660048036038101906104e191906123c4565b611004565b6040516104f39190612467565b60405180910390f35b600082600201600083815260200190815260200160002080549050905092915050565b60008111610562576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610559906125ff565b60405180910390fd5b816003015481116105a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059f9061266b565b60405180910390fd5b6101008111156105ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e4906126fd565b60405180910390fd5b8082600301819055505050565b610602611e49565b600061060e8584610629565b905061061f858583600001516107ce565b9150509392505050565b610631611e92565b42821115610674576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066b90612769565b60405180910390fd5b6106808383600061101f565b905092915050565b60606000806106a2866001018054905086866103e8611066565b91509150600082826106b491906127b8565b67ffffffffffffffff8111156106cd576106cc6127ec565b5b60405190808252806020026020018201604052801561070657816020015b6106f3611e92565b8152602001906001900390816106eb5790505b50905060008390505b8281101561075757610721888261115d565b82858361072e91906127b8565b8151811061073f5761073e61281b565b5b6020026020010181905250808060010191505061070f565b508093505050509392505050565b6103e881565b610773611e49565b610786838361078186610afa565b6107ce565b905092915050565b600081600101805490509050919050565b6107a7611e49565b60006107b38584610e5e565b90506107c4858583600001516107ce565b9150509392505050565b6107d6611e49565b83826107e28282610cf5565b610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081890612896565b60405180910390fd5b6000866003015467ffffffffffffffff811115610841576108406127ec565b5b60405190808252806020026020018201604052801561086f5781602001602082028036833780820191505090505b50905060005b87600301548110156108af5760008282815181106108965761089561281b565b5b6020026020010181815250508080600101915050610875565b5060006040518061010001604052808781526020016000151581526020018381526020018881526020016000815260200160001515815260200160008152602001600081525090506000869050610904611ec8565b60005b8a600301548111610ae95761091c8b84610f71565b91506000600281111561093257610931612482565b5b8260000151600281111561094957610948612482565b5b0315610ae9576001600281111561096357610962612482565b5b8260000151600281111561097a57610979612482565b5b036109f25783606001518260600151036109b25760018460200190151590811515815250508160800151846080018181525050610ae9565b60018460a001901515908115158152505081606001518460c001818152505081608001518460e00181815250508160800151846080018181525050610ae9565b600280811115610a0557610a04612482565b5b82600001516002811115610a1c57610a1b612482565b5b03610a9b57600180828660600151901c1603610a665781604001519250816020015184604001518281518110610a5557610a5461281b565b5b602002602001018181525050610a96565b81602001519250816040015184604001518281518110610a8957610a8861281b565b5b6020026020010181815250505b610ad6565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610acd90612902565b60405180910390fd5b8080610ae190612922565b915050610907565b508296505050505050509392505050565b600081610b0681611004565b610b45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3c906129b6565b60405180910390fd5b8260010160018460010180549050610b5d91906127b8565b81548110610b6e57610b6d61281b565b5b906000526020600020906003020160000154915050919050565b600081600301549050919050565b60608484610ba48282610cf5565b610be3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bda90612896565b60405180910390fd5b60008760020160008881526020019081526020016000209050600080610c11838054905089896103e8611066565b9150915060008282610c2391906127b8565b67ffffffffffffffff811115610c3c57610c3b6127ec565b5b604051908082528060200260200182016040528015610c7557816020015b610c62611e92565b815260200190600190039081610c5a5790505b50905060008390505b82811015610ce357610cad8c868381548110610c9d57610c9c61281b565b5b906000526020600020015461115d565b828583610cba91906127b8565b81518110610ccb57610cca61281b565b5b60200260200101819052508080600101915050610c7e565b50809650505050505050949350505050565b6000808360020160008481526020019081526020016000208054905011905092915050565b610d2382611004565b15610d63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5a90612a22565b60405180910390fd5b610d6d828261051f565b610d7b8260008060006112aa565b60018260040160006101000a81548160ff0219169083151502179055505050565b61010081565b82610dac81611004565b610deb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610de2906129b6565b60405180910390fd5b60006040518060a0016040528060016002811115610e0c57610e0b612482565b5b815260200160008152602001600081526020018581526020018481525090506000610e3686610afa565b90506000610e478784846000611367565b9050610e55878242436112aa565b50505050505050565b610e66611e92565b43821115610ea9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea090612a8e565b60405180910390fd5b610eb58383600161101f565b905092915050565b610ec5611e92565b8282610ed18282610cf5565b610f10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0790612896565b60405180910390fd5b6000856002016000868152602001908152602001600020905060008160018380549050610f3d91906127b8565b81548110610f4e57610f4d61281b565b5b90600052602060002001549050610f65878261115d565b94505050505092915050565b610f79611ec8565b8260000160008381526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff166002811115610fbe57610fbd612482565b5b6002811115610fd057610fcf612482565b5b8152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905092915050565b60008160040160009054906101000a900460ff169050919050565b611027611e92565b60008061103f85858861160b9092919063ffffffff16565b915091508061105157611050612aae565b5b61105b868361115d565b925050509392505050565b600080600084116110ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a390612b29565b60405180910390fd5b828411156110ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e690612b95565b60405180910390fd5b858510611131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112890612c01565b60405180910390fd5b6000848661113f9190612c21565b90508681111561114d578690505b8581925092505094509492505050565b611165611e92565b60006001846001018054905061117b91906127b8565b8314905060008460010184815481106111975761119661281b565b5b906000526020600020906003020190506040518060c0016040528082600001548152602001836111fa57866001016001876111d29190612c21565b815481106111e3576111e261281b565b5b9060005260206000209060030201600001546111fd565b60005b8152602001826001015481526020018361124a57866001016001876112229190612c21565b815481106112335761123261281b565b5b90600052602060002090600302016001015461124d565b60005b8152602001826002015481526020018361129a57866001016001876112729190612c21565b815481106112835761128261281b565b5b90600052602060002090600302016002015461129d565b60005b8152509250505092915050565b83600101604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000155602082015181600101556040820151816002015550508360020160008481526020019081526020016000206001856001018054905061133b91906127b8565b908060018154018082558091505060019003906000526020600020016000909190919091505550505050565b600084600301548211156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a790612ca1565b60405180910390fd5b60008560000160008581526020019081526020016000206040518060a00160405290816000820160009054906101000a900460ff1660028111156113f7576113f6612482565b5b600281111561140957611408612482565b5b81526020016001820154815260200160028201548152602001600382015481526020016004820154815250509050600080600090506000600281111561145257611451612482565b5b8360000151600281111561146957611468612482565b5b0361147f5761147888886117f8565b90506115fd565b6001600281111561149357611492612482565b5b836000015160028111156114aa576114a9612482565b5b036114e15786606001518360600151146114cf576114ca888885886119e9565b6114da565b6114d988886117f8565b5b90506115fc565b6002808111156114f4576114f3612482565b5b8360000151600281111561150b5761150a612482565b5b036115fb57611518611ec8565b600180878a60600151901c160361158d576115458989866040015160018a6115409190612c21565b611367565b92506040518060a0016040528060028081111561156557611564612482565b5b81526020018560200151815260200184815260200160008152602001600081525090506115ed565b6115a98989866020015160018a6115a49190612c21565b611367565b92506040518060a001604052806002808111156115c9576115c8612482565b5b81526020018481526020018560400151815260200160008152602001600081525090505b6115f789826117f8565b9150505b5b5b809350505050949350505050565b600080600085600101805490500361162957600080915091506117f0565b6000806001876001018054905061164091906127b8565b905060005b8183116117e5576002838361165a9190612c21565b6116649190612cf0565b905060006116be8960010183815481106116815761168061281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505088611be8565b905087810361178a575b600189600101805490506116dc91906127b8565b82101561177a5760006117478a6001016001856116f99190612c21565b8154811061170a5761170961281b565b5b9060005260206000209060030201604051806060016040529081600082015481526020016001820154815260200160028201548152505089611be8565b905088810361176357828061175b90612922565b935050611774565b8260019650965050505050506117f0565b506116c8565b81600195509550505050506117f0565b808811156117a65760018261179f9190612c21565b93506117df565b80881080156117b55750600082115b156117ce576001826117c791906127b8565b92506117de565b60008095509550505050506117f0565b5b50611645565b816001945094505050505b935093915050565b60008061180483611c9a565b90506000600281111561181a57611819612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff16600281111561185257611851612482565b5b1461196d578260000151600281111561186e5761186d612482565b5b84600001600083815260200190815260200160002060000160009054906101000a900460ff1660028111156118a6576118a5612482565b5b146118b4576118b3612aae565b5b826020015184600001600083815260200190815260200160002060010154146118e0576118df612aae565b5b8260400151846000016000838152602001908152602001600020600201541461190c5761190b612aae565b5b8260600151846000016000838152602001908152602001600020600301541461193857611937612aae565b5b8260800151846000016000838152602001908152602001600020600401541461196457611963612aae565b5b809150506119e3565b8284600001600083815260200190815260200160002060008201518160000160006101000a81548160ff021916908360028111156119ae576119ad612482565b5b021790555060208201518160010155604082015181600201556060820151816003015560808201518160040155905050809150505b92915050565b600084600301548210611a31576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2890612ca1565b60405180910390fd5b611a39611ec8565b6000600180858860600151901c161490506000600180868860600151901c1614905080151582151503611b1f576000611a8089898960018a611a7b9190612c21565b6119e9565b90508215611acb576040518060a00160405280600280811115611aa657611aa5612482565b5b8152602001600081526020018281526020016000815260200160008152509350611b0a565b6040518060a00160405280600280811115611ae957611ae8612482565b5b81526020018281526020016000815260200160008152602001600081525093505b611b1489856117f8565b945050505050611be0565b8115611b77576040518060a00160405280600280811115611b4357611b42612482565b5b8152602001611b5188611c9a565b8152602001611b5f89611c9a565b81526020016000815260200160008152509250611bc5565b6040518060a00160405280600280811115611b9557611b94612482565b5b8152602001611ba389611c9a565b8152602001611bb188611c9a565b815260200160008152602001600081525092505b611bcf88886117f8565b50611bda88846117f8565b93505050505b949350505050565b6000600180811115611bfd57611bfc612482565b5b826001811115611c1057611c0f612482565b5b03611c215782604001519050611c94565b60006001811115611c3557611c34612482565b5b826001811115611c4857611c47612482565b5b03611c595782602001519050611c94565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8b90612d6d565b60405180910390fd5b92915050565b6000806000905060016002811115611cb557611cb4612482565b5b83600001516002811115611ccc57611ccb612482565b5b03611d795760006040518060600160405280856060015181526020018560800151815260200160018152509050735bc89782d5ebf62663df7ce5fb4bc7408926a2406325cc70e8826040518263ffffffff1660e01b8152600401611d309190612e11565b602060405180830381865af4158015611d4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d719190612e41565b915050611e40565b600280811115611d8c57611d8b612482565b5b83600001516002811115611da357611da2612482565b5b03611e3f577372f721d9d5f91353b505207c63b56cf3d9447edb6329a5f2f660405180604001604052808660200151815260200186604001518152506040518263ffffffff1660e01b8152600401611dfb9190612ef2565b602060405180830381865af4158015611e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3c9190612e41565b90505b5b80915050919050565b6040518061010001604052806000815260200160001515815260200160608152602001600081526020016000815260200160001515815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060006002811115611ee757611ee6612482565b5b8152602001600081526020016000815260200160008152602001600081525090565b600080fd5b6000819050919050565b611f2181611f0e565b8114611f2c57600080fd5b50565b600081359050611f3e81611f18565b92915050565b6000819050919050565b611f5781611f44565b8114611f6257600080fd5b50565b600081359050611f7481611f4e565b92915050565b60008060408385031215611f9157611f90611f09565b5b6000611f9f85828601611f2f565b9250506020611fb085828601611f65565b9150509250929050565b611fc381611f44565b82525050565b6000602082019050611fde6000830184611fba565b92915050565b600080600060608486031215611ffd57611ffc611f09565b5b600061200b86828701611f2f565b935050602061201c86828701611f65565b925050604061202d86828701611f65565b9150509250925092565b61204081611f44565b82525050565b60008115159050919050565b61205b81612046565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006120998383612037565b60208301905092915050565b6000602082019050919050565b60006120bd82612061565b6120c7818561206c565b93506120d28361207d565b8060005b838110156121035781516120ea888261208d565b97506120f5836120a5565b9250506001810190506120d6565b5085935050505092915050565b6000610100830160008301516121296000860182612037565b50602083015161213c6020860182612052565b506040830151848203604086015261215482826120b2565b91505060608301516121696060860182612037565b50608083015161217c6080860182612037565b5060a083015161218f60a0860182612052565b5060c08301516121a260c0860182612037565b5060e08301516121b560e0860182612037565b508091505092915050565b600060208201905081810360008301526121da8184612110565b905092915050565b60c0820160008201516121f86000850182612037565b50602082015161220b6020850182612037565b50604082015161221e6040850182612037565b5060608201516122316060850182612037565b5060808201516122446080850182612037565b5060a082015161225760a0850182612037565b50505050565b600060c08201905061227260008301846121e2565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60c0820160008201516122ba6000850182612037565b5060208201516122cd6020850182612037565b5060408201516122e06040850182612037565b5060608201516122f36060850182612037565b5060808201516123066080850182612037565b5060a082015161231960a0850182612037565b50505050565b600061232b83836122a4565b60c08301905092915050565b6000602082019050919050565b600061234f82612278565b6123598185612283565b935061236483612294565b8060005b8381101561239557815161237c888261231f565b975061238783612337565b925050600181019050612368565b5085935050505092915050565b600060208201905081810360008301526123bc8184612344565b905092915050565b6000602082840312156123da576123d9611f09565b5b60006123e884828501611f2f565b91505092915050565b6000806000806080858703121561240b5761240a611f09565b5b600061241987828801611f2f565b945050602061242a87828801611f65565b935050604061243b87828801611f65565b925050606061244c87828801611f65565b91505092959194509250565b61246181612046565b82525050565b600060208201905061247c6000830184612458565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600381106124c2576124c1612482565b5b50565b60008190506124d3826124b1565b919050565b60006124e3826124c5565b9050919050565b6124f3816124d8565b82525050565b60a08201600082015161250f60008501826124ea565b5060208201516125226020850182612037565b5060408201516125356040850182612037565b5060608201516125486060850182612037565b50608082015161255b6080850182612037565b50505050565b600060a08201905061257660008301846124f9565b92915050565b600082825260208201905092915050565b7f4d6178206465707468206d7573742062652067726561746572207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006125e960238361257c565b91506125f48261258d565b604082019050919050565b60006020820190508181036000830152612618816125dc565b9050919050565b7f4d61782064657074682063616e206f6e6c7920626520696e6372656173656400600082015250565b6000612655601f8361257c565b91506126608261261f565b602082019050919050565b6000602082019050818103600083015261268481612648565b9050919050565b7f4d61782064657074682069732067726561746572207468616e2068617264206360008201527f6170000000000000000000000000000000000000000000000000000000000000602082015250565b60006126e760228361257c565b91506126f28261268b565b604082019050919050565b60006020820190508181036000830152612716816126da565b9050919050565b7f4e6f206675747572652074696d657374616d707320616c6c6f77656400000000600082015250565b6000612753601c8361257c565b915061275e8261271d565b602082019050919050565b6000602082019050818103600083015261278281612746565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006127c382611f44565b91506127ce83611f44565b92508282039050818111156127e6576127e5612789565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f526f6f7420646f6573206e6f7420657869737400000000000000000000000000600082015250565b600061288060138361257c565b915061288b8261284a565b602082019050919050565b600060208201905081810360008301526128af81612873565b9050919050565b7f496e76616c6964206e6f64652074797065000000000000000000000000000000600082015250565b60006128ec60118361257c565b91506128f7826128b6565b602082019050919050565b6000602082019050818103600083015261291b816128df565b9050919050565b600061292d82611f44565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361295f5761295e612789565b5b600182019050919050565b7f536d74206973206e6f7420696e697469616c697a656400000000000000000000600082015250565b60006129a060168361257c565b91506129ab8261296a565b602082019050919050565b600060208201905081810360008301526129cf81612993565b9050919050565b7f536d7420697320616c726561647920696e697469616c697a6564000000000000600082015250565b6000612a0c601a8361257c565b9150612a17826129d6565b602082019050919050565b60006020820190508181036000830152612a3b816129ff565b9050919050565b7f4e6f2066757475726520626c6f636b7320616c6c6f7765640000000000000000600082015250565b6000612a7860188361257c565b9150612a8382612a42565b602082019050919050565b60006020820190508181036000830152612aa781612a6b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000612b13601f8361257c565b9150612b1e82612add565b602082019050919050565b60006020820190508181036000830152612b4281612b06565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b6000612b7f60158361257c565b9150612b8a82612b49565b602082019050919050565b60006020820190508181036000830152612bae81612b72565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b6000612beb60198361257c565b9150612bf682612bb5565b602082019050919050565b60006020820190508181036000830152612c1a81612bde565b9050919050565b6000612c2c82611f44565b9150612c3783611f44565b9250828201905080821115612c4f57612c4e612789565b5b92915050565b7f4d61782064657074682072656163686564000000000000000000000000000000600082015250565b6000612c8b60118361257c565b9150612c9682612c55565b602082019050919050565b60006020820190508181036000830152612cba81612c7e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612cfb82611f44565b9150612d0683611f44565b925082612d1657612d15612cc1565b5b828204905092915050565b7f496e76616c696420736561726368207479706500000000000000000000000000600082015250565b6000612d5760138361257c565b9150612d6282612d21565b602082019050919050565b60006020820190508181036000830152612d8681612d4a565b9050919050565b600060039050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612dc381612d8d565b612dcd8184612d98565b9250612dd882612da3565b8060005b83811015612e09578151612df0878261208d565b9650612dfb83612dad565b925050600181019050612ddc565b505050505050565b6000606082019050612e266000830184612dba565b92915050565b600081519050612e3b81611f4e565b92915050565b600060208284031215612e5757612e56611f09565b5b6000612e6584828501612e2c565b91505092915050565b600060029050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b612ea481612e6e565b612eae8184612e79565b9250612eb982612e84565b8060005b83811015612eea578151612ed1878261208d565b9650612edc83612e8e565b925050600181019050612ebd565b505050505050565b6000604082019050612f076000830184612e9b565b9291505056fea26469706673582212205abbe031e31994d755b34f8c95303d957ba6b4e7ac64a9fa5d1846ab9c21a73b64736f6c634300081b0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.