Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 209 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Verify Age | 18654127 | 389 days ago | IN | 0 ETH | 0.00144507 | ||||
Verify Age | 18596236 | 397 days ago | IN | 0 ETH | 0.00178547 | ||||
Verify Age | 18594683 | 398 days ago | IN | 0 ETH | 0.00196048 | ||||
Verify Age | 18501713 | 411 days ago | IN | 0 ETH | 0.00091961 | ||||
Verify Age | 18412801 | 423 days ago | IN | 0 ETH | 0.00108917 | ||||
Verify Age | 18411953 | 423 days ago | IN | 0 ETH | 0.00115535 | ||||
Verify Age | 18411953 | 423 days ago | IN | 0 ETH | 0.00115535 | ||||
Verify Age | 18411915 | 423 days ago | IN | 0 ETH | 0.00081349 | ||||
Verify Age | 18408127 | 424 days ago | IN | 0 ETH | 0.00075866 | ||||
Verify Age | 18405720 | 424 days ago | IN | 0 ETH | 0.0005762 | ||||
Verify Age | 18368668 | 429 days ago | IN | 0 ETH | 0.00062666 | ||||
Verify Age | 18361404 | 430 days ago | IN | 0 ETH | 0.0004495 | ||||
Verify Age | 18360781 | 430 days ago | IN | 0 ETH | 0.00050343 | ||||
Verify Age | 18360686 | 430 days ago | IN | 0 ETH | 0.00054453 | ||||
Verify Age | 18360625 | 430 days ago | IN | 0 ETH | 0.0005829 | ||||
Verify Age | 18354717 | 431 days ago | IN | 0 ETH | 0.00051176 | ||||
Verify Age | 18354693 | 431 days ago | IN | 0 ETH | 0.00047914 | ||||
Verify Age | 18354074 | 431 days ago | IN | 0 ETH | 0.00032556 | ||||
Verify Age | 18352256 | 432 days ago | IN | 0 ETH | 0.00043318 | ||||
Verify Age | 18351652 | 432 days ago | IN | 0 ETH | 0.0004131 | ||||
Verify Age | 18351635 | 432 days ago | IN | 0 ETH | 0.00042562 | ||||
Verify Age | 18351149 | 432 days ago | IN | 0 ETH | 0.00036855 | ||||
Verify Age | 18350748 | 432 days ago | IN | 0 ETH | 0.00045917 | ||||
Verify Age | 18350434 | 432 days ago | IN | 0 ETH | 0.00049656 | ||||
Verify Age | 18345333 | 433 days ago | IN | 0 ETH | 0.00046131 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
AccountAge
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // WARNING! This smart contract has not been audited. // DO NOT USE THIS CONTRACT FOR PRODUCTION // This is an example contract to demonstrate how to integrate an application with the audited production release of AxiomV1 and AxiomV1Query. pragma solidity 0.8.19; // Constants and free functions to be inlined into by AxiomV1Core // ZK circuit constants: // AxiomV1 caches blockhashes in batches, stored as Merkle roots of binary Merkle trees uint32 constant BLOCK_BATCH_SIZE = 1024; uint32 constant BLOCK_BATCH_DEPTH = 10; // constants for batch import of historical block hashes // historical uploads a bigger batch of block hashes, stored as Merkle roots of binary Merkle trees uint32 constant HISTORICAL_BLOCK_BATCH_SIZE = 131072; // 2 ** 17 uint32 constant HISTORICAL_BLOCK_BATCH_DEPTH = 17; // we will consider the historical Merkle tree of blocks as a Merkle tree of the block batch roots uint32 constant HISTORICAL_NUM_ROOTS = 128; // HISTORICAL_BATCH_SIZE / BLOCK_BATCH_SIZE // The first 4 * 3 * 32 bytes of proof calldata are reserved for two BN254 G1 points for a pairing check // It will then be followed by (7 + BLOCK_BATCH_DEPTH * 2) * 32 bytes of public inputs/outputs uint32 constant AUX_PEAKS_START_IDX = 608; // PUBLIC_BYTES_START_IDX + 7 * 32 // Historical MMR Ring Buffer constants uint32 constant MMR_RING_BUFFER_SIZE = 8; /// @dev proofData stores bytes32 and uint256 values in hi-lo format as two uint128 values because the BN254 scalar field is 254 bits /// @dev The first 12 * 32 bytes of proofData are reserved for ZK proof verification data // Extract public instances from proof // The public instances are laid out in the proof calldata as follows: // First 4 * 3 * 32 = 384 bytes are reserved for proof verification data used with the pairing precompile // 384..384 + 32 * 2: prevHash (32 bytes) as two uint128 cast to uint256, because zk proof uses 254 bit field and cannot fit uint256 into a single element // 384 + 32 * 2..384 + 32 * 4: endHash (32 bytes) as two uint128 cast to uint256 // 384 + 32 * 4..384 + 32 * 5: startBlockNumber (uint32: 4 bytes) and endBlockNumber (uint32: 4 bytes) are concatenated as `startBlockNumber . endBlockNumber` (8 bytes) and then cast to uint256 // 384 + 32 * 5..384 + 32 * 7: root (32 bytes) as two uint128 cast to uint256, this is the highest peak of the MMR if endBlockNumber - startBlockNumber == 1023, otherwise 0 function getBoundaryBlockData(bytes calldata proofData) pure returns (bytes32 prevHash, bytes32 endHash, uint32 startBlockNumber, uint32 endBlockNumber, bytes32 root) { prevHash = bytes32(uint256(bytes32(proofData[384:416])) << 128 | uint256(bytes32(proofData[416:448]))); endHash = bytes32(uint256(bytes32(proofData[448:480])) << 128 | uint256(bytes32(proofData[480:512]))); startBlockNumber = uint32(bytes4(proofData[536:540])); endBlockNumber = uint32(bytes4(proofData[540:544])); root = bytes32(uint256(bytes32(proofData[544:576])) << 128 | uint256(bytes32(proofData[576:608]))); } // We have a Merkle mountain range of max depth BLOCK_BATCH_DEPTH (so length BLOCK_BATCH_DEPTH + 1 total) ordered in **decreasing** order of peak size, so: // `root` from `getBoundaryBlockData` is the peak for depth BLOCK_BATCH_DEPTH // `getAuxMmrPeak(proofData, i)` is the peaks for depth BLOCK_BATCH_DEPTH - 1 - i // 384 + 32 * 7 + 32 * 2 * i .. 384 + 32 * 7 + 32 * 2 * (i + 1): (32 bytes) as two uint128 cast to uint256, same as blockHash // Note that the decreasing ordering is *different* than the convention in library MerkleMountainRange function getAuxMmrPeak(bytes calldata proofData, uint256 i) pure returns (bytes32) { return bytes32( uint256(bytes32(proofData[AUX_PEAKS_START_IDX + i * 64:AUX_PEAKS_START_IDX + i * 64 + 32])) << 128 | uint256(bytes32(proofData[AUX_PEAKS_START_IDX + i * 64 + 32:AUX_PEAKS_START_IDX + (i + 1) * 64])) ); } interface IAxiomV1Verifier { /// @notice A merkle proof to verify a block against the verified blocks cached by Axiom /// @dev `BLOCK_BATCH_DEPTH = 10` struct BlockHashWitness { uint32 blockNumber; bytes32 claimedBlockHash; bytes32 prevHash; uint32 numFinal; bytes32[BLOCK_BATCH_DEPTH] merkleProof; } /// @notice Verify the blockhash of block blockNumber equals claimedBlockHash. Assumes that blockNumber is within the last 256 most recent blocks. /// @param blockNumber The block number to verify /// @param claimedBlockHash The claimed blockhash of block blockNumber function isRecentBlockHashValid(uint32 blockNumber, bytes32 claimedBlockHash) external view returns (bool); /// @notice Verify the blockhash of block witness.blockNumber equals witness.claimedBlockHash by checking against Axiom's cache of #historicalRoots. /// @dev For block numbers within the last 256, use #isRecentBlockHashValid instead. /// @param witness The block hash to verify and the Merkle proof to verify it /// witness.blockNumber is the block number to verify /// witness.claimedBlockHash is the claimed blockhash of block witness.blockNumber /// witness.prevHash is the prevHash stored in #historicalRoots(witness.blockNumber - witness.blockNumber % 1024) /// witness.numFinal is the numFinal stored in #historicalRoots(witness.blockNumber - witness.blockNumber % 1024) /// witness.merkleProof is the Merkle inclusion proof of witness.claimedBlockHash to the root stored in #historicalRoots(witness.blockNumber - witness.blockNumber % 1024) /// witness.merkleProof[i] is the sibling of the Merkle node at depth 10 - i, for i = 0, ..., 10 function isBlockHashValid(BlockHashWitness calldata witness) external view returns (bool); /// @notice Verify the blockhash of block blockNumber equals claimedBlockHash by checking against Axiom's cache of historical Merkle mountain ranges in #mmrRingBuffer. /// @dev Use event logs to determine the correct bufferId and get the MMR at that index in the ring buffer. /// @param mmr The Merkle mountain range commited to in #mmrRingBuffer(bufferId), must be correct length /// @param bufferId The index in the ring buffer of #mmrRingBuffer /// @param blockNumber The block number to verify /// @param claimedBlockHash The claimed blockhash of block blockNumber /// @param merkleProof The Merkle inclusion proof of claimedBlockHash to the corresponding peak in mmr. The correct peak is calculated from mmr.length and blockNumber. function mmrVerifyBlockHash( bytes32[] calldata mmr, uint8 bufferId, uint32 blockNumber, bytes32 claimedBlockHash, bytes32[] calldata merkleProof ) external view; } // The depth of the Merkle root of queries in: // `keccakBlockResponse`, `keccakAccountResponse`, and `keccakStorageResponse` uint32 constant QUERY_MERKLE_DEPTH = 6; interface IAxiomV1Query { /// @notice States of an on-chain query /// @param Inactive The query has not been made or was refunded. /// @param Active The query has been requested, but not fulfilled. /// @param Fulfilled The query was successfully fulfilled. enum AxiomQueryState { Inactive, Active, Fulfilled } /// @notice Stores metadata about a query /// @param payment The ETH payment received, in wei. /// @param state The state of the query. /// @param deadlineBlockNumber The deadline (in block number) after which a refund may be granted. /// @param refundee The address funds should be returned to if the query is not fulfilled. struct AxiomQueryMetadata { uint256 payment; AxiomQueryState state; uint32 deadlineBlockNumber; address payable refundee; } /// @notice Response values read from ZK proof for query. /// @param poseidonBlockResponse Poseidon Merkle root of `poseidon(blockHash . blockNumber . poseidon_tree_root(block_header))` /// @param keccakBlockResponse Keccak Merkle root of `keccak(blockHash . blockNumber)` /// @param poseidonAccountResponse Poseidon Merkle root of `poseidon(poseidonBlockResponseRow . poseidon(stateRoot . addr . poseidon_tree_root(account_state)))` /// @param keccakAccountResponse Keccak Merkle root of `keccak(blockNumber . addr . keccak(nonce . balance . storageRoot . codeHash))` /// @param poseidonStorageResponse Poseidon Merkle root of `poseidon(poseidonBlockResponseRow . poseidonAccountResponseRow . poseidon(storageRoot . slot . value))` /// @param keccakStorageResponse Keccak Merkle root of `keccak(blockNumber . addr . slot . value)` /// @param historicalMMRKeccak `keccak256(abi.encodePacked(mmr[10:]))` /// @param recentMMRKeccak `keccak256(abi.encodePacked(mmr[:10]))` // Detailed documentation on format here: https://hackmd.io/@axiom/S17K2drf2 // ** `poseidonBlockResponseRow = poseidon(blockHash . blockNumber . poseidon_tree_root(block_header))` // ** `poseidonAccountResponseRow = poseidon(stateRoot . addr . poseidon_tree_root(account_state)))` // ** `mmr` is a variable length array of bytes32 containing the Merkle Mountain Range the ZK proof is proving into. // `mmr[idx]` is either `bytes32(0)` or the Merkle root of `1 << idx` block hashes. // ** `mmr` is guaranteed to have length at least `10` and at most `32`. struct AxiomMMRQueryResponse { bytes32 poseidonBlockResponse; bytes32 keccakBlockResponse; bytes32 poseidonAccountResponse; bytes32 keccakAccountResponse; bytes32 poseidonStorageResponse; bytes32 keccakStorageResponse; bytes32 historicalMMRKeccak; bytes32 recentMMRKeccak; } /// @notice Stores witness data for checking MMRs /// @param prevHash The `prevHash` as in `IAxiomV1State`. /// @param root The `root` as in `IAxiomV1State`. /// @param numFinal The `numFinal` as in `IAxiomV1State`. /// @param startBlockNumber The `startBlockNumber` as in `IAxiomV1State`. /// @param recentMMRPeaks Peaks of the MMR committed to in the public input `recentMMRKeccak` of the ZK proof. /// @param mmrComplementOrPeaks If `len(recentMMRPeaks) <= numFinal`, then this is a complementary MMR containing /// the complement of `recentMMRPeaks` which together with `recentMMRPeaks` forms `root`. /// If `len(recentMMRPeaks) > numFinal`, then this is the MMR peaks of the `numFinal` blockhashes commited /// to in `root`. struct RecentMMRWitness { bytes32 prevHash; bytes32 root; uint32 numFinal; uint32 startBlockNumber; bytes32[10] recentMMRPeaks; bytes32[10] mmrComplementOrPeaks; } /// @notice Store a query result into a single block /// @param blockNumber The block number. /// @param blockHash The block hash. /// @param leafIdx The position of this result in the Merkle tree committed to by `keccakBlockResponse`. /// @param proof A Merkle proof into `keccakBlockResponse`. struct BlockResponse { uint32 blockNumber; bytes32 blockHash; uint32 leafIdx; bytes32[QUERY_MERKLE_DEPTH] proof; } /// @notice Store a query result into a single block /// @param blockNumber The block number. /// @param addr The address. /// @param nonce The nonce. /// @param balance The balance. /// @param storageRoot The storage root. /// @param codeHash The code hash. /// @param leafIdx The position of this result in the Merkle tree committed to by `keccakAccountResponse`. /// @param proof A Merkle proof into `keccakAccountResponse`. // Note: Fields are zero-padded by prefixing with zero bytes to: // * `nonce`: 8 bytes // * `balance`: 12 bytes // * `storageRoot`: 32 bytes // * `codeHash`: 32 bytes struct AccountResponse { uint32 blockNumber; address addr; uint64 nonce; uint96 balance; bytes32 storageRoot; bytes32 codeHash; uint32 leafIdx; bytes32[QUERY_MERKLE_DEPTH] proof; } /// @notice Store a query result into a single block /// @param blockNumber The block number. /// @param addr The address. /// @param slot The storage slot index. /// @param value The storage slot value. /// @param leafIdx The position of this result in the Merkle tree committed to by `keccakStorageResponse`. /// @param proof A Merkle proof into `keccakStorageResponse`. struct StorageResponse { uint32 blockNumber; address addr; uint256 slot; uint256 value; uint32 leafIdx; bytes32[QUERY_MERKLE_DEPTH] proof; } /// @notice Read the set of verified query responses in Keccak form. /// @param hash `verifiedKeccakResults(keccak256(keccakBlockResponse . keccakAccountResponse . keccakStorageResponse)) == true` /// if and only if each of `keccakBlockResponse`, `keccakAccountResponse`, and `keccakStorageResponse` have been verified /// on-chain by a ZK proof. function verifiedKeccakResults(bytes32 hash) external view returns (bool); /// @notice Read the set of verified query responses in Poseidon form. /// @param hash `verifiedPoseidonResults(keccak256(poseidonBlockResponse . poseidonAccountResponse . poseidonStorageResponse)) == true` /// if and only if each of `poseidonBlockResponse`, `poseidonAccountResponse`, and `poseidonStorageResponse` have been /// verified on-chain by a ZK proof. function verifiedPoseidonResults(bytes32 hash) external view returns (bool); /// @notice Returns the metadata associated to a query /// @param keccakQueryResponse The hash of the query response. function queries(bytes32 keccakQueryResponse) external view returns ( uint256 payment, AxiomQueryState state, uint32 deadlineBlockNumber, address payable refundee ); /// @notice Emitted when the `AxiomV1Core` address is updated. /// @param newAddress The updated address. event UpdateAxiomAddress(address newAddress); /// @notice Emitted when the batch query verifier address is updated. /// @param newAddress The updated address. event UpdateMMRVerifierAddress(address newAddress); /// @notice Emitted when a Keccak result is recorded /// @param keccakBlockResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakAccountResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakStorageResponse As documented in `AxiomMMRQueryResponse`. event KeccakResultEvent(bytes32 keccakBlockResponse, bytes32 keccakAccountResponse, bytes32 keccakStorageResponse); /// @notice Emitted when a Poseidon result is recorded /// @param poseidonBlockResponse As documented in `AxiomMMRQueryResponse`. /// @param poseidonAccountResponse As documented in `AxiomMMRQueryResponse`. /// @param poseidonStorageResponse As documented in `AxiomMMRQueryResponse`. event PoseidonResultEvent(bytes32 poseidonBlockResponse, bytes32 poseidonAccountResponse, bytes32 poseidonStorageResponse); /// @notice Emitted when the `minQueryPrice` is updated. /// @param minQueryPrice The new `minQueryPrice`. event UpdateMinQueryPrice(uint256 minQueryPrice); /// @notice Emitted when the `maxQueryPrice` is updated. /// @param maxQueryPrice The new `maxQueryPrice`. event UpdateMaxQueryPrice(uint256 maxQueryPrice); /// @notice Emitted when the `queryDeadlineInterval` is updated. /// @param queryDeadlineInterval The new `queryDeadlineInterval`. event UpdateQueryDeadlineInterval(uint32 queryDeadlineInterval); /// @notice Emitted when a new query with off-chain data availability is requested. /// @param keccakQueryResponse The hash of the claimed query response. /// @param payment The ETH payment offered, in wei. /// @param deadlineBlockNumber The deadline block number after which a refund is possible. /// @param refundee The address of the refundee. /// @param ipfsHash A content-addressed hash on IPFS where the query spec may be found. event QueryInitiatedOffchain(bytes32 keccakQueryResponse, uint256 payment, uint32 deadlineBlockNumber, address refundee, bytes32 ipfsHash); /// @notice Emitted when a new query with on-chain data availability is requested. /// @param keccakQueryResponse The hash of the claimed query response. /// @param payment The ETH payment offered, in wei. /// @param deadlineBlockNumber The deadline block number after which a refund is possible. /// @param refundee The address of the refundee. /// @param queryHash The hash of the on-chain query. event QueryInitiatedOnchain(bytes32 keccakQueryResponse, uint256 payment, uint32 deadlineBlockNumber, address refundee, bytes32 queryHash); /// @notice Emitted when a query is fulfilled. /// @param keccakQueryResponse The hash of the query response. /// @param payment The ETH payment collected, in wei. /// @param prover The address of the prover collecting payment. event QueryFulfilled(bytes32 keccakQueryResponse, uint256 payment, address prover); /// @notice Emitted when a query is refunded. /// @param keccakQueryResponse The hash of the query response. /// @param payment The ETH payment refunded minus gas, in wei. /// @param refundee The address collecting the refund. event QueryRefunded(bytes32 keccakQueryResponse, uint256 payment, uint32 deadlineBlockNumber, address refundee); /// @notice Verify a query result on-chain. /// @param mmrIdx The index of the cached MMR to verify against. /// @param mmrWitness Witness data to reconcile `recentMMR` against `historicalRoots`. /// @param proof The ZK proof data. function verifyResultVsMMR( uint32 mmrIdx, RecentMMRWitness calldata mmrWitness, bytes calldata proof ) external; /// @notice Request proof for query with on-chain query data availability. /// @param keccakQueryResponse The Keccak-encoded query response. /// @param refundee The address refunds should be sent to. /// @param query The serialized query. function sendQuery(bytes32 keccakQueryResponse, address payable refundee, bytes calldata query) external payable; /// @notice Request proof for query with off-chain query data availability. /// @param keccakQueryResponse The Keccak-encoded query response. /// @param refundee The address refunds should be sent to. /// @param ipfsHash The IPFS hash the query should optionally be posted to. function sendOffchainQuery(bytes32 keccakQueryResponse, address payable refundee, bytes32 ipfsHash) external payable; /// @notice Fulfill a query request on-chain. /// @param keccakQueryResponse The hashed query response. /// @param payee The address to send payment to. /// @param mmrIdx The index of the cached MMR to verify against. /// @param mmrWitness Witness data to reconcile `recentMMR` against `historicalRoots`. /// @param proof The ZK proof data. function fulfillQueryVsMMR( bytes32 keccakQueryResponse, address payable payee, uint32 mmrIdx, RecentMMRWitness calldata mmrWitness, bytes calldata proof ) external; /// @notice Trigger refund collection for a query after the deadline has expired. /// @param keccakQueryResponse THe hashed query response. function collectRefund(bytes32 keccakQueryResponse) external; /// @notice Checks whether an unpacked query response has already been verified. /// @param keccakBlockResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakAccountResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakStorageResponse As documented in `AxiomMMRQueryResponse`. function isKeccakResultValid(bytes32 keccakBlockResponse, bytes32 keccakAccountResponse, bytes32 keccakStorageResponse) external view returns (bool); /// @notice Checks whether an unpacked query response has already been verified. /// @param poseidonBlockResponse As documented in `AxiomMMRQueryResponse`. /// @param poseidonAccountResponse As documented in `AxiomMMRQueryResponse`. /// @param poseidonStorageResponse As documented in `AxiomMMRQueryResponse`. function isPoseidonResultValid(bytes32 poseidonBlockResponse, bytes32 poseidonAccountResponse, bytes32 poseidonStorageResponse) external view returns (bool); /// @notice Verify block, account, and storage data against responses which have already been proven. /// @param keccakBlockResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakAccountResponse As documented in `AxiomMMRQueryResponse`. /// @param keccakStorageResponse As documented in `AxiomMMRQueryResponse`. /// @param blockResponses The list of block results. /// @param accountResponses The list of account results. /// @param storageResponses The list of storage results. // block_response = keccak(blockHash . blockNumber) // account_response = hash(blockNumber . address . hash_tree_root(account_state)) // storage_response = hash(blockNumber . address . slot . value) function areResponsesValid( bytes32 keccakBlockResponse, bytes32 keccakAccountResponse, bytes32 keccakStorageResponse, BlockResponse[] calldata blockResponses, AccountResponse[] calldata accountResponses, StorageResponse[] calldata storageResponses ) external view returns (bool); } // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) // OpenZeppelin Contracts v4.4.1 (utils/Context.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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } contract AccountAge is Ownable { address public axiomQueryAddress; mapping(address => uint32) public birthBlocks; event UpdateAxiomQueryAddress(address newAddress); event AccountAgeVerified(address account, uint32 birthBlock); constructor(address _axiomQueryAddress) { axiomQueryAddress = _axiomQueryAddress; emit UpdateAxiomQueryAddress(_axiomQueryAddress); } function updateAxiomQueryAddress(address _axiomQueryAddress) external onlyOwner { axiomQueryAddress = _axiomQueryAddress; emit UpdateAxiomQueryAddress(_axiomQueryAddress); } function verifyAge(IAxiomV1Query.AccountResponse[] calldata accountProofs, bytes32[3] calldata keccakResponses) external { require(accountProofs.length == 2, "Too many account proofs"); address account = accountProofs[0].addr; require(account == accountProofs[1].addr, "Accounts are not the same"); require(accountProofs[0].blockNumber + 1 == accountProofs[1].blockNumber, "Block numbers are not consecutive"); require(accountProofs[0].nonce == 0, "Prev block nonce is not 0"); require(accountProofs[1].nonce > 0, "No account transactions in curr block"); uint256 addrSize; assembly { addrSize := extcodesize(account) } require(addrSize == 0, "Account is a contract"); require( IAxiomV1Query(axiomQueryAddress).areResponsesValid( keccakResponses[0], keccakResponses[1], keccakResponses[2], new IAxiomV1Query.BlockResponse[](0), accountProofs, new IAxiomV1Query.StorageResponse[](0) ), "Proof not valid" ); birthBlocks[account] = accountProofs[0].blockNumber; emit AccountAgeVerified(account, accountProofs[0].blockNumber); } }
{ "remappings": [ "@openzeppelin/contracts-upgradeable/=/Users/jpw/github/axiom-apps/lib/axiom-v1-contracts/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=/Users/jpw/github/axiom-apps/lib/axiom-v1-contracts/lib/openzeppelin-contracts/contracts/", "axiom-contracts/=../lib/axiom-v1-contracts/", "axiom-v1-contracts/=/Users/jpw/github/axiom-apps/lib/axiom-v1-contracts/contracts/", "ds-test/=../lib/forge-std/lib/ds-test/src/", "forge-std/=../lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=/Users/jpw/github/axiom-apps/lib/axiom-v1-contracts/lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=../lib/openzeppelin-contracts/contracts/", "utils/=../lib/utils/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_axiomQueryAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint32","name":"birthBlock","type":"uint32"}],"name":"AccountAgeVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"UpdateAxiomQueryAddress","type":"event"},{"inputs":[],"name":"axiomQueryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"birthBlocks","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_axiomQueryAddress","type":"address"}],"name":"updateAxiomQueryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"bytes32","name":"storageRoot","type":"bytes32"},{"internalType":"bytes32","name":"codeHash","type":"bytes32"},{"internalType":"uint32","name":"leafIdx","type":"uint32"},{"internalType":"bytes32[6]","name":"proof","type":"bytes32[6]"}],"internalType":"struct IAxiomV1Query.AccountResponse[]","name":"accountProofs","type":"tuple[]"},{"internalType":"bytes32[3]","name":"keccakResponses","type":"bytes32[3]"}],"name":"verifyAge","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080346100d357601f610b4438819003918201601f19168301916001600160401b038311848410176100d8578084926020946040528339810103126100d357516001600160a01b0390818116908190036100d3577f68de448da211dae8043270d0ad5291d8fc6f9345e1acf4cfacabbe9a7233ae9d918160209260005460018060a01b0319903382821617600055604051943391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a360015416176001558152a1604051610a5590816100ef8239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe608080604052600436101561001357600080fd5b60003560e01c9081633ba7c59a146108fe575080633cc7922114610892578063715018a6146108395780638449e692146107f95780638da5cb5b146107d0578063c20c5ca9146101355763f2fde38b1461006c57600080fd5b3461013057602036600319011261013057610085610922565b61008d610938565b6001600160a01b039081169081156100dc57600054826001600160601b0360a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b600080fd5b346101305760803660031901126101305760043567ffffffffffffffff811161013057366023820112156101305767ffffffffffffffff816004013511610130573660246101a083600401350283010111610130573660841161013057600281600401350361078b57806004013515610775576101b460448201610990565b90806004013560011015610775576001600160a01b036101d76101e48301610990565b166001600160a01b0383160361073057600163ffffffff6101fa602484016109a4565b160163ffffffff811161071a5763ffffffff8061021a6101c485016109a4565b169116036106cb5767ffffffffffffffff610237606483016109b5565b166106865767ffffffffffffffff61025261020483016109b5565b161561063357813b6105f657600154604051906001600160a01b0316610277826109ca565b6000825260405191610288836109ca565b6000835260405192839163190e7a7560e21b835260243560048401526044356024840152606435604484015260c0606484015280518060c4850152602060e4850192019060005b8181106105a457505050828103600319016084840152600486013581526020016024860160005b876004013581106104d55750506003198382030160a48401526020808351928381520192019060005b81811061046a5750505091818060209403915afa90811561045e576000916103f7575b50156103c0577f9fd5d31537ef0f7a1029cf79fdbec67607971ea7ee11a78c731e0f33a7a12e579163ffffffff6103a860248461038282604097016109a4565b60018060a01b0386166000526002602052848760002091168519825416179055016109a4565b83516001600160a01b039093168352166020820152a1005b60405162461bcd60e51b815260206004820152600f60248201526e141c9bdbd9881b9bdd081d985b1a59608a1b6044820152606490fd5b905060203d602011610457575b601f8101601f1916820167ffffffffffffffff81118382101761044157602091839160405281010312610130575180151581036101305783610342565b634e487b7160e01b600052604160045260246000fd5b503d610404565b6040513d6000823e3d90fd5b9193509160206101606001926104c7875163ffffffff8151168352858060a01b03858201511685840152604081015160408401526060808201519084015263ffffffff608082015116608084015260a080910151908301906109e6565b01940191019185939261031f565b919092935063ffffffff6104e884610a0e565b16815260208301356001600160a01b0381168103610130576001600160a01b03166020820152604083013567ffffffffffffffff811681036101305767ffffffffffffffff1660408201526060830135906001600160601b0382168203610130576101a080916001600160601b036001941660608201526080860135608082015260a0808701359082015263ffffffff61058460c08801610a0e565b1660c082015260c060e0870160e0830137019301910190859392916102f6565b919394509160206101206001926105e7875163ffffffff8151168352848101518584015263ffffffff6040820151166040840152606080910151908301906109e6565b019401910191869493926102cf565b60405162461bcd60e51b81526020600482015260156024820152741058d8dbdd5b9d081a5cc8184818dbdb9d1c9858dd605a1b6044820152606490fd5b60405162461bcd60e51b815260206004820152602560248201527f4e6f206163636f756e74207472616e73616374696f6e7320696e206375727220604482015264626c6f636b60d81b6064820152608490fd5b60405162461bcd60e51b815260206004820152601960248201527f5072657620626c6f636b206e6f6e6365206973206e6f742030000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152602160248201527f426c6f636b206e756d6265727320617265206e6f7420636f6e736563757469766044820152606560f81b6064820152608490fd5b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152601960248201527f4163636f756e747320617265206e6f74207468652073616d65000000000000006044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b60405162461bcd60e51b815260206004820152601760248201527f546f6f206d616e79206163636f756e742070726f6f66730000000000000000006044820152606490fd5b34610130576000366003190112610130576000546040516001600160a01b039091168152602090f35b34610130576020366003190112610130576001600160a01b0361081a610922565b166000526002602052602063ffffffff60406000205416604051908152f35b3461013057600036600319011261013057610852610938565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610130576020366003190112610130577f68de448da211dae8043270d0ad5291d8fc6f9345e1acf4cfacabbe9a7233ae9d60206108ce610922565b6108d6610938565b600180546001600160a01b0319166001600160a01b03929092169182179055604051908152a1005b34610130576000366003190112610130576001546001600160a01b03168152602090f35b600435906001600160a01b038216820361013057565b6000546001600160a01b0316330361094c57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b356001600160a01b03811681036101305790565b3563ffffffff811681036101305790565b3567ffffffffffffffff811681036101305790565b6020810190811067ffffffffffffffff82111761044157604052565b6000915b600683106109f757505050565b6001908251815260208091019201920191906109ea565b359063ffffffff821682036101305756fea26469706673582212207f0a4522a605e9abdecd9a2714e47b3a0f5f4b802016efb16722f2b7b51f6c9464736f6c63430008130033000000000000000000000000d617ab7f787adf64c2b5b920c251ea10cd35a952
Deployed Bytecode
0x608080604052600436101561001357600080fd5b60003560e01c9081633ba7c59a146108fe575080633cc7922114610892578063715018a6146108395780638449e692146107f95780638da5cb5b146107d0578063c20c5ca9146101355763f2fde38b1461006c57600080fd5b3461013057602036600319011261013057610085610922565b61008d610938565b6001600160a01b039081169081156100dc57600054826001600160601b0360a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b600080fd5b346101305760803660031901126101305760043567ffffffffffffffff811161013057366023820112156101305767ffffffffffffffff816004013511610130573660246101a083600401350283010111610130573660841161013057600281600401350361078b57806004013515610775576101b460448201610990565b90806004013560011015610775576001600160a01b036101d76101e48301610990565b166001600160a01b0383160361073057600163ffffffff6101fa602484016109a4565b160163ffffffff811161071a5763ffffffff8061021a6101c485016109a4565b169116036106cb5767ffffffffffffffff610237606483016109b5565b166106865767ffffffffffffffff61025261020483016109b5565b161561063357813b6105f657600154604051906001600160a01b0316610277826109ca565b6000825260405191610288836109ca565b6000835260405192839163190e7a7560e21b835260243560048401526044356024840152606435604484015260c0606484015280518060c4850152602060e4850192019060005b8181106105a457505050828103600319016084840152600486013581526020016024860160005b876004013581106104d55750506003198382030160a48401526020808351928381520192019060005b81811061046a5750505091818060209403915afa90811561045e576000916103f7575b50156103c0577f9fd5d31537ef0f7a1029cf79fdbec67607971ea7ee11a78c731e0f33a7a12e579163ffffffff6103a860248461038282604097016109a4565b60018060a01b0386166000526002602052848760002091168519825416179055016109a4565b83516001600160a01b039093168352166020820152a1005b60405162461bcd60e51b815260206004820152600f60248201526e141c9bdbd9881b9bdd081d985b1a59608a1b6044820152606490fd5b905060203d602011610457575b601f8101601f1916820167ffffffffffffffff81118382101761044157602091839160405281010312610130575180151581036101305783610342565b634e487b7160e01b600052604160045260246000fd5b503d610404565b6040513d6000823e3d90fd5b9193509160206101606001926104c7875163ffffffff8151168352858060a01b03858201511685840152604081015160408401526060808201519084015263ffffffff608082015116608084015260a080910151908301906109e6565b01940191019185939261031f565b919092935063ffffffff6104e884610a0e565b16815260208301356001600160a01b0381168103610130576001600160a01b03166020820152604083013567ffffffffffffffff811681036101305767ffffffffffffffff1660408201526060830135906001600160601b0382168203610130576101a080916001600160601b036001941660608201526080860135608082015260a0808701359082015263ffffffff61058460c08801610a0e565b1660c082015260c060e0870160e0830137019301910190859392916102f6565b919394509160206101206001926105e7875163ffffffff8151168352848101518584015263ffffffff6040820151166040840152606080910151908301906109e6565b019401910191869493926102cf565b60405162461bcd60e51b81526020600482015260156024820152741058d8dbdd5b9d081a5cc8184818dbdb9d1c9858dd605a1b6044820152606490fd5b60405162461bcd60e51b815260206004820152602560248201527f4e6f206163636f756e74207472616e73616374696f6e7320696e206375727220604482015264626c6f636b60d81b6064820152608490fd5b60405162461bcd60e51b815260206004820152601960248201527f5072657620626c6f636b206e6f6e6365206973206e6f742030000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152602160248201527f426c6f636b206e756d6265727320617265206e6f7420636f6e736563757469766044820152606560f81b6064820152608490fd5b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152601960248201527f4163636f756e747320617265206e6f74207468652073616d65000000000000006044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b60405162461bcd60e51b815260206004820152601760248201527f546f6f206d616e79206163636f756e742070726f6f66730000000000000000006044820152606490fd5b34610130576000366003190112610130576000546040516001600160a01b039091168152602090f35b34610130576020366003190112610130576001600160a01b0361081a610922565b166000526002602052602063ffffffff60406000205416604051908152f35b3461013057600036600319011261013057610852610938565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610130576020366003190112610130577f68de448da211dae8043270d0ad5291d8fc6f9345e1acf4cfacabbe9a7233ae9d60206108ce610922565b6108d6610938565b600180546001600160a01b0319166001600160a01b03929092169182179055604051908152a1005b34610130576000366003190112610130576001546001600160a01b03168152602090f35b600435906001600160a01b038216820361013057565b6000546001600160a01b0316330361094c57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b356001600160a01b03811681036101305790565b3563ffffffff811681036101305790565b3567ffffffffffffffff811681036101305790565b6020810190811067ffffffffffffffff82111761044157604052565b6000915b600683106109f757505050565b6001908251815260208091019201920191906109ea565b359063ffffffff821682036101305756fea26469706673582212207f0a4522a605e9abdecd9a2714e47b3a0f5f4b802016efb16722f2b7b51f6c9464736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d617ab7f787adf64c2b5b920c251ea10cd35a952
-----Decoded View---------------
Arg [0] : _axiomQueryAddress (address): 0xd617ab7f787adF64C2b5B920c251ea10Cd35a952
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d617ab7f787adf64c2b5b920c251ea10cd35a952
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.