Source Code
Overview
ETH Balance
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 24956844 | 92 days ago | 0 ETH | ||||
| 24956844 | 92 days ago | 0 ETH | ||||
| 19537146 | 240 days ago | 0 ETH | ||||
| 19537146 | 240 days ago | 0 ETH | ||||
| 19448074 | 243 days ago | 0 ETH | ||||
| 19448074 | 243 days ago | 0 ETH | ||||
| 19447635 | 243 days ago | 0 ETH | ||||
| 19447635 | 243 days ago | 0 ETH | ||||
| 19429427 | 244 days ago | 0 ETH | ||||
| 19429427 | 244 days ago | 0 ETH | ||||
| 19423738 | 244 days ago | 0 ETH | ||||
| 19423738 | 244 days ago | 0 ETH | ||||
| 19423669 | 244 days ago | 0 ETH | ||||
| 19423669 | 244 days ago | 0 ETH | ||||
| 19423458 | 244 days ago | 0 ETH | ||||
| 19423458 | 244 days ago | 0 ETH | ||||
| 19423355 | 244 days ago | 0 ETH | ||||
| 19423355 | 244 days ago | 0 ETH | ||||
| 19420876 | 244 days ago | 0 ETH | ||||
| 19420876 | 244 days ago | 0 ETH | ||||
| 19414526 | 244 days ago | 0 ETH | ||||
| 19414526 | 244 days ago | 0 ETH | ||||
| 19413623 | 244 days ago | 0 ETH | ||||
| 19413623 | 244 days ago | 0 ETH | ||||
| 19410689 | 244 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
VeraxZKPVerifier
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Attestation, AttestationPayload} from './types/Structs.sol';
import {ZKPVerifierBase} from '@iden3/contracts/verifiers/ZKPVerifierBase.sol';
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {IZKPVerifier} from '@iden3/contracts/interfaces/IZKPVerifier.sol';
interface IPortal {
function attest(AttestationPayload memory attestationPayload, bytes[] memory validationPayloads) external payable;
function attestationRegistry() external view returns (address);
}
interface AttestationRegistry {
function getAttestationIdCounter() external view returns (uint32);
event AttestationRegistered(bytes32 indexed attestationId);
function getAttestation(bytes32 attestationId) external view returns (Attestation memory);
}
contract VeraxZKPVerifier is Ownable2StepUpgradeable, ZKPVerifierBase {
event AttestOk(string message, address indexed sender);
enum AttestationSchemaType { PoU, PoL }
struct PortalInfo {
IPortal attestationPortalContract;
bytes32 schemaId;
AttestationSchemaType schemaType;
}
/// @custom:storage-location erc7201:polygonid.storage.VeraxZKPVerifier
struct VeraxZKPVerifierStorage {
mapping (uint64 requestId => PortalInfo portalInfo) portalInfoForReq;
}
// keccak256(abi.encode(uint256(keccak256("polygonid.storage.VeraxZKPVerifier")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant VeraxZKPVerifierStorageLocation =
0xf2a0fb5adce57cdd20ffa282dfdeffa5cf790754d88eeeedb507a130ec7f2900;
/**
* @dev Version of contract
*/
string public constant VERSION = "1.0.3";
function _getVeraxZKPVerifierStorage() private pure returns (VeraxZKPVerifierStorage storage $) {
assembly {
$.slot := VeraxZKPVerifierStorageLocation
}
}
function initialize() public initializer {
__Ownable_init(_msgSender());
}
function setPortalInfo(uint64 requestId, address portalAddress, bytes32 schemaId, AttestationSchemaType schemaType) public onlyOwner {
VeraxZKPVerifierStorage storage $ = _getVeraxZKPVerifierStorage();
$.portalInfoForReq[requestId] = PortalInfo(IPortal(portalAddress), schemaId, schemaType);
}
function _attest(uint64 requestId,
uint256[] calldata inputs,
uint256[2] calldata a,
uint256[2][2] calldata b,
uint256[2] calldata c) internal {
VeraxZKPVerifierStorage storage $ = _getVeraxZKPVerifierStorage();
PortalInfo memory portalInfo = $.portalInfoForReq[requestId];
if (portalInfo.attestationPortalContract == IPortal(address(0))) {
revert("Attestation portal not found for request");
}
bytes memory attestationPayload;
IZKPVerifier.ZKPRequest memory request = getZKPRequest(requestId);
uint64 attestationExpiration;
if (portalInfo.schemaType == AttestationSchemaType.PoL) {
attestationExpiration = 30 days * 6;
attestationPayload = abi.encode(requestId, inputs[request.validator.inputIndexOf('nullifier')]);
} else {
uint256 reputationLevel = inputs[request.validator.inputIndexOf('operatorOutput')];
if (reputationLevel >= 2) {
attestationExpiration = 30 days * 6;
} else {
attestationExpiration = 2 weeks;
}
attestationPayload = abi.encode(requestId, inputs[request.validator.inputIndexOf('nullifier')], reputationLevel);
}
AttestationPayload memory payload = AttestationPayload(
bytes32(portalInfo.schemaId),
uint64(inputs[request.validator.inputIndexOf('timestamp')]) + attestationExpiration, // expiration
abi.encode(msg.sender), // message sender
attestationPayload
);
bytes memory validationData = abi.encode(requestId, inputs, a, b, c);
bytes[] memory validationPayload = new bytes[](1);
validationPayload[0] = validationData;
portalInfo.attestationPortalContract.attest(payload, validationPayload) ;
emit AttestOk("attestation done", msg.sender);
}
/// @dev Submits a ZKP response and updates proof status
/// @param requestId The ID of the ZKP request
/// @param inputs The input data for the proof
/// @param a The first component of the proof
/// @param b The second component of the proof
/// @param c The third component of the proof
function submitZKPResponse(
uint64 requestId,
uint256[] calldata inputs,
uint256[2] calldata a,
uint256[2][2] calldata b,
uint256[2] calldata c
) public virtual override {
_attest(requestId, inputs, a, b ,c);
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;
interface ICircuitValidator {
struct KeyToInputIndex {
string key;
uint256 inputIndex;
}
function version() external view returns (string memory);
function verify(
uint256[] memory inputs,
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
bytes calldata data,
address sender
) external view returns (ICircuitValidator.KeyToInputIndex[] memory);
function getSupportedCircuitIds() external view returns (string[] memory ids);
function inputIndexOf(string memory name) external view returns (uint256);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;
import {ICircuitValidator} from "./ICircuitValidator.sol";
interface IZKPVerifier {
struct ZKPRequest {
string metadata;
ICircuitValidator validator;
bytes data;
}
struct ProofStatus {
bool isVerified;
string validatorVersion;
uint256 blockNumber;
uint256 blockTimestamp;
}
function submitZKPResponse(
uint64 requestId,
uint256[] memory inputs,
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c
) external;
function setZKPRequest(uint64 requestId, ZKPRequest calldata request) external;
function getZKPRequest(uint64 requestId) external view returns (ZKPRequest memory);
function getZKPRequestsCount() external view returns (uint256);
function requestIdExists(uint64 requestId) external view returns (bool);
function getZKPRequests(
uint256 startIndex,
uint256 length
) external view returns (ZKPRequest[] memory);
function isProofVerified(address sender, uint64 requestId) external view returns (bool);
function getProofStatus(
address sender,
uint64 requestId
) external view returns (ProofStatus memory);
function getProofStorageField(
address user,
uint64 requestId,
string memory key
) external view returns (uint256);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;
/// @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.20;
import {IZKPVerifier} from "../interfaces/IZKPVerifier.sol";
import {ICircuitValidator} from "../interfaces/ICircuitValidator.sol";
import {ArrayUtils} from "../lib/ArrayUtils.sol";
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
abstract contract ZKPVerifierBase is IZKPVerifier, ContextUpgradeable {
/// @dev Struct to store ZKP proof and associated data
struct Proof {
bool isVerified;
mapping(string key => uint256 inputIndex) storageFields;
string validatorVersion;
uint256 blockNumber;
uint256 blockTimestamp;
}
/// @custom:storage-location erc7201:iden3.storage.ZKPVerifier
struct ZKPVerifierStorage {
mapping(address user => mapping(uint64 requestID => Proof)) _proofs;
mapping(uint64 requestID => IZKPVerifier.ZKPRequest) _requests;
uint64[] _requestIds;
}
// keccak256(abi.encode(uint256(keccak256("iden3.storage.ZKPVerifier")) - 1)) & ~bytes32(uint256(0xff));
bytes32 internal constant ZKPVerifierStorageLocation =
0x512d18c55869273fec77e70d8a8586e3fb133e90f1db24c6bcf4ff3506ef6a00;
/// @dev Get the main storage using assembly to ensure specific storage location
function _getZKPVerifierStorage() private pure returns (ZKPVerifierStorage storage $) {
assembly {
$.slot := ZKPVerifierStorageLocation
}
}
/**
* @dev Max return array length for request queries
*/
uint256 public constant REQUESTS_RETURN_LIMIT = 1000;
/// @dev Key to retrieve the linkID from the proof storage
string constant LINKED_PROOF_KEY = "linkID";
/// @dev Linked proof custom error
error LinkedProofError(
string message,
uint64 requestId,
uint256 linkID,
uint64 requestIdToCompare,
uint256 linkIdToCompare
);
/// @dev Modifier to check if the validator is set for the request
modifier checkRequestExistence(uint64 requestId, bool existence) {
if (existence) {
require(requestIdExists(requestId), "request id doesn't exist");
} else {
require(!requestIdExists(requestId), "request id already exists");
}
_;
}
/// @dev Sets a ZKP request
/// @param requestId The ID of the ZKP request
/// @param request The ZKP request data
function setZKPRequest(
uint64 requestId,
IZKPVerifier.ZKPRequest calldata request
) public virtual checkRequestExistence(requestId, false) {
ZKPVerifierStorage storage s = _getZKPVerifierStorage();
s._requests[requestId] = request;
s._requestIds.push(requestId);
}
/// @notice Submits a ZKP response and updates proof status
/// @param requestId The ID of the ZKP request
/// @param inputs The input data for the proof
/// @param a The first component of the proof
/// @param b The second component of the proof
/// @param c The third component of the proof
function submitZKPResponse(
uint64 requestId,
uint256[] calldata inputs,
uint256[2] calldata a,
uint256[2][2] calldata b,
uint256[2] calldata c
) public virtual checkRequestExistence(requestId, true) {
address sender = _msgSender();
ICircuitValidator.KeyToInputIndex[] memory pairs = _verifyZKPResponse(
requestId,
inputs,
a,
b,
c,
sender
);
Proof storage proof = _getZKPVerifierStorage()._proofs[sender][requestId];
for (uint256 i = 0; i < pairs.length; i++) {
proof.storageFields[pairs[i].key] = inputs[pairs[i].inputIndex];
}
proof.isVerified = true;
proof.validatorVersion = _getZKPVerifierStorage()._requests[requestId].validator.version();
proof.blockNumber = block.number;
proof.blockTimestamp = block.timestamp;
}
/// @dev Verifies a ZKP response without updating any proof status
/// @param requestId The ID of the ZKP request
/// @param inputs The public inputs for the proof
/// @param a The first component of the proof
/// @param b The second component of the proof
/// @param c The third component of the proof
/// @param sender The sender on behalf of which the proof is done
function verifyZKPResponse(
uint64 requestId,
uint256[] calldata inputs,
uint256[2] calldata a,
uint256[2][2] calldata b,
uint256[2] calldata c,
address sender
)
public
view
virtual
checkRequestExistence(requestId, true)
returns (ICircuitValidator.KeyToInputIndex[] memory)
{
return _verifyZKPResponse(requestId, inputs, a, b, c, sender);
}
/// @dev Gets the list of request IDs and verifies the proofs are linked
/// @param sender the user's address
/// @param requestIds the list of request IDs
/// Throws if the proofs are not linked
function verifyLinkedProofs(address sender, uint64[] calldata requestIds) public view virtual {
require(requestIds.length > 1, "Linked proof verification needs more than 1 request");
uint256 expectedLinkID = getProofStorageField(sender, requestIds[0], LINKED_PROOF_KEY);
if (expectedLinkID == 0) {
revert("Can't find linkID for given request Ids and user address");
}
for (uint256 i = 1; i < requestIds.length; i++) {
uint256 actualLinkID = getProofStorageField(sender, requestIds[i], LINKED_PROOF_KEY);
if (expectedLinkID != actualLinkID) {
revert LinkedProofError(
"Proofs are not linked",
requestIds[0],
expectedLinkID,
requestIds[i],
actualLinkID
);
}
}
}
/// @dev Gets a specific ZKP request by ID
/// @param requestId The ID of the ZKP request
/// @return zkpRequest The ZKP request data
function getZKPRequest(
uint64 requestId
)
public
view
checkRequestExistence(requestId, true)
returns (IZKPVerifier.ZKPRequest memory zkpRequest)
{
return _getZKPVerifierStorage()._requests[requestId];
}
/// @dev Gets the count of ZKP requests
/// @return The count of ZKP requests
function getZKPRequestsCount() public view returns (uint256) {
return _getZKPVerifierStorage()._requestIds.length;
}
/// @dev Checks if a ZKP request ID exists
/// @param requestId The ID of the ZKP request
/// @return Whether the request ID exists
function requestIdExists(uint64 requestId) public view override returns (bool) {
return
_getZKPVerifierStorage()._requests[requestId].validator !=
ICircuitValidator(address(0));
}
/// @dev Gets multiple ZKP requests within a range
/// @param startIndex The starting index of the range
/// @param length The length of the range
/// @return An array of ZKP requests within the specified range
function getZKPRequests(
uint256 startIndex,
uint256 length
) public view returns (IZKPVerifier.ZKPRequest[] memory) {
ZKPVerifierStorage storage s = _getZKPVerifierStorage();
(uint256 start, uint256 end) = ArrayUtils.calculateBounds(
s._requestIds.length,
startIndex,
length,
REQUESTS_RETURN_LIMIT
);
IZKPVerifier.ZKPRequest[] memory result = new IZKPVerifier.ZKPRequest[](end - start);
for (uint256 i = start; i < end; i++) {
result[i - start] = s._requests[s._requestIds[i]];
}
return result;
}
/// @dev Checks if proof submitted for a given sender and request ID
/// @param sender The sender's address
/// @param requestId The ID of the ZKP request
/// @return true if proof submitted
function isProofVerified(
address sender,
uint64 requestId
) public view checkRequestExistence(requestId, true) returns (bool) {
return _getZKPVerifierStorage()._proofs[sender][requestId].isVerified;
}
/// @dev Checks the proof status for a given user and request ID
/// @param sender The sender's address
/// @param requestId The ID of the ZKP request
/// @return The proof status structure
function getProofStatus(
address sender,
uint64 requestId
) public view checkRequestExistence(requestId, true) returns (IZKPVerifier.ProofStatus memory) {
Proof storage proof = _getZKPVerifierStorage()._proofs[sender][requestId];
return
IZKPVerifier.ProofStatus(
proof.isVerified,
proof.validatorVersion,
proof.blockNumber,
proof.blockTimestamp
);
}
/// @dev Gets the proof storage item for a given user, request ID and key
/// @param user The user's address
/// @param requestId The ID of the ZKP request
/// @return The proof
function getProofStorageField(
address user,
uint64 requestId,
string memory key
) public view checkRequestExistence(requestId, true) returns (uint256) {
return _getZKPVerifierStorage()._proofs[user][requestId].storageFields[key];
}
function _verifyZKPResponse(
uint64 requestId,
uint256[] calldata inputs,
uint256[2] calldata a,
uint256[2][2] calldata b,
uint256[2] calldata c,
address sender
) private view returns (ICircuitValidator.KeyToInputIndex[] memory) {
IZKPVerifier.ZKPRequest memory request = _getZKPVerifierStorage()._requests[requestId];
ICircuitValidator.KeyToInputIndex[] memory pairs = request.validator.verify(
inputs,
a,
b,
c,
request.data,
sender
);
return pairs;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step
struct Ownable2StepStorage {
address _pendingOwner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;
function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {
assembly {
$.slot := Ownable2StepStorageLocation
}
}
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
return $._pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
$._pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
delete $._pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../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.
*
* The initial owner is set to the address provided by the deployer. 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 {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @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]
* ```solidity
* 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 Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 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.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._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.
*
* 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.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* 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.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._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() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @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.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// copied from https://github.com/Consensys/linea-attestation-registry/blob/dev/contracts/src/types/Structs.sol
pragma solidity 0.8.20;
struct AttestationPayload {
bytes32 schemaId; // The identifier of the schema this attestation adheres to.
uint64 expirationDate; // The expiration date of the attestation.
bytes subject; // The ID of the attestee, EVM address, DID, URL etc.
bytes attestationData; // The attestation data.
}
struct Attestation {
bytes32 attestationId; // The unique identifier of the attestation.
bytes32 schemaId; // The identifier of the schema this attestation adheres to.
bytes32 replacedBy; // Whether the attestation was replaced by a new one.
address attester; // The address issuing the attestation to the subject.
address portal; // The id of the portal that created the attestation.
uint64 attestedDate; // The date the attestation is issued.
uint64 expirationDate; // The expiration date of the attestation.
uint64 revocationDate; // The date when the attestation was revoked.
uint16 version; // Version of the registry when the attestation was created.
bool revoked; // Whether the attestation is revoked or not.
bytes subject; // The ID of the attestee, EVM address, DID, URL etc.
bytes attestationData; // The attestation data.
}
struct Schema {
string name; // The name of the schema.
string description; // A description of the schema.
string context; // The context of the schema.
string schema; // The schema definition.
}
struct Portal {
address id; // The unique identifier of the portal.
address ownerAddress; // The address of the owner of this portal.
address[] modules; // Addresses of modules implemented by the portal.
bool isRevocable; // Whether attestations issued can be revoked.
string name; // The name of the portal.
string description; // A description of the portal.
string ownerName; // The name of the owner of this portal.
}
struct Module {
address moduleAddress; // The address of the module.
string name; // The name of the module.
string description; // A description of the module.
}{
"evmVersion": "paris",
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"},{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"uint256","name":"linkID","type":"uint256"},{"internalType":"uint64","name":"requestIdToCompare","type":"uint64"},{"internalType":"uint256","name":"linkIdToCompare","type":"uint256"}],"name":"LinkedProofError","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AttestOk","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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"},{"inputs":[],"name":"REQUESTS_RETURN_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint64","name":"requestId","type":"uint64"}],"name":"getProofStatus","outputs":[{"components":[{"internalType":"bool","name":"isVerified","type":"bool"},{"internalType":"string","name":"validatorVersion","type":"string"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"internalType":"struct IZKPVerifier.ProofStatus","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"string","name":"key","type":"string"}],"name":"getProofStorageField","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"}],"name":"getZKPRequest","outputs":[{"components":[{"internalType":"string","name":"metadata","type":"string"},{"internalType":"contract ICircuitValidator","name":"validator","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IZKPVerifier.ZKPRequest","name":"zkpRequest","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"getZKPRequests","outputs":[{"components":[{"internalType":"string","name":"metadata","type":"string"},{"internalType":"contract ICircuitValidator","name":"validator","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IZKPVerifier.ZKPRequest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getZKPRequestsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint64","name":"requestId","type":"uint64"}],"name":"isProofVerified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"}],"name":"requestIdExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"address","name":"portalAddress","type":"address"},{"internalType":"bytes32","name":"schemaId","type":"bytes32"},{"internalType":"enum VeraxZKPVerifier.AttestationSchemaType","name":"schemaType","type":"uint8"}],"name":"setPortalInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"components":[{"internalType":"string","name":"metadata","type":"string"},{"internalType":"contract ICircuitValidator","name":"validator","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IZKPVerifier.ZKPRequest","name":"request","type":"tuple"}],"name":"setZKPRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"uint256[]","name":"inputs","type":"uint256[]"},{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"}],"name":"submitZKPResponse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint64[]","name":"requestIds","type":"uint64[]"}],"name":"verifyLinkedProofs","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"requestId","type":"uint64"},{"internalType":"uint256[]","name":"inputs","type":"uint256[]"},{"internalType":"uint256[2]","name":"a","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"b","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"c","type":"uint256[2]"},{"internalType":"address","name":"sender","type":"address"}],"name":"verifyZKPResponse","outputs":[{"components":[{"internalType":"string","name":"key","type":"string"},{"internalType":"uint256","name":"inputIndex","type":"uint256"}],"internalType":"struct ICircuitValidator.KeyToInputIndex[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50614696806100206000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c80638da5cb5b116100ad578063d485805111610071578063d48580511461031d578063da8c27901461034d578063e30c397814610369578063f2fde38b14610387578063ffa1ad74146103a35761012c565b80638da5cb5b146102675780639f5223e014610285578063ab7bcfb7146102a1578063b68967e2146102d1578063c76d0845146102ed5761012c565b80636508e1b4116100f45780636508e1b4146101fb578063715018a61461021957806379ba5097146102235780638129fc1c1461022d5780638c1da2c9146102375761012c565b80630106a959146101315780631905e7b11461014d57806349555fb11461016b5780635176983b1461019b5780635f9e60d7146101cb575b600080fd5b61014b600480360381019061014691906124f5565b6103c1565b005b6101556105e7565b604051610162919061256e565b60405180910390f35b610185600480360381019061018091906125c9565b6105ed565b6040516101929190612624565b60405180910390f35b6101b560048036038101906101b091906126d9565b610717565b6040516101c29190612929565b60405180910390f35b6101e560048036038101906101e09190612977565b6107d7565b6040516101f29190612b84565b60405180910390f35b610203610aa9565b604051610210919061256e565b60405180910390f35b610221610abf565b005b61022b610ad3565b005b610235610b62565b005b610251600480360381019061024c91906125c9565b610cf7565b60405161025e9190612c18565b60405180910390f35b61026f610ee3565b60405161027c9190612c49565b60405180910390f35b61029f600480360381019061029a9190612c88565b610f1b565b005b6102bb60048036038101906102b69190612ce4565b61105f565b6040516102c89190612624565b60405180910390f35b6102eb60048036038101906102e69190612d11565b6110eb565b005b61030760048036038101906103029190612ce4565b611101565b6040516103149190612e04565b60405180910390f35b61033760048036038101906103329190612f56565b611367565b604051610344919061256e565b60405180910390f35b61036760048036038101906103629190613020565b6114a1565b005b6103716115ac565b60405161037e9190612c49565b60405180910390f35b6103a1600480360381019061039c9190613087565b6115e4565b005b6103ab6116a0565b6040516103b891906130fe565b60405180910390f35b60018282905011610407576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fe90613192565b60405180910390fd5b60006104718484846000818110610421576104206131b2565b5b90506020020160208101906104369190612ce4565b6040518060400160405280600681526020017f6c696e6b49440000000000000000000000000000000000000000000000000000815250611367565b9050600081036104b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ad90613253565b60405180910390fd5b6000600190505b838390508110156105e0576000610531868686858181106104e1576104e06131b2565b5b90506020020160208101906104f69190612ce4565b6040518060400160405280600681526020017f6c696e6b49440000000000000000000000000000000000000000000000000000815250611367565b90508083146105cc578484600081811061054e5761054d6131b2565b5b90506020020160208101906105639190612ce4565b83868685818110610577576105766131b2565b5b905060200201602081019061058c9190612ce4565b836040517f0cb82c030000000000000000000000000000000000000000000000000000000081526004016105c394939291906132ce565b60405180910390fd5b5080806105d890613355565b9150506104bd565b5050505050565b6103e881565b60008160018015610645576106018261105f565b610640576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610637906133e9565b60405180910390fd5b61068f565b61064e8261105f565b1561068e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068590613455565b60405180910390fd5b5b6106976116d9565b60000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008567ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169250505092915050565b6060876001801561076f5761072b8261105f565b61076a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610761906133e9565b60405180910390fd5b6107b9565b6107788261105f565b156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90613455565b60405180910390fd5b5b6107c88a8a8a8a8a8a8a611701565b92505050979650505050505050565b606060006107e36116d9565b90506000806107fd836002018054905087876103e8611963565b915091506000828261080f9190613475565b67ffffffffffffffff81111561082857610827612e2b565b5b60405190808252806020026020018201604052801561086157816020015b61084e6123bd565b8152602001906001900390816108465790505b50905060008390505b82811015610a9b5784600101600086600201838154811061088e5761088d6131b2565b5b90600052602060002090600491828204019190066008029054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820180546108f5906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610921906134d8565b801561096e5780601f106109435761010080835404028352916020019161096e565b820191906000526020600020905b81548152906001019060200180831161095157829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546109dd906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a09906134d8565b8015610a565780601f10610a2b57610100808354040283529160200191610a56565b820191906000526020600020905b815481529060010190602001808311610a3957829003601f168201915b505050505081525050828583610a6c9190613475565b81518110610a7d57610a7c6131b2565b5b60200260200101819052508080610a9390613355565b91505061086a565b508094505050505092915050565b6000610ab36116d9565b60020180549050905090565b610ac7611a5a565b610ad16000611ae1565b565b6000610add611b21565b90508073ffffffffffffffffffffffffffffffffffffffff16610afe6115ac565b73ffffffffffffffffffffffffffffffffffffffff1614610b5657806040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610b4d9190612c49565b60405180910390fd5b610b5f81611ae1565b50565b6000610b6c611b29565b905060008160000160089054906101000a900460ff1615905060008260000160009054906101000a900467ffffffffffffffff1690506000808267ffffffffffffffff16148015610bba5750825b9050600060018367ffffffffffffffff16148015610bef575060003073ffffffffffffffffffffffffffffffffffffffff163b145b905081158015610bfd575080155b15610c34576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018560000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508315610c845760018560000160086101000a81548160ff0219169083151502179055505b610c94610c8f611b21565b611b51565b8315610cf05760008560000160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d26001604051610ce79190613544565b60405180910390a15b5050505050565b610cff6123f4565b8160018015610d5557610d118261105f565b610d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d47906133e9565b60405180910390fd5b610d9f565b610d5e8261105f565b15610d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9590613455565b60405180910390fd5b5b6000610da96116d9565b60000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008667ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020905060405180608001604052808260000160009054906101000a900460ff1615158152602001826002018054610e43906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6f906134d8565b8015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b820191906000526020600020905b815481529060010190602001808311610e9f57829003601f168201915b50505050508152602001826003015481526020018260040154815250935050505092915050565b600080610eee611b65565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b8160008015610f7157610f2d8261105f565b610f6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f63906133e9565b60405180910390fd5b610fbb565b610f7a8261105f565b15610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb190613455565b60405180910390fd5b5b6000610fc56116d9565b9050838160010160008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000208181610ffd9190613b41565b905050806002018590806001815401808255809150506001900390600052602060002090600491828204019190066008029091909190916101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff166110806116d9565b60010160008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6110f9868686868686611b8d565b505050505050565b6111096123bd565b816001801561115f5761111b8261105f565b61115a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611151906133e9565b60405180910390fd5b6111a9565b6111688261105f565b156111a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119f90613455565b60405180910390fd5b5b6111b16116d9565b60010160008567ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820180546111f4906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611220906134d8565b801561126d5780601f106112425761010080835404028352916020019161126d565b820191906000526020600020905b81548152906001019060200180831161125057829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546112dc906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611308906134d8565b80156113555780601f1061132a57610100808354040283529160200191611355565b820191906000526020600020905b81548152906001019060200180831161133857829003601f168201915b50505050508152505092505050919050565b600082600180156113bf5761137b8261105f565b6113ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b1906133e9565b60405180910390fd5b611409565b6113c88261105f565b15611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613455565b60405180910390fd5b5b6114116116d9565b60000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008667ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600101846040516114879190613b8b565b908152602001604051809103902054925050509392505050565b6114a9611a5a565b60006114b36121b0565b905060405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018360018111156114f5576114f4613ba2565b5b8152508160000160008767ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600181111561159d5761159c613ba2565b5b02179055509050505050505050565b6000806115b76121d8565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b6115ec611a5a565b60006115f66121d8565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff1661165a610ee3565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b6040518060400160405280600581526020017f312e302e3300000000000000000000000000000000000000000000000000000081525081565b60007f512d18c55869273fec77e70d8a8586e3fb133e90f1db24c6bcf4ff3506ef6a00905090565b6060600061170d6116d9565b60010160008a67ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020604051806060016040529081600082018054611750906134d8565b80601f016020809104026020016040519081016040528092919081815260200182805461177c906134d8565b80156117c95780601f1061179e576101008083540402835291602001916117c9565b820191906000526020600020905b8154815290600101906020018083116117ac57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282018054611838906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611864906134d8565b80156118b15780601f10611886576101008083540402835291602001916118b1565b820191906000526020600020905b81548152906001019060200180831161189457829003601f168201915b50505050508152505090506000816020015173ffffffffffffffffffffffffffffffffffffffff1663f177a69e8a8a8a8a8a88604001518b6040518863ffffffff1660e01b815260040161190b9796959493929190613d65565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190613fb5565b90508092505050979650505050505050565b600080600084116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061404a565b60405180910390fd5b828411156119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e3906140b6565b60405180910390fd5b858510611a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2590614122565b60405180910390fd5b60008486611a3c9190614142565b905086811115611a4a578690505b8581925092505094509492505050565b611a62611b21565b73ffffffffffffffffffffffffffffffffffffffff16611a80610ee3565b73ffffffffffffffffffffffffffffffffffffffff1614611adf57611aa3611b21565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ad69190612c49565b60405180910390fd5b565b6000611aeb6121d8565b90508060000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055611b1d82612200565b5050565b600033905090565b60007ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b611b596122d7565b611b6281612317565b50565b60007f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300905090565b6000611b976121b0565b905060008160000160008967ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900460ff166001811115611c5457611c53613ba2565b5b6001811115611c6657611c65613ba2565b5b815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd6906141e8565b60405180910390fd5b60606000611cec8a611101565b90506000600180811115611d0357611d02613ba2565b5b84604001516001811115611d1a57611d19613ba2565b5b03611de25762ed4e0090508a8a8a846020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611d6390614254565b602060405180830381865afa158015611d80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da49190614274565b818110611db457611db36131b2565b5b90506020020135604051602001611dcc9291906142a1565b6040516020818303038152906040529250611f51565b60008a8a846020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611e2190614316565b602060405180830381865afa158015611e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e629190614274565b818110611e7257611e716131b2565b5b90506020020135905060028110611e8e5762ed4e009150611e95565b6212750091505b8b8b8b856020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611ed390614254565b602060405180830381865afa158015611ef0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f149190614274565b818110611f2457611f236131b2565b5b9050602002013582604051602001611f3e93929190614336565b6040516020818303038152906040529350505b6000604051806080016040528086602001518152602001838d8d876020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611fa6906143b9565b602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190614274565b818110611ff757611ff66131b2565b5b9050602002013561200891906143d9565b67ffffffffffffffff168152602001336040516020016120289190612c49565b604051602081830303815290604052815260200185815250905060008c8c8c8c8c8c60405160200161205f96959493929190614415565b60405160208183030381529060405290506000600167ffffffffffffffff81111561208d5761208c612e2b565b5b6040519080825280602002602001820160405280156120c057816020015b60608152602001906001900390816120ab5790505b50905081816000815181106120d8576120d76131b2565b5b6020026020010181905250866000015173ffffffffffffffffffffffffffffffffffffffff16630743219684836040518363ffffffff1660e01b81526004016121229291906145bd565b600060405180830381600087803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167fb0a83a43ed09e036921792bd721f9ed3e94e200dee4681749927d4f8525a55dc60405161219890614640565b60405180910390a25050505050505050505050505050565b60007ff2a0fb5adce57cdd20ffa282dfdeffa5cf790754d88eeeedb507a130ec7f2900905090565b60007f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00905090565b600061220a611b65565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6122df61239d565b612315576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61231f6122d7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036123915760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016123889190612c49565b60405180910390fd5b61239a81611ae1565b50565b60006123a7611b29565b60000160089054906101000a900460ff16905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b60405180608001604052806000151581526020016060815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061245d82612432565b9050919050565b61246d81612452565b811461247857600080fd5b50565b60008135905061248a81612464565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126124b5576124b4612490565b5b8235905067ffffffffffffffff8111156124d2576124d1612495565b5b6020830191508360208202830111156124ee576124ed61249a565b5b9250929050565b60008060006040848603121561250e5761250d612428565b5b600061251c8682870161247b565b935050602084013567ffffffffffffffff81111561253d5761253c61242d565b5b6125498682870161249f565b92509250509250925092565b6000819050919050565b61256881612555565b82525050565b6000602082019050612583600083018461255f565b92915050565b600067ffffffffffffffff82169050919050565b6125a681612589565b81146125b157600080fd5b50565b6000813590506125c38161259d565b92915050565b600080604083850312156125e0576125df612428565b5b60006125ee8582860161247b565b92505060206125ff858286016125b4565b9150509250929050565b60008115159050919050565b61261e81612609565b82525050565b60006020820190506126396000830184612615565b92915050565b60008083601f84011261265557612654612490565b5b8235905067ffffffffffffffff81111561267257612671612495565b5b60208301915083602082028301111561268e5761268d61249a565b5b9250929050565b6000819050826020600202820111156126b1576126b061249a565b5b92915050565b6000819050826040600202820111156126d3576126d261249a565b5b92915050565b6000806000806000806000610160888a0312156126f9576126f8612428565b5b60006127078a828b016125b4565b975050602088013567ffffffffffffffff8111156127285761272761242d565b5b6127348a828b0161263f565b965096505060406127478a828b01612695565b94505060806127588a828b016126b7565b93505061010061276a8a828b01612695565b92505061014061277c8a828b0161247b565b91505092959891949750929550565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156127f15780820151818401526020810190506127d6565b60008484015250505050565b6000601f19601f8301169050919050565b6000612819826127b7565b61282381856127c2565b93506128338185602086016127d3565b61283c816127fd565b840191505092915050565b61285081612555565b82525050565b60006040830160008301518482036000860152612873828261280e565b91505060208301516128886020860182612847565b508091505092915050565b600061289f8383612856565b905092915050565b6000602082019050919050565b60006128bf8261278b565b6128c98185612796565b9350836020820285016128db856127a7565b8060005b8581101561291757848403895281516128f88582612893565b9450612903836128a7565b925060208a019950506001810190506128df565b50829750879550505050505092915050565b6000602082019050818103600083015261294381846128b4565b905092915050565b61295481612555565b811461295f57600080fd5b50565b6000813590506129718161294b565b92915050565b6000806040838503121561298e5761298d612428565b5b600061299c85828601612962565b92505060206129ad85828601612962565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000612a08612a036129fe84612432565b6129e3565b612432565b9050919050565b6000612a1a826129ed565b9050919050565b6000612a2c82612a0f565b9050919050565b612a3c81612a21565b82525050565b600081519050919050565b600082825260208201905092915050565b6000612a6982612a42565b612a738185612a4d565b9350612a838185602086016127d3565b612a8c816127fd565b840191505092915050565b60006060830160008301518482036000860152612ab4828261280e565b9150506020830151612ac96020860182612a33565b5060408301518482036040860152612ae18282612a5e565b9150508091505092915050565b6000612afa8383612a97565b905092915050565b6000602082019050919050565b6000612b1a826129b7565b612b2481856129c2565b935083602082028501612b36856129d3565b8060005b85811015612b725784840389528151612b538582612aee565b9450612b5e83612b02565b925060208a01995050600181019050612b3a565b50829750879550505050505092915050565b60006020820190508181036000830152612b9e8184612b0f565b905092915050565b612baf81612609565b82525050565b6000608083016000830151612bcd6000860182612ba6565b5060208301518482036020860152612be5828261280e565b9150506040830151612bfa6040860182612847565b506060830151612c0d6060860182612847565b508091505092915050565b60006020820190508181036000830152612c328184612bb5565b905092915050565b612c4381612452565b82525050565b6000602082019050612c5e6000830184612c3a565b92915050565b600080fd5b600060608284031215612c7f57612c7e612c64565b5b81905092915050565b60008060408385031215612c9f57612c9e612428565b5b6000612cad858286016125b4565b925050602083013567ffffffffffffffff811115612cce57612ccd61242d565b5b612cda85828601612c69565b9150509250929050565b600060208284031215612cfa57612cf9612428565b5b6000612d08848285016125b4565b91505092915050565b6000806000806000806101408789031215612d2f57612d2e612428565b5b6000612d3d89828a016125b4565b965050602087013567ffffffffffffffff811115612d5e57612d5d61242d565b5b612d6a89828a0161263f565b95509550506040612d7d89828a01612695565b9350506080612d8e89828a016126b7565b925050610100612da089828a01612695565b9150509295509295509295565b60006060830160008301518482036000860152612dca828261280e565b9150506020830151612ddf6020860182612a33565b5060408301518482036040860152612df78282612a5e565b9150508091505092915050565b60006020820190508181036000830152612e1e8184612dad565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e63826127fd565b810181811067ffffffffffffffff82111715612e8257612e81612e2b565b5b80604052505050565b6000612e9561241e565b9050612ea18282612e5a565b919050565b600067ffffffffffffffff821115612ec157612ec0612e2b565b5b612eca826127fd565b9050602081019050919050565b82818337600083830152505050565b6000612ef9612ef484612ea6565b612e8b565b905082815260208101848484011115612f1557612f14612e26565b5b612f20848285612ed7565b509392505050565b600082601f830112612f3d57612f3c612490565b5b8135612f4d848260208601612ee6565b91505092915050565b600080600060608486031215612f6f57612f6e612428565b5b6000612f7d8682870161247b565b9350506020612f8e868287016125b4565b925050604084013567ffffffffffffffff811115612faf57612fae61242d565b5b612fbb86828701612f28565b9150509250925092565b6000819050919050565b612fd881612fc5565b8114612fe357600080fd5b50565b600081359050612ff581612fcf565b92915050565b6002811061300857600080fd5b50565b60008135905061301a81612ffb565b92915050565b6000806000806080858703121561303a57613039612428565b5b6000613048878288016125b4565b94505060206130598782880161247b565b935050604061306a87828801612fe6565b925050606061307b8782880161300b565b91505092959194509250565b60006020828403121561309d5761309c612428565b5b60006130ab8482850161247b565b91505092915050565b600082825260208201905092915050565b60006130d0826127b7565b6130da81856130b4565b93506130ea8185602086016127d3565b6130f3816127fd565b840191505092915050565b6000602082019050818103600083015261311881846130c5565b905092915050565b7f4c696e6b65642070726f6f6620766572696669636174696f6e206e656564732060008201527f6d6f7265207468616e2031207265717565737400000000000000000000000000602082015250565b600061317c6033836130b4565b915061318782613120565b604082019050919050565b600060208201905081810360008301526131ab8161316f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f43616e27742066696e64206c696e6b494420666f7220676976656e207265717560008201527f6573742049647320616e64207573657220616464726573730000000000000000602082015250565b600061323d6038836130b4565b9150613248826131e1565b604082019050919050565b6000602082019050818103600083015261326c81613230565b9050919050565b7f50726f6f667320617265206e6f74206c696e6b65640000000000000000000000600082015250565b60006132a96015836130b4565b91506132b482613273565b602082019050919050565b6132c881612589565b82525050565b600060a08201905081810360008301526132e78161329c565b90506132f660208301876132bf565b613303604083018661255f565b61331060608301856132bf565b61331d608083018461255f565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061336082612555565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361339257613391613326565b5b600182019050919050565b7f7265717565737420696420646f65736e27742065786973740000000000000000600082015250565b60006133d36018836130b4565b91506133de8261339d565b602082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b7f7265717565737420696420616c72656164792065786973747300000000000000600082015250565b600061343f6019836130b4565b915061344a82613409565b602082019050919050565b6000602082019050818103600083015261346e81613432565b9050919050565b600061348082612555565b915061348b83612555565b92508282039050818111156134a3576134a2613326565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134f057607f821691505b602082108103613503576135026134a9565b5b50919050565b6000819050919050565b600061352e61352961352484613509565b6129e3565b612589565b9050919050565b61353e81613513565b82525050565b60006020820190506135596000830184613535565b92915050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261358b5761358a61355f565b5b80840192508235915067ffffffffffffffff8211156135ad576135ac613564565b5b6020830192506001820236038313156135c9576135c8613569565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261363e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613601565b6136488683613601565b95508019841693508086168417925050509392505050565b600061367b61367661367184612555565b6129e3565b612555565b9050919050565b6000819050919050565b61369583613660565b6136a96136a182613682565b84845461360e565b825550505050565b600090565b6136be6136b1565b6136c981848461368c565b505050565b5b818110156136ed576136e26000826136b6565b6001810190506136cf565b5050565b601f82111561373257613703816135dc565b61370c846135f1565b8101602085101561371b578190505b61372f613727856135f1565b8301826136ce565b50505b505050565b600082821c905092915050565b600061375560001984600802613737565b1980831691505092915050565b600061376e8383613744565b9150826002028217905092915050565b61378883836135d1565b67ffffffffffffffff8111156137a1576137a0612e2b565b5b6137ab82546134d8565b6137b68282856136f1565b6000601f8311600181146137e557600084156137d3578287013590505b6137dd8582613762565b865550613845565b601f1984166137f3866135dc565b60005b8281101561381b578489013582556001820191506020850194506020810190506137f6565b868310156138385784890135613834601f891682613744565b8355505b6001600288020188555050505b50505050505050565b61385983838361377e565b505050565b600061386982612452565b9050919050565b6138798161385e565b811461388457600080fd5b50565b6000813561389481613870565b80915050919050565b60008160001b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff6138ca8461389d565b9350801983169250808416831791505092915050565b60006138eb826129ed565b9050919050565b60006138fd826138e0565b9050919050565b6000819050919050565b613917826138f2565b61392a61392382613904565b83546138aa565b8255505050565b6000808335600160200384360303811261394e5761394d61355f565b5b80840192508235915067ffffffffffffffff8211156139705761396f613564565b5b60208301925060018202360383131561398c5761398b613569565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b601f8211156139f5576139c68161399f565b6139cf846135f1565b810160208510156139de578190505b6139f26139ea856135f1565b8301826136ce565b50505b505050565b613a048383613994565b67ffffffffffffffff811115613a1d57613a1c612e2b565b5b613a2782546134d8565b613a328282856139b4565b6000601f831160018114613a615760008415613a4f578287013590505b613a598582613762565b865550613ac1565b601f198416613a6f8661399f565b60005b82811015613a9757848901358255600182019150602085019450602081019050613a72565b86831015613ab45784890135613ab0601f891682613744565b8355505b6001600288020188555050505b50505050505050565b613ad58383836139fa565b505050565b6000810160008301613aec818561356e565b613af781838661384e565b50505050600181016020830180613b0d81613887565b9050613b19818461390e565b5050506002810160408301613b2e8185613931565b613b39818386613aca565b505050505050565b613b4b8282613ada565b5050565b600081905092915050565b6000613b65826127b7565b613b6f8185613b4f565b9350613b7f8185602086016127d3565b80840191505092915050565b6000613b978284613b5a565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082825260208201905092915050565b600080fd5b82818337505050565b6000613bfc8385613bd1565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613c2f57613c2e613be2565b5b602083029250613c40838584613be7565b82840190509392505050565b613c5860408383613be7565b5050565b600060029050919050565b600081905092915050565b6000819050919050565b613c8860408383613be7565b5050565b6000613c988383613c7c565b60408301905092915050565b600082905092915050565b6000604082019050919050565b613cc581613c5c565b613ccf8184613c67565b9250613cda82613c72565b8060005b83811015613d1357613cf08284613ca4565b613cfa8782613c8c565b9650613d0583613caf565b925050600181019050613cde565b505050505050565b600082825260208201905092915050565b6000613d3782612a42565b613d418185613d1b565b9350613d518185602086016127d3565b613d5a816127fd565b840191505092915050565b6000610160820190508181036000830152613d8181898b613bf0565b9050613d906020830188613c4c565b613d9d6060830187613cbc565b613daa60e0830186613c4c565b818103610120830152613dbd8185613d2c565b9050613dcd610140830184612c3a565b98975050505050505050565b600067ffffffffffffffff821115613df457613df3612e2b565b5b602082029050602081019050919050565b600080fd5b600080fd5b6000613e22613e1d84612ea6565b612e8b565b905082815260208101848484011115613e3e57613e3d612e26565b5b613e498482856127d3565b509392505050565b600082601f830112613e6657613e65612490565b5b8151613e76848260208601613e0f565b91505092915050565b600081519050613e8e8161294b565b92915050565b600060408284031215613eaa57613ea9613e05565b5b613eb46040612e8b565b9050600082015167ffffffffffffffff811115613ed457613ed3613e0a565b5b613ee084828501613e51565b6000830152506020613ef484828501613e7f565b60208301525092915050565b6000613f13613f0e84613dd9565b612e8b565b90508083825260208201905060208402830185811115613f3657613f3561249a565b5b835b81811015613f7d57805167ffffffffffffffff811115613f5b57613f5a612490565b5b808601613f688982613e94565b85526020850194505050602081019050613f38565b5050509392505050565b600082601f830112613f9c57613f9b612490565b5b8151613fac848260208601613f00565b91505092915050565b600060208284031215613fcb57613fca612428565b5b600082015167ffffffffffffffff811115613fe957613fe861242d565b5b613ff584828501613f87565b91505092915050565b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000614034601f836130b4565b915061403f82613ffe565b602082019050919050565b6000602082019050818103600083015261406381614027565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b60006140a06015836130b4565b91506140ab8261406a565b602082019050919050565b600060208201905081810360008301526140cf81614093565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b600061410c6019836130b4565b9150614117826140d6565b602082019050919050565b6000602082019050818103600083015261413b816140ff565b9050919050565b600061414d82612555565b915061415883612555565b92508282019050808211156141705761416f613326565b5b92915050565b7f4174746573746174696f6e20706f7274616c206e6f7420666f756e6420666f7260008201527f2072657175657374000000000000000000000000000000000000000000000000602082015250565b60006141d26028836130b4565b91506141dd82614176565b604082019050919050565b60006020820190508181036000830152614201816141c5565b9050919050565b7f6e756c6c69666965720000000000000000000000000000000000000000000000600082015250565b600061423e6009836130b4565b915061424982614208565b602082019050919050565b6000602082019050818103600083015261426d81614231565b9050919050565b60006020828403121561428a57614289612428565b5b600061429884828501613e7f565b91505092915050565b60006040820190506142b660008301856132bf565b6142c3602083018461255f565b9392505050565b7f6f70657261746f724f7574707574000000000000000000000000000000000000600082015250565b6000614300600e836130b4565b915061430b826142ca565b602082019050919050565b6000602082019050818103600083015261432f816142f3565b9050919050565b600060608201905061434b60008301866132bf565b614358602083018561255f565b614365604083018461255f565b949350505050565b7f74696d657374616d700000000000000000000000000000000000000000000000600082015250565b60006143a36009836130b4565b91506143ae8261436d565b602082019050919050565b600060208201905081810360008301526143d281614396565b9050919050565b60006143e482612589565b91506143ef83612589565b9250828201905067ffffffffffffffff81111561440f5761440e613326565b5b92915050565b60006101408201905061442b60008301896132bf565b818103602083015261443e818789613bf0565b905061444d6040830186613c4c565b61445a6080830185613cbc565b614468610100830184613c4c565b979650505050505050565b61447c81612fc5565b82525050565b61448b81612589565b82525050565b60006080830160008301516144a96000860182614473565b5060208301516144bc6020860182614482565b50604083015184820360408601526144d48282612a5e565b915050606083015184820360608601526144ee8282612a5e565b9150508091505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006145338383612a5e565b905092915050565b6000602082019050919050565b6000614553826144fb565b61455d8185614506565b93508360208202850161456f85614517565b8060005b858110156145ab578484038952815161458c8582614527565b94506145978361453b565b925060208a01995050600181019050614573565b50829750879550505050505092915050565b600060408201905081810360008301526145d78185614491565b905081810360208301526145eb8184614548565b90509392505050565b7f6174746573746174696f6e20646f6e6500000000000000000000000000000000600082015250565b600061462a6010836130b4565b9150614635826145f4565b602082019050919050565b600060208201905081810360008301526146598161461d565b905091905056fea264697066735822122096a04b34043e44e94aa7d8293dbc90fdaed77a2b5266e003f641d9f3850c6c0364736f6c63430008140033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012c5760003560e01c80638da5cb5b116100ad578063d485805111610071578063d48580511461031d578063da8c27901461034d578063e30c397814610369578063f2fde38b14610387578063ffa1ad74146103a35761012c565b80638da5cb5b146102675780639f5223e014610285578063ab7bcfb7146102a1578063b68967e2146102d1578063c76d0845146102ed5761012c565b80636508e1b4116100f45780636508e1b4146101fb578063715018a61461021957806379ba5097146102235780638129fc1c1461022d5780638c1da2c9146102375761012c565b80630106a959146101315780631905e7b11461014d57806349555fb11461016b5780635176983b1461019b5780635f9e60d7146101cb575b600080fd5b61014b600480360381019061014691906124f5565b6103c1565b005b6101556105e7565b604051610162919061256e565b60405180910390f35b610185600480360381019061018091906125c9565b6105ed565b6040516101929190612624565b60405180910390f35b6101b560048036038101906101b091906126d9565b610717565b6040516101c29190612929565b60405180910390f35b6101e560048036038101906101e09190612977565b6107d7565b6040516101f29190612b84565b60405180910390f35b610203610aa9565b604051610210919061256e565b60405180910390f35b610221610abf565b005b61022b610ad3565b005b610235610b62565b005b610251600480360381019061024c91906125c9565b610cf7565b60405161025e9190612c18565b60405180910390f35b61026f610ee3565b60405161027c9190612c49565b60405180910390f35b61029f600480360381019061029a9190612c88565b610f1b565b005b6102bb60048036038101906102b69190612ce4565b61105f565b6040516102c89190612624565b60405180910390f35b6102eb60048036038101906102e69190612d11565b6110eb565b005b61030760048036038101906103029190612ce4565b611101565b6040516103149190612e04565b60405180910390f35b61033760048036038101906103329190612f56565b611367565b604051610344919061256e565b60405180910390f35b61036760048036038101906103629190613020565b6114a1565b005b6103716115ac565b60405161037e9190612c49565b60405180910390f35b6103a1600480360381019061039c9190613087565b6115e4565b005b6103ab6116a0565b6040516103b891906130fe565b60405180910390f35b60018282905011610407576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fe90613192565b60405180910390fd5b60006104718484846000818110610421576104206131b2565b5b90506020020160208101906104369190612ce4565b6040518060400160405280600681526020017f6c696e6b49440000000000000000000000000000000000000000000000000000815250611367565b9050600081036104b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ad90613253565b60405180910390fd5b6000600190505b838390508110156105e0576000610531868686858181106104e1576104e06131b2565b5b90506020020160208101906104f69190612ce4565b6040518060400160405280600681526020017f6c696e6b49440000000000000000000000000000000000000000000000000000815250611367565b90508083146105cc578484600081811061054e5761054d6131b2565b5b90506020020160208101906105639190612ce4565b83868685818110610577576105766131b2565b5b905060200201602081019061058c9190612ce4565b836040517f0cb82c030000000000000000000000000000000000000000000000000000000081526004016105c394939291906132ce565b60405180910390fd5b5080806105d890613355565b9150506104bd565b5050505050565b6103e881565b60008160018015610645576106018261105f565b610640576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610637906133e9565b60405180910390fd5b61068f565b61064e8261105f565b1561068e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161068590613455565b60405180910390fd5b5b6106976116d9565b60000160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008567ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169250505092915050565b6060876001801561076f5761072b8261105f565b61076a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610761906133e9565b60405180910390fd5b6107b9565b6107788261105f565b156107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90613455565b60405180910390fd5b5b6107c88a8a8a8a8a8a8a611701565b92505050979650505050505050565b606060006107e36116d9565b90506000806107fd836002018054905087876103e8611963565b915091506000828261080f9190613475565b67ffffffffffffffff81111561082857610827612e2b565b5b60405190808252806020026020018201604052801561086157816020015b61084e6123bd565b8152602001906001900390816108465790505b50905060008390505b82811015610a9b5784600101600086600201838154811061088e5761088d6131b2565b5b90600052602060002090600491828204019190066008029054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820180546108f5906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610921906134d8565b801561096e5780601f106109435761010080835404028352916020019161096e565b820191906000526020600020905b81548152906001019060200180831161095157829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546109dd906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610a09906134d8565b8015610a565780601f10610a2b57610100808354040283529160200191610a56565b820191906000526020600020905b815481529060010190602001808311610a3957829003601f168201915b505050505081525050828583610a6c9190613475565b81518110610a7d57610a7c6131b2565b5b60200260200101819052508080610a9390613355565b91505061086a565b508094505050505092915050565b6000610ab36116d9565b60020180549050905090565b610ac7611a5a565b610ad16000611ae1565b565b6000610add611b21565b90508073ffffffffffffffffffffffffffffffffffffffff16610afe6115ac565b73ffffffffffffffffffffffffffffffffffffffff1614610b5657806040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610b4d9190612c49565b60405180910390fd5b610b5f81611ae1565b50565b6000610b6c611b29565b905060008160000160089054906101000a900460ff1615905060008260000160009054906101000a900467ffffffffffffffff1690506000808267ffffffffffffffff16148015610bba5750825b9050600060018367ffffffffffffffff16148015610bef575060003073ffffffffffffffffffffffffffffffffffffffff163b145b905081158015610bfd575080155b15610c34576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018560000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508315610c845760018560000160086101000a81548160ff0219169083151502179055505b610c94610c8f611b21565b611b51565b8315610cf05760008560000160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d26001604051610ce79190613544565b60405180910390a15b5050505050565b610cff6123f4565b8160018015610d5557610d118261105f565b610d50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d47906133e9565b60405180910390fd5b610d9f565b610d5e8261105f565b15610d9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9590613455565b60405180910390fd5b5b6000610da96116d9565b60000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008667ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020905060405180608001604052808260000160009054906101000a900460ff1615158152602001826002018054610e43906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6f906134d8565b8015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b820191906000526020600020905b815481529060010190602001808311610e9f57829003601f168201915b50505050508152602001826003015481526020018260040154815250935050505092915050565b600080610eee611b65565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b8160008015610f7157610f2d8261105f565b610f6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f63906133e9565b60405180910390fd5b610fbb565b610f7a8261105f565b15610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb190613455565b60405180910390fd5b5b6000610fc56116d9565b9050838160010160008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000208181610ffd9190613b41565b905050806002018590806001815401808255809150506001900390600052602060002090600491828204019190066008029091909190916101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050505050565b60008073ffffffffffffffffffffffffffffffffffffffff166110806116d9565b60010160008467ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6110f9868686868686611b8d565b505050505050565b6111096123bd565b816001801561115f5761111b8261105f565b61115a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611151906133e9565b60405180910390fd5b6111a9565b6111688261105f565b156111a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119f90613455565b60405180910390fd5b5b6111b16116d9565b60010160008567ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820180546111f4906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611220906134d8565b801561126d5780601f106112425761010080835404028352916020019161126d565b820191906000526020600020905b81548152906001019060200180831161125057829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820180546112dc906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611308906134d8565b80156113555780601f1061132a57610100808354040283529160200191611355565b820191906000526020600020905b81548152906001019060200180831161133857829003601f168201915b50505050508152505092505050919050565b600082600180156113bf5761137b8261105f565b6113ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b1906133e9565b60405180910390fd5b611409565b6113c88261105f565b15611408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ff90613455565b60405180910390fd5b5b6114116116d9565b60000160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008667ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600101846040516114879190613b8b565b908152602001604051809103902054925050509392505050565b6114a9611a5a565b60006114b36121b0565b905060405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018360018111156114f5576114f4613ba2565b5b8152508160000160008767ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548160ff0219169083600181111561159d5761159c613ba2565b5b02179055509050505050505050565b6000806115b76121d8565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b6115ec611a5a565b60006115f66121d8565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff1661165a610ee3565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b6040518060400160405280600581526020017f312e302e3300000000000000000000000000000000000000000000000000000081525081565b60007f512d18c55869273fec77e70d8a8586e3fb133e90f1db24c6bcf4ff3506ef6a00905090565b6060600061170d6116d9565b60010160008a67ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020604051806060016040529081600082018054611750906134d8565b80601f016020809104026020016040519081016040528092919081815260200182805461177c906134d8565b80156117c95780601f1061179e576101008083540402835291602001916117c9565b820191906000526020600020905b8154815290600101906020018083116117ac57829003601f168201915b505050505081526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282018054611838906134d8565b80601f0160208091040260200160405190810160405280929190818152602001828054611864906134d8565b80156118b15780601f10611886576101008083540402835291602001916118b1565b820191906000526020600020905b81548152906001019060200180831161189457829003601f168201915b50505050508152505090506000816020015173ffffffffffffffffffffffffffffffffffffffff1663f177a69e8a8a8a8a8a88604001518b6040518863ffffffff1660e01b815260040161190b9796959493929190613d65565b600060405180830381865afa158015611928573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906119519190613fb5565b90508092505050979650505050505050565b600080600084116119a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119a09061404a565b60405180910390fd5b828411156119ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119e3906140b6565b60405180910390fd5b858510611a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2590614122565b60405180910390fd5b60008486611a3c9190614142565b905086811115611a4a578690505b8581925092505094509492505050565b611a62611b21565b73ffffffffffffffffffffffffffffffffffffffff16611a80610ee3565b73ffffffffffffffffffffffffffffffffffffffff1614611adf57611aa3611b21565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611ad69190612c49565b60405180910390fd5b565b6000611aeb6121d8565b90508060000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055611b1d82612200565b5050565b600033905090565b60007ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b611b596122d7565b611b6281612317565b50565b60007f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300905090565b6000611b976121b0565b905060008160000160008967ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206040518060600160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900460ff166001811115611c5457611c53613ba2565b5b6001811115611c6657611c65613ba2565b5b815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603611cdf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cd6906141e8565b60405180910390fd5b60606000611cec8a611101565b90506000600180811115611d0357611d02613ba2565b5b84604001516001811115611d1a57611d19613ba2565b5b03611de25762ed4e0090508a8a8a846020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611d6390614254565b602060405180830381865afa158015611d80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da49190614274565b818110611db457611db36131b2565b5b90506020020135604051602001611dcc9291906142a1565b6040516020818303038152906040529250611f51565b60008a8a846020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611e2190614316565b602060405180830381865afa158015611e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e629190614274565b818110611e7257611e716131b2565b5b90506020020135905060028110611e8e5762ed4e009150611e95565b6212750091505b8b8b8b856020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611ed390614254565b602060405180830381865afa158015611ef0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f149190614274565b818110611f2457611f236131b2565b5b9050602002013582604051602001611f3e93929190614336565b6040516020818303038152906040529350505b6000604051806080016040528086602001518152602001838d8d876020015173ffffffffffffffffffffffffffffffffffffffff1663b16a394f6040518163ffffffff1660e01b8152600401611fa6906143b9565b602060405180830381865afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe79190614274565b818110611ff757611ff66131b2565b5b9050602002013561200891906143d9565b67ffffffffffffffff168152602001336040516020016120289190612c49565b604051602081830303815290604052815260200185815250905060008c8c8c8c8c8c60405160200161205f96959493929190614415565b60405160208183030381529060405290506000600167ffffffffffffffff81111561208d5761208c612e2b565b5b6040519080825280602002602001820160405280156120c057816020015b60608152602001906001900390816120ab5790505b50905081816000815181106120d8576120d76131b2565b5b6020026020010181905250866000015173ffffffffffffffffffffffffffffffffffffffff16630743219684836040518363ffffffff1660e01b81526004016121229291906145bd565b600060405180830381600087803b15801561213c57600080fd5b505af1158015612150573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167fb0a83a43ed09e036921792bd721f9ed3e94e200dee4681749927d4f8525a55dc60405161219890614640565b60405180910390a25050505050505050505050505050565b60007ff2a0fb5adce57cdd20ffa282dfdeffa5cf790754d88eeeedb507a130ec7f2900905090565b60007f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00905090565b600061220a611b65565b905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050828260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505050565b6122df61239d565b612315576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b61231f6122d7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036123915760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016123889190612c49565b60405180910390fd5b61239a81611ae1565b50565b60006123a7611b29565b60000160089054906101000a900460ff16905090565b604051806060016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b60405180608001604052806000151581526020016060815260200160008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061245d82612432565b9050919050565b61246d81612452565b811461247857600080fd5b50565b60008135905061248a81612464565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126124b5576124b4612490565b5b8235905067ffffffffffffffff8111156124d2576124d1612495565b5b6020830191508360208202830111156124ee576124ed61249a565b5b9250929050565b60008060006040848603121561250e5761250d612428565b5b600061251c8682870161247b565b935050602084013567ffffffffffffffff81111561253d5761253c61242d565b5b6125498682870161249f565b92509250509250925092565b6000819050919050565b61256881612555565b82525050565b6000602082019050612583600083018461255f565b92915050565b600067ffffffffffffffff82169050919050565b6125a681612589565b81146125b157600080fd5b50565b6000813590506125c38161259d565b92915050565b600080604083850312156125e0576125df612428565b5b60006125ee8582860161247b565b92505060206125ff858286016125b4565b9150509250929050565b60008115159050919050565b61261e81612609565b82525050565b60006020820190506126396000830184612615565b92915050565b60008083601f84011261265557612654612490565b5b8235905067ffffffffffffffff81111561267257612671612495565b5b60208301915083602082028301111561268e5761268d61249a565b5b9250929050565b6000819050826020600202820111156126b1576126b061249a565b5b92915050565b6000819050826040600202820111156126d3576126d261249a565b5b92915050565b6000806000806000806000610160888a0312156126f9576126f8612428565b5b60006127078a828b016125b4565b975050602088013567ffffffffffffffff8111156127285761272761242d565b5b6127348a828b0161263f565b965096505060406127478a828b01612695565b94505060806127588a828b016126b7565b93505061010061276a8a828b01612695565b92505061014061277c8a828b0161247b565b91505092959891949750929550565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156127f15780820151818401526020810190506127d6565b60008484015250505050565b6000601f19601f8301169050919050565b6000612819826127b7565b61282381856127c2565b93506128338185602086016127d3565b61283c816127fd565b840191505092915050565b61285081612555565b82525050565b60006040830160008301518482036000860152612873828261280e565b91505060208301516128886020860182612847565b508091505092915050565b600061289f8383612856565b905092915050565b6000602082019050919050565b60006128bf8261278b565b6128c98185612796565b9350836020820285016128db856127a7565b8060005b8581101561291757848403895281516128f88582612893565b9450612903836128a7565b925060208a019950506001810190506128df565b50829750879550505050505092915050565b6000602082019050818103600083015261294381846128b4565b905092915050565b61295481612555565b811461295f57600080fd5b50565b6000813590506129718161294b565b92915050565b6000806040838503121561298e5761298d612428565b5b600061299c85828601612962565b92505060206129ad85828601612962565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000612a08612a036129fe84612432565b6129e3565b612432565b9050919050565b6000612a1a826129ed565b9050919050565b6000612a2c82612a0f565b9050919050565b612a3c81612a21565b82525050565b600081519050919050565b600082825260208201905092915050565b6000612a6982612a42565b612a738185612a4d565b9350612a838185602086016127d3565b612a8c816127fd565b840191505092915050565b60006060830160008301518482036000860152612ab4828261280e565b9150506020830151612ac96020860182612a33565b5060408301518482036040860152612ae18282612a5e565b9150508091505092915050565b6000612afa8383612a97565b905092915050565b6000602082019050919050565b6000612b1a826129b7565b612b2481856129c2565b935083602082028501612b36856129d3565b8060005b85811015612b725784840389528151612b538582612aee565b9450612b5e83612b02565b925060208a01995050600181019050612b3a565b50829750879550505050505092915050565b60006020820190508181036000830152612b9e8184612b0f565b905092915050565b612baf81612609565b82525050565b6000608083016000830151612bcd6000860182612ba6565b5060208301518482036020860152612be5828261280e565b9150506040830151612bfa6040860182612847565b506060830151612c0d6060860182612847565b508091505092915050565b60006020820190508181036000830152612c328184612bb5565b905092915050565b612c4381612452565b82525050565b6000602082019050612c5e6000830184612c3a565b92915050565b600080fd5b600060608284031215612c7f57612c7e612c64565b5b81905092915050565b60008060408385031215612c9f57612c9e612428565b5b6000612cad858286016125b4565b925050602083013567ffffffffffffffff811115612cce57612ccd61242d565b5b612cda85828601612c69565b9150509250929050565b600060208284031215612cfa57612cf9612428565b5b6000612d08848285016125b4565b91505092915050565b6000806000806000806101408789031215612d2f57612d2e612428565b5b6000612d3d89828a016125b4565b965050602087013567ffffffffffffffff811115612d5e57612d5d61242d565b5b612d6a89828a0161263f565b95509550506040612d7d89828a01612695565b9350506080612d8e89828a016126b7565b925050610100612da089828a01612695565b9150509295509295509295565b60006060830160008301518482036000860152612dca828261280e565b9150506020830151612ddf6020860182612a33565b5060408301518482036040860152612df78282612a5e565b9150508091505092915050565b60006020820190508181036000830152612e1e8184612dad565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e63826127fd565b810181811067ffffffffffffffff82111715612e8257612e81612e2b565b5b80604052505050565b6000612e9561241e565b9050612ea18282612e5a565b919050565b600067ffffffffffffffff821115612ec157612ec0612e2b565b5b612eca826127fd565b9050602081019050919050565b82818337600083830152505050565b6000612ef9612ef484612ea6565b612e8b565b905082815260208101848484011115612f1557612f14612e26565b5b612f20848285612ed7565b509392505050565b600082601f830112612f3d57612f3c612490565b5b8135612f4d848260208601612ee6565b91505092915050565b600080600060608486031215612f6f57612f6e612428565b5b6000612f7d8682870161247b565b9350506020612f8e868287016125b4565b925050604084013567ffffffffffffffff811115612faf57612fae61242d565b5b612fbb86828701612f28565b9150509250925092565b6000819050919050565b612fd881612fc5565b8114612fe357600080fd5b50565b600081359050612ff581612fcf565b92915050565b6002811061300857600080fd5b50565b60008135905061301a81612ffb565b92915050565b6000806000806080858703121561303a57613039612428565b5b6000613048878288016125b4565b94505060206130598782880161247b565b935050604061306a87828801612fe6565b925050606061307b8782880161300b565b91505092959194509250565b60006020828403121561309d5761309c612428565b5b60006130ab8482850161247b565b91505092915050565b600082825260208201905092915050565b60006130d0826127b7565b6130da81856130b4565b93506130ea8185602086016127d3565b6130f3816127fd565b840191505092915050565b6000602082019050818103600083015261311881846130c5565b905092915050565b7f4c696e6b65642070726f6f6620766572696669636174696f6e206e656564732060008201527f6d6f7265207468616e2031207265717565737400000000000000000000000000602082015250565b600061317c6033836130b4565b915061318782613120565b604082019050919050565b600060208201905081810360008301526131ab8161316f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f43616e27742066696e64206c696e6b494420666f7220676976656e207265717560008201527f6573742049647320616e64207573657220616464726573730000000000000000602082015250565b600061323d6038836130b4565b9150613248826131e1565b604082019050919050565b6000602082019050818103600083015261326c81613230565b9050919050565b7f50726f6f667320617265206e6f74206c696e6b65640000000000000000000000600082015250565b60006132a96015836130b4565b91506132b482613273565b602082019050919050565b6132c881612589565b82525050565b600060a08201905081810360008301526132e78161329c565b90506132f660208301876132bf565b613303604083018661255f565b61331060608301856132bf565b61331d608083018461255f565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061336082612555565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361339257613391613326565b5b600182019050919050565b7f7265717565737420696420646f65736e27742065786973740000000000000000600082015250565b60006133d36018836130b4565b91506133de8261339d565b602082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b7f7265717565737420696420616c72656164792065786973747300000000000000600082015250565b600061343f6019836130b4565b915061344a82613409565b602082019050919050565b6000602082019050818103600083015261346e81613432565b9050919050565b600061348082612555565b915061348b83612555565b92508282039050818111156134a3576134a2613326565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806134f057607f821691505b602082108103613503576135026134a9565b5b50919050565b6000819050919050565b600061352e61352961352484613509565b6129e3565b612589565b9050919050565b61353e81613513565b82525050565b60006020820190506135596000830184613535565b92915050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261358b5761358a61355f565b5b80840192508235915067ffffffffffffffff8211156135ad576135ac613564565b5b6020830192506001820236038313156135c9576135c8613569565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261363e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613601565b6136488683613601565b95508019841693508086168417925050509392505050565b600061367b61367661367184612555565b6129e3565b612555565b9050919050565b6000819050919050565b61369583613660565b6136a96136a182613682565b84845461360e565b825550505050565b600090565b6136be6136b1565b6136c981848461368c565b505050565b5b818110156136ed576136e26000826136b6565b6001810190506136cf565b5050565b601f82111561373257613703816135dc565b61370c846135f1565b8101602085101561371b578190505b61372f613727856135f1565b8301826136ce565b50505b505050565b600082821c905092915050565b600061375560001984600802613737565b1980831691505092915050565b600061376e8383613744565b9150826002028217905092915050565b61378883836135d1565b67ffffffffffffffff8111156137a1576137a0612e2b565b5b6137ab82546134d8565b6137b68282856136f1565b6000601f8311600181146137e557600084156137d3578287013590505b6137dd8582613762565b865550613845565b601f1984166137f3866135dc565b60005b8281101561381b578489013582556001820191506020850194506020810190506137f6565b868310156138385784890135613834601f891682613744565b8355505b6001600288020188555050505b50505050505050565b61385983838361377e565b505050565b600061386982612452565b9050919050565b6138798161385e565b811461388457600080fd5b50565b6000813561389481613870565b80915050919050565b60008160001b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff6138ca8461389d565b9350801983169250808416831791505092915050565b60006138eb826129ed565b9050919050565b60006138fd826138e0565b9050919050565b6000819050919050565b613917826138f2565b61392a61392382613904565b83546138aa565b8255505050565b6000808335600160200384360303811261394e5761394d61355f565b5b80840192508235915067ffffffffffffffff8211156139705761396f613564565b5b60208301925060018202360383131561398c5761398b613569565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b601f8211156139f5576139c68161399f565b6139cf846135f1565b810160208510156139de578190505b6139f26139ea856135f1565b8301826136ce565b50505b505050565b613a048383613994565b67ffffffffffffffff811115613a1d57613a1c612e2b565b5b613a2782546134d8565b613a328282856139b4565b6000601f831160018114613a615760008415613a4f578287013590505b613a598582613762565b865550613ac1565b601f198416613a6f8661399f565b60005b82811015613a9757848901358255600182019150602085019450602081019050613a72565b86831015613ab45784890135613ab0601f891682613744565b8355505b6001600288020188555050505b50505050505050565b613ad58383836139fa565b505050565b6000810160008301613aec818561356e565b613af781838661384e565b50505050600181016020830180613b0d81613887565b9050613b19818461390e565b5050506002810160408301613b2e8185613931565b613b39818386613aca565b505050505050565b613b4b8282613ada565b5050565b600081905092915050565b6000613b65826127b7565b613b6f8185613b4f565b9350613b7f8185602086016127d3565b80840191505092915050565b6000613b978284613b5a565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082825260208201905092915050565b600080fd5b82818337505050565b6000613bfc8385613bd1565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115613c2f57613c2e613be2565b5b602083029250613c40838584613be7565b82840190509392505050565b613c5860408383613be7565b5050565b600060029050919050565b600081905092915050565b6000819050919050565b613c8860408383613be7565b5050565b6000613c988383613c7c565b60408301905092915050565b600082905092915050565b6000604082019050919050565b613cc581613c5c565b613ccf8184613c67565b9250613cda82613c72565b8060005b83811015613d1357613cf08284613ca4565b613cfa8782613c8c565b9650613d0583613caf565b925050600181019050613cde565b505050505050565b600082825260208201905092915050565b6000613d3782612a42565b613d418185613d1b565b9350613d518185602086016127d3565b613d5a816127fd565b840191505092915050565b6000610160820190508181036000830152613d8181898b613bf0565b9050613d906020830188613c4c565b613d9d6060830187613cbc565b613daa60e0830186613c4c565b818103610120830152613dbd8185613d2c565b9050613dcd610140830184612c3a565b98975050505050505050565b600067ffffffffffffffff821115613df457613df3612e2b565b5b602082029050602081019050919050565b600080fd5b600080fd5b6000613e22613e1d84612ea6565b612e8b565b905082815260208101848484011115613e3e57613e3d612e26565b5b613e498482856127d3565b509392505050565b600082601f830112613e6657613e65612490565b5b8151613e76848260208601613e0f565b91505092915050565b600081519050613e8e8161294b565b92915050565b600060408284031215613eaa57613ea9613e05565b5b613eb46040612e8b565b9050600082015167ffffffffffffffff811115613ed457613ed3613e0a565b5b613ee084828501613e51565b6000830152506020613ef484828501613e7f565b60208301525092915050565b6000613f13613f0e84613dd9565b612e8b565b90508083825260208201905060208402830185811115613f3657613f3561249a565b5b835b81811015613f7d57805167ffffffffffffffff811115613f5b57613f5a612490565b5b808601613f688982613e94565b85526020850194505050602081019050613f38565b5050509392505050565b600082601f830112613f9c57613f9b612490565b5b8151613fac848260208601613f00565b91505092915050565b600060208284031215613fcb57613fca612428565b5b600082015167ffffffffffffffff811115613fe957613fe861242d565b5b613ff584828501613f87565b91505092915050565b7f4c656e6774682073686f756c642062652067726561746572207468616e203000600082015250565b6000614034601f836130b4565b915061403f82613ffe565b602082019050919050565b6000602082019050818103600083015261406381614027565b9050919050565b7f4c656e677468206c696d69742065786365656465640000000000000000000000600082015250565b60006140a06015836130b4565b91506140ab8261406a565b602082019050919050565b600060208201905081810360008301526140cf81614093565b9050919050565b7f537461727420696e646578206f7574206f6620626f756e647300000000000000600082015250565b600061410c6019836130b4565b9150614117826140d6565b602082019050919050565b6000602082019050818103600083015261413b816140ff565b9050919050565b600061414d82612555565b915061415883612555565b92508282019050808211156141705761416f613326565b5b92915050565b7f4174746573746174696f6e20706f7274616c206e6f7420666f756e6420666f7260008201527f2072657175657374000000000000000000000000000000000000000000000000602082015250565b60006141d26028836130b4565b91506141dd82614176565b604082019050919050565b60006020820190508181036000830152614201816141c5565b9050919050565b7f6e756c6c69666965720000000000000000000000000000000000000000000000600082015250565b600061423e6009836130b4565b915061424982614208565b602082019050919050565b6000602082019050818103600083015261426d81614231565b9050919050565b60006020828403121561428a57614289612428565b5b600061429884828501613e7f565b91505092915050565b60006040820190506142b660008301856132bf565b6142c3602083018461255f565b9392505050565b7f6f70657261746f724f7574707574000000000000000000000000000000000000600082015250565b6000614300600e836130b4565b915061430b826142ca565b602082019050919050565b6000602082019050818103600083015261432f816142f3565b9050919050565b600060608201905061434b60008301866132bf565b614358602083018561255f565b614365604083018461255f565b949350505050565b7f74696d657374616d700000000000000000000000000000000000000000000000600082015250565b60006143a36009836130b4565b91506143ae8261436d565b602082019050919050565b600060208201905081810360008301526143d281614396565b9050919050565b60006143e482612589565b91506143ef83612589565b9250828201905067ffffffffffffffff81111561440f5761440e613326565b5b92915050565b60006101408201905061442b60008301896132bf565b818103602083015261443e818789613bf0565b905061444d6040830186613c4c565b61445a6080830185613cbc565b614468610100830184613c4c565b979650505050505050565b61447c81612fc5565b82525050565b61448b81612589565b82525050565b60006080830160008301516144a96000860182614473565b5060208301516144bc6020860182614482565b50604083015184820360408601526144d48282612a5e565b915050606083015184820360608601526144ee8282612a5e565b9150508091505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006145338383612a5e565b905092915050565b6000602082019050919050565b6000614553826144fb565b61455d8185614506565b93508360208202850161456f85614517565b8060005b858110156145ab578484038952815161458c8582614527565b94506145978361453b565b925060208a01995050600181019050614573565b50829750879550505050505092915050565b600060408201905081810360008301526145d78185614491565b905081810360208301526145eb8184614548565b90509392505050565b7f6174746573746174696f6e20646f6e6500000000000000000000000000000000600082015250565b600061462a6010836130b4565b9150614635826145f4565b602082019050919050565b600060208201905081810360008301526146598161461d565b905091905056fea264697066735822122096a04b34043e44e94aa7d8293dbc90fdaed77a2b5266e003f641d9f3850c6c0364736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
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.