Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 8 from a total of 8 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Submit Merkle Ro... | 7593632 | 17 days ago | IN | 0 ETH | 0.00043477 | ||||
Submit Merkle Ro... | 7260776 | 65 days ago | IN | 0 ETH | 0.00000066 | ||||
Submit Merkle Ro... | 7250483 | 67 days ago | IN | 0 ETH | 0.00604182 | ||||
Submit Merkle Ro... | 7226772 | 70 days ago | IN | 0 ETH | 0.00000038 | ||||
Submit Merkle Ro... | 7223714 | 71 days ago | IN | 0 ETH | 0.00348199 | ||||
Submit Merkle Ro... | 7214668 | 72 days ago | IN | 0 ETH | 0.00203508 | ||||
Submit Merkle Ro... | 7214404 | 72 days ago | IN | 0 ETH | 0.00087995 | ||||
Submit Merkle Ro... | 7206626 | 73 days ago | IN | 0 ETH | 0.00000037 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
7201549 | 74 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
RiscZeroSetVerifier
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; import {MerkleProof} from "openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import {IRiscZeroVerifier, Receipt, ReceiptClaim, ReceiptClaimLib, VerificationFailed} from "./IRiscZeroVerifier.sol"; import {IRiscZeroSetVerifier, Seal} from "./IRiscZeroSetVerifier.sol"; /// @notice Error raised when this verifier receives a receipt with a selector that does not match /// its own. The selector value is calculated from the verifier parameters, and so this /// usually indicates a mismatch between the version of the prover and this verifier. error SelectorMismatch(bytes4 received, bytes4 expected); library RiscZeroSetVerifierLib { function selector(bytes32 imageId) internal pure returns (bytes4) { return bytes4( sha256( abi.encodePacked( // tag sha256("risc0.SetInclusionReceiptVerifierParameters"), // down imageId, // down length uint16(1) << 8 ) ) ); } } /// @notice RiscZeroSetVerifier verifier contract for RISC Zero receipts of execution. contract RiscZeroSetVerifier is IRiscZeroSetVerifier { using ReceiptClaimLib for ReceiptClaim; /// Semantic version of the the RISC Zero Set Verifier. string public constant VERSION = "0.1.0"; IRiscZeroVerifier public immutable VERIFIER; /// @notice A short key attached to the seal to select the correct verifier implementation. /// @dev The selector is taken from the hash of the verifier parameters including the Groth16 /// verification key and the control IDs that commit to the RISC Zero circuits. If two /// receipts have different selectors (i.e. different verifier parameters), then it can /// generally be assumed that they need distinct verifier implementations. This is used as /// part of the RISC Zero versioning mechanism. /// /// A selector is not intended to be collision resistant, in that it is possible to find /// two preimages that result in the same selector. This is acceptable since it's purpose /// to a route a request among a set of trusted verifiers, and to make errors of sending a /// receipt to a mismatching verifiers easier to debug. It is analogous to the ABI /// function selectors. bytes4 public immutable SELECTOR; bytes32 private immutable IMAGE_ID; string private imageUrl; mapping(bytes32 => bool) private merkleRoots; constructor(IRiscZeroVerifier verifier, bytes32 imageId, string memory _imageUrl) { VERIFIER = verifier; IMAGE_ID = imageId; imageUrl = _imageUrl; SELECTOR = RiscZeroSetVerifierLib.selector(imageId); } /// @inheritdoc IRiscZeroVerifier function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) public view { _verifyIntegrity(seal, ReceiptClaimLib.ok(imageId, journalDigest).digest()); } /// @inheritdoc IRiscZeroVerifier function verifyIntegrity(Receipt calldata receipt) public view { _verifyIntegrity(receipt.seal, receipt.claimDigest); } /// @notice internal implementation of verifyIntegrity, factored to avoid copying calldata bytes to memory. function _verifyIntegrity(bytes calldata seal, bytes32 claimDigest) internal view { Seal memory setVerifierSeal; // Check that the seal has a matching selector. Mismatch generally indicates that the // prover and this verifier are using different parameters, and so the verification // will not succeed. if (SELECTOR != bytes4(seal[:4])) { revert SelectorMismatch({received: bytes4(seal[:4]), expected: SELECTOR}); } // Check if the seal is not empty and decode it, otherwise use an empty array // TODO(victor): Can we verify the Merkle inclusion without abi decoding into memory? if (seal.length > 4) { setVerifierSeal = abi.decode(seal[4:], (Seal)); } // Compute the root and verify it against the stored Merkle roots if a // root seal was not provided, or validate the root seal. // NOTE: If an invalid root seal was provided, the verify will fail // even if the root was already verified earlier and stored in state. bytes32 root = MerkleProof.processProof(setVerifierSeal.path, claimDigest); if (setVerifierSeal.rootSeal.length > 0) { VERIFIER.verify(setVerifierSeal.rootSeal, IMAGE_ID, sha256(abi.encode(IMAGE_ID, root))); } else if (!merkleRoots[root]) { revert VerificationFailed(); } } function submitMerkleRoot(bytes32 root, bytes calldata seal) external { VERIFIER.verify(seal, IMAGE_ID, sha256(abi.encode(IMAGE_ID, root))); merkleRoots[root] = true; emit VerifiedRoot(root); } function containsRoot(bytes32 root) external view returns (bool) { return merkleRoots[root]; } function imageInfo() external view returns (bytes32, string memory) { return (IMAGE_ID, imageUrl); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; import {reverseByteOrderUint32} from "./Util.sol"; /// @notice A receipt attesting to the execution of a guest program. /// @dev A receipt contains two parts: a seal and a claim. The seal is a zero-knowledge proof /// attesting to knowledge of a zkVM execution resulting in the claim. The claim is a set of public /// outputs for the execution. Crucially, the claim includes the journal and the image ID. The /// image ID identifies the program that was executed, and the journal is the public data written /// by the program. Note that this struct only contains the claim digest, as can be obtained with /// the `digest()` function on `ReceiptClaimLib`. struct Receipt { bytes seal; bytes32 claimDigest; } /// @notice Public claims about a zkVM guest execution, such as the journal committed to by the guest. /// @dev Also includes important information such as the exit code and the starting and ending system /// state (i.e. the state of memory). `ReceiptClaim` is a "Merkle-ized struct" supporting /// partial openings of the underlying fields from a hash commitment to the full structure. struct ReceiptClaim { /// @notice Digest of the SystemState just before execution has begun. bytes32 preStateDigest; /// @notice Digest of the SystemState just after execution has completed. bytes32 postStateDigest; /// @notice The exit code for the execution. ExitCode exitCode; /// @notice A digest of the input to the guest. /// @dev This field is currently unused and must be set to the zero digest. bytes32 input; /// @notice Digest of the Output of the guest, including the journal /// and assumptions set during execution. bytes32 output; } library ReceiptClaimLib { using OutputLib for Output; using SystemStateLib for SystemState; bytes32 constant TAG_DIGEST = sha256("risc0.ReceiptClaim"); // Define a constant to ensure hashing is done at compile time. Can't use the // SystemStateLib.digest method here because the Solidity compiler complains. bytes32 constant SYSTEM_STATE_ZERO_DIGEST = 0xa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2; /// @notice Construct a ReceiptClaim from the given imageId and journalDigest. /// Returned ReceiptClaim will represent a successful execution of the zkVM, running /// the program committed by imageId and resulting in the journal specified by /// journalDigest. /// @param imageId The identifier for the guest program. /// @param journalDigest The SHA-256 digest of the journal bytes. /// @dev Input hash and postStateDigest are set to all-zeros (i.e. no committed input, or /// final memory state), the exit code is (Halted, 0), and there are no assumptions /// (i.e. the receipt is unconditional). function ok(bytes32 imageId, bytes32 journalDigest) internal pure returns (ReceiptClaim memory) { return ReceiptClaim( imageId, SYSTEM_STATE_ZERO_DIGEST, ExitCode(SystemExitCode.Halted, 0), bytes32(0), Output(journalDigest, bytes32(0)).digest() ); } function digest(ReceiptClaim memory claim) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down claim.input, claim.preStateDigest, claim.postStateDigest, claim.output, // data uint32(claim.exitCode.system) << 24, uint32(claim.exitCode.user) << 24, // down.length uint16(4) << 8 ) ); } } /// @notice Commitment to the memory state and program counter (pc) of the zkVM. /// @dev The "pre" and "post" fields of the ReceiptClaim are digests of the system state at the /// start are stop of execution. Programs are loaded into the zkVM by creating a memory image /// of the loaded program, and creating a system state for initializing the zkVM. This is /// known as the "image ID". struct SystemState { /// @notice Program counter. uint32 pc; /// @notice Root hash of a merkle tree which confirms the integrity of the memory image. bytes32 merkle_root; } library SystemStateLib { bytes32 constant TAG_DIGEST = sha256("risc0.SystemState"); function digest(SystemState memory state) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down state.merkle_root, // data reverseByteOrderUint32(state.pc), // down.length uint16(1) << 8 ) ); } } /// @notice Exit condition indicated by the zkVM at the end of the guest execution. /// @dev Exit codes have a "system" part and a "user" part. Semantically, the system part is set to /// indicate the type of exit (e.g. halt, pause, or system split) and is directly controlled by the /// zkVM. The user part is an exit code, similar to exit codes used in Linux, chosen by the guest /// program to indicate additional information (e.g. 0 to indicate success or 1 to indicate an /// error). struct ExitCode { SystemExitCode system; uint8 user; } /// @notice Exit condition indicated by the zkVM at the end of the execution covered by this proof. /// @dev /// `Halted` indicates normal termination of a program with an interior exit code returned from the /// guest program. A halted program cannot be resumed. /// /// `Paused` indicates the execution ended in a paused state with an interior exit code set by the /// guest program. A paused program can be resumed such that execution picks up where it left /// of, with the same memory state. /// /// `SystemSplit` indicates the execution ended on a host-initiated system split. System split is /// mechanism by which the host can temporarily stop execution of the execution ended in a system /// split has no output and no conclusions can be drawn about whether the program will eventually /// halt. System split is used in continuations to split execution into individually provable segments. enum SystemExitCode { Halted, Paused, SystemSplit } /// @notice Output field in the `ReceiptClaim`, committing to a claimed journal and assumptions list. struct Output { /// @notice Digest of the journal committed to by the guest execution. bytes32 journalDigest; /// @notice Digest of the ordered list of `ReceiptClaim` digests corresponding to the /// calls to `env::verify` and `env::verify_integrity`. /// @dev Verifying the integrity of a `Receipt` corresponding to a `ReceiptClaim` with a /// non-empty assumptions list does not guarantee unconditionally any of the claims over the /// guest execution (i.e. if the assumptions list is non-empty, then the journal digest cannot /// be trusted to correspond to a genuine execution). The claims can be checked by additional /// verifying a `Receipt` for every digest in the assumptions list. bytes32 assumptionsDigest; } library OutputLib { bytes32 constant TAG_DIGEST = sha256("risc0.Output"); function digest(Output memory output) internal pure returns (bytes32) { return sha256( abi.encodePacked( TAG_DIGEST, // down output.journalDigest, output.assumptionsDigest, // down.length uint16(2) << 8 ) ); } } /// @notice Error raised when cryptographic verification of the zero-knowledge proof fails. error VerificationFailed(); /// @notice Verifier interface for RISC Zero receipts of execution. interface IRiscZeroVerifier { /// @notice Verify that the given seal is a valid RISC Zero proof of execution with the /// given image ID and journal digest. Reverts on failure. /// @dev This method additionally ensures that the input hash is all-zeros (i.e. no /// committed input), the exit code is (Halted, 0), and there are no assumptions (i.e. the /// receipt is unconditional). /// @param seal The encoded cryptographic proof (i.e. SNARK). /// @param imageId The identifier for the guest program. /// @param journalDigest The SHA-256 digest of the journal bytes. function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view; /// @notice Verify that the given receipt is a valid RISC Zero receipt, ensuring the `seal` is /// valid a cryptographic proof of the execution with the given `claim`. Reverts on failure. /// @param receipt The receipt to be verified. function verifyIntegrity(Receipt calldata receipt) external view; }
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; import {IRiscZeroVerifier} from "./IRiscZeroVerifier.sol"; /// Seal of the SetInclusionReceipt. struct Seal { /// Merkle path to the leaf. bytes32[] path; /// Root seal. bytes rootSeal; } interface IRiscZeroSetVerifier is IRiscZeroVerifier { error VerificationFailed(); /// A new root has been added to the set. event VerifiedRoot(bytes32 root); /// Publishes a new root of a proof aggregation. function submitMerkleRoot(bytes32 root, bytes calldata seal) external; /// Returns whether `root` has been submitted. function containsRoot(bytes32 root) external view returns (bool); /// Returns the set builder imageId and its url. function imageInfo() external view returns (bytes32, string memory); }
// Copyright 2024 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.9; /// @notice reverse the byte order of the uint256 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint256(uint256 input) pure returns (uint256 v) { v = input; // swap bytes v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8) | ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8); // swap 2-byte long pairs v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16) | ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16); // swap 4-byte long pairs v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32) | ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32); // swap 8-byte long pairs v = ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64) | ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64); // swap 16-byte long pairs v = (v >> 128) | (v << 128); } /// @notice reverse the byte order of the uint32 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint32(uint32 input) pure returns (uint32 v) { v = input; // swap bytes v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8); // swap 2-byte long pairs v = (v >> 16) | (v << 16); } /// @notice reverse the byte order of the uint16 value. /// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding /// ensure that the encoded value will be little-endian. /// Written by k06a. https://ethereum.stackexchange.com/a/83627 function reverseByteOrderUint16(uint16 input) pure returns (uint16 v) { v = input; // swap bytes v = (v >> 8) | ((v & 0x00FF) << 8); }
{ "remappings": [ "forge-std/=../lib/forge-std/src/", "openzeppelin/=../lib/openzeppelin-contracts/", "@openzeppelin/contracts/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/contracts/", "ds-test/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts/=/Users/victorgraf/risc0/ethereum/lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"contract IRiscZeroVerifier","name":"verifier","type":"address"},{"internalType":"bytes32","name":"imageId","type":"bytes32"},{"internalType":"string","name":"_imageUrl","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes4","name":"received","type":"bytes4"},{"internalType":"bytes4","name":"expected","type":"bytes4"}],"name":"SelectorMismatch","type":"error"},{"inputs":[],"name":"VerificationFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"VerifiedRoot","type":"event"},{"inputs":[],"name":"SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERIFIER","outputs":[{"internalType":"contract IRiscZeroVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"containsRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imageInfo","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes","name":"seal","type":"bytes"}],"name":"submitMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"seal","type":"bytes"},{"internalType":"bytes32","name":"imageId","type":"bytes32"},{"internalType":"bytes32","name":"journalDigest","type":"bytes32"}],"name":"verify","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"seal","type":"bytes"},{"internalType":"bytes32","name":"claimDigest","type":"bytes32"}],"internalType":"struct Receipt","name":"receipt","type":"tuple"}],"name":"verifyIntegrity","outputs":[],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e060405234801561000f575f80fd5b5060405161133e38038061133e83398101604081905261002e91610181565b6001600160a01b03831660805260c08290525f61004b82826102dc565b506100558261006b565b6001600160e01b03191660a052506103c3915050565b5f6002806040516100b3907f72697363302e536574496e636c7573696f6e526563656970745665726966696581526a72506172616d657465727360a81b6020820152602b0190565b602060405180830381855afa1580156100ce573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906100f19190610396565b6040805160208101929092528101849052600160f81b606082015260620160408051601f1981840301815290829052610129916103ad565b602060405180830381855afa158015610144573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906101679190610396565b92915050565b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610193575f80fd5b83516001600160a01b03811681146101a9575f80fd5b6020850151604086015191945092506001600160401b038111156101cb575f80fd5b8401601f810186136101db575f80fd5b80516001600160401b038111156101f4576101f461016d565b604051601f8201601f19908116603f011681016001600160401b03811182821017156102225761022261016d565b604052818152828201602001881015610239575f80fd5b8160208401602083015e5f602083830101528093505050509250925092565b600181811c9082168061026c57607f821691505b60208210810361028a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156102d757805f5260205f20601f840160051c810160208510156102b55750805b601f840160051c820191505b818110156102d4575f81556001016102c1565b50505b505050565b81516001600160401b038111156102f5576102f561016d565b610309816103038454610258565b84610290565b6020601f82116001811461033b575f83156103245750848201515b5f19600385901b1c1916600184901b1784556102d4565b5f84815260208120601f198516915b8281101561036a578785015182556020948501946001909201910161034a565b508482101561038757868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156103a6575f80fd5b5051919050565b5f82518060208501845e5f920191825250919050565b60805160a05160c051610f1b6104235f395f818161020e01528181610231015281816103870152818161057e01526105a101525f8181608e0152818161046f01526104d301525f818160d3015281816101dd015261054a0152610f1b5ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c80636691f647116100585780636691f64714610154578063ab750e7514610167578063cdc971231461017a578063ffa1ad7414610190575f80fd5b8063053c238d1461008957806308c84e70146100ce5780631599ead51461010d57806348cbdfca14610122575b5f80fd5b6100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160e01b031990911681526020015b60405180910390f35b6100f57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c5565b61012061011b3660046109e9565b6101c1565b005b610144610130366004610a20565b5f9081526001602052604090205460ff1690565b60405190151581526020016100c5565b610120610162366004610a7c565b6101db565b610120610175366004610ac4565b610360565b610182610382565b6040516100c5929190610b3f565b6101b4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516100c59190610b5f565b6101d86101ce8280610b71565b8360200135610439565b50565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ab750e7583837f000000000000000000000000000000000000000000000000000000000000000060027f00000000000000000000000000000000000000000000000000000000000000008960405160200161026b929190918252602082015260400190565b60408051601f198184030181529082905261028591610bb4565b602060405180830381855afa1580156102a0573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906102c39190610bca565b6040518563ffffffff1660e01b81526004016102e29493929190610be1565b5f6040518083038186803b1580156102f8575f80fd5b505afa15801561030a573d5f803e3d5ffd5b5050505f84815260016020818152604092839020805460ff191690921790915590518581527fdd00992bb62ed043f2d437a844df0b524ab27e17bc67f8b8caf8bb5836be295992500160405180910390a1505050565b61037c848461037761037286866106b7565b610741565b610439565b50505050565b5f60607f00000000000000000000000000000000000000000000000000000000000000005f8080546103b390610c1f565b80601f01602080910402602001604051908101604052809291908181526020018280546103df90610c1f565b801561042a5780601f106104015761010080835404028352916020019161042a565b820191905f5260205f20905b81548152906001019060200180831161040d57829003601f168201915b50505050509050915091509091565b604080518082019091526060808252602082015261045a60045f8587610c57565b61046391610c7e565b6001600160e01b0319167f00000000000000000000000000000000000000000000000000000000000000006001600160e01b03191614610506576104aa60045f8587610c57565b6104b391610c7e565b604051632e2ce35360e21b81526001600160e01b031991821660048201527f0000000000000000000000000000000000000000000000000000000000000000909116602482015260440160405180910390fd5b600483111561052c5761051c8360048187610c57565b8101906105299190610d90565b90505b5f61053a825f0151846108a1565b60208301515190915015610682577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ab750e7583602001517f000000000000000000000000000000000000000000000000000000000000000060027f0000000000000000000000000000000000000000000000000000000000000000866040516020016105db929190918252602082015260400190565b60408051601f19818403018152908290526105f591610bb4565b602060405180830381855afa158015610610573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106339190610bca565b6040518463ffffffff1660e01b815260040161065193929190610e99565b5f6040518083038186803b158015610667575f80fd5b505afa158015610679573d5f803e3d5ffd5b505050506106b0565b5f8181526001602052604090205460ff166106b05760405163439cc0cd60e01b815260040160405180910390fd5b5050505050565b6106bf6109a7565b6040805160a0810182528481527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e26020820152815180830183529091820190805f81526020015f60ff1681525081526020015f801b815260200161073860405180604001604052808681526020015f801b8152506108e3565b90529392505050565b5f60028060405161076a907172697363302e52656365697074436c61696d60701b815260120190565b602060405180830381855afa158015610785573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107a89190610bca565b606084015184516020860151608087015160408801515160189060028111156107d3576107d3610ebd565b60408a810151602090810151825191820199909952908101969096526060860194909452608085019290925260a084015263ffffffff909116901b60e01b6001600160e01b03191660c082015260f89190911b6001600160f81b03191660c4820152600160fa1b60c882015260ca015b60408051601f198184030181529082905261085d91610bb4565b602060405180830381855afa158015610878573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061089b9190610bca565b92915050565b5f81815b84518110156108db576108d1828683815181106108c4576108c4610ed1565b6020026020010151610978565b91506001016108a5565b509392505050565b5f600280604051610906906b1c9a5cd8cc0b93dd5d1c1d5d60a21b8152600c0190565b602060405180830381855afa158015610921573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109449190610bca565b83516020808601516040805192830194909452928101919091526060810191909152600160f91b6080820152608201610843565b5f818310610992575f8281526020849052604090206109a0565b5f8381526020839052604090205b9392505050565b6040805160a0810182525f80825260208201529081016109d6604080518082019091525f808252602082015290565b81525f6020820181905260409091015290565b5f602082840312156109f9575f80fd5b813567ffffffffffffffff811115610a0f575f80fd5b8201604081850312156109a0575f80fd5b5f60208284031215610a30575f80fd5b5035919050565b5f8083601f840112610a47575f80fd5b50813567ffffffffffffffff811115610a5e575f80fd5b602083019150836020828501011115610a75575f80fd5b9250929050565b5f805f60408486031215610a8e575f80fd5b83359250602084013567ffffffffffffffff811115610aab575f80fd5b610ab786828701610a37565b9497909650939450505050565b5f805f8060608587031215610ad7575f80fd5b843567ffffffffffffffff811115610aed575f80fd5b610af987828801610a37565b90989097506020870135966040013595509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b828152604060208201525f610b576040830184610b11565b949350505050565b602081525f6109a06020830184610b11565b5f808335601e19843603018112610b86575f80fd5b83018035915067ffffffffffffffff821115610ba0575f80fd5b602001915036819003821315610a75575f80fd5b5f82518060208501845e5f920191825250919050565b5f60208284031215610bda575f80fd5b5051919050565b60608152836060820152838560808301375f608085830101525f6080601f19601f870116830101905083602083015282604083015295945050505050565b600181811c90821680610c3357607f821691505b602082108103610c5157634e487b7160e01b5f52602260045260245ffd5b50919050565b5f8085851115610c65575f80fd5b83861115610c71575f80fd5b5050820193919092039150565b80356001600160e01b03198116906004841015610caf576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610ced57610ced610cb6565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610d1c57610d1c610cb6565b604052919050565b5f82601f830112610d33575f80fd5b813567ffffffffffffffff811115610d4d57610d4d610cb6565b610d60601f8201601f1916602001610cf3565b818152846020838601011115610d74575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610da0575f80fd5b813567ffffffffffffffff811115610db6575f80fd5b820160408185031215610dc7575f80fd5b610dcf610cca565b813567ffffffffffffffff811115610de5575f80fd5b8201601f81018613610df5575f80fd5b803567ffffffffffffffff811115610e0f57610e0f610cb6565b8060051b610e1f60208201610cf3565b91825260208184018101929081019089841115610e3a575f80fd5b6020850194505b83851015610e6057843580835260209586019590935090910190610e41565b855250505050602082013567ffffffffffffffff811115610e7f575f80fd5b610e8b86828501610d24565b602083015250949350505050565b606081525f610eab6060830186610b11565b60208301949094525060400152919050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffdfea26469706673582212205976d1ea50c2019a9a6740f3140f728d189b9264d24c00ffcf2446abd4695b2264736f6c634300081a0033000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b691877d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb252600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d5856763846457278687a78516953455944717744413562574c753777456e375a576346766a417366714a645700000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610085575f3560e01c80636691f647116100585780636691f64714610154578063ab750e7514610167578063cdc971231461017a578063ffa1ad7414610190575f80fd5b8063053c238d1461008957806308c84e70146100ce5780631599ead51461010d57806348cbdfca14610122575b5f80fd5b6100b07fbfca9ccb0000000000000000000000000000000000000000000000000000000081565b6040516001600160e01b031990911681526020015b60405180910390f35b6100f57f000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b6918781565b6040516001600160a01b0390911681526020016100c5565b61012061011b3660046109e9565b6101c1565b005b610144610130366004610a20565b5f9081526001602052604090205460ff1690565b60405190151581526020016100c5565b610120610162366004610a7c565b6101db565b610120610175366004610ac4565b610360565b610182610382565b6040516100c5929190610b3f565b6101b4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516100c59190610b5f565b6101d86101ce8280610b71565b8360200135610439565b50565b7f000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b691876001600160a01b031663ab750e7583837f7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb2526060027f7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb252608960405160200161026b929190918252602082015260400190565b60408051601f198184030181529082905261028591610bb4565b602060405180830381855afa1580156102a0573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906102c39190610bca565b6040518563ffffffff1660e01b81526004016102e29493929190610be1565b5f6040518083038186803b1580156102f8575f80fd5b505afa15801561030a573d5f803e3d5ffd5b5050505f84815260016020818152604092839020805460ff191690921790915590518581527fdd00992bb62ed043f2d437a844df0b524ab27e17bc67f8b8caf8bb5836be295992500160405180910390a1505050565b61037c848461037761037286866106b7565b610741565b610439565b50505050565b5f60607f7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb252605f8080546103b390610c1f565b80601f01602080910402602001604051908101604052809291908181526020018280546103df90610c1f565b801561042a5780601f106104015761010080835404028352916020019161042a565b820191905f5260205f20905b81548152906001019060200180831161040d57829003601f168201915b50505050509050915091509091565b604080518082019091526060808252602082015261045a60045f8587610c57565b61046391610c7e565b6001600160e01b0319167fbfca9ccb000000000000000000000000000000000000000000000000000000006001600160e01b03191614610506576104aa60045f8587610c57565b6104b391610c7e565b604051632e2ce35360e21b81526001600160e01b031991821660048201527fbfca9ccb00000000000000000000000000000000000000000000000000000000909116602482015260440160405180910390fd5b600483111561052c5761051c8360048187610c57565b8101906105299190610d90565b90505b5f61053a825f0151846108a1565b60208301515190915015610682577f000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b691876001600160a01b031663ab750e7583602001517f7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb2526060027f7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb25260866040516020016105db929190918252602082015260400190565b60408051601f19818403018152908290526105f591610bb4565b602060405180830381855afa158015610610573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106339190610bca565b6040518463ffffffff1660e01b815260040161065193929190610e99565b5f6040518083038186803b158015610667575f80fd5b505afa158015610679573d5f803e3d5ffd5b505050506106b0565b5f8181526001602052604090205460ff166106b05760405163439cc0cd60e01b815260040160405180910390fd5b5050505050565b6106bf6109a7565b6040805160a0810182528481527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e26020820152815180830183529091820190805f81526020015f60ff1681525081526020015f801b815260200161073860405180604001604052808681526020015f801b8152506108e3565b90529392505050565b5f60028060405161076a907172697363302e52656365697074436c61696d60701b815260120190565b602060405180830381855afa158015610785573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906107a89190610bca565b606084015184516020860151608087015160408801515160189060028111156107d3576107d3610ebd565b60408a810151602090810151825191820199909952908101969096526060860194909452608085019290925260a084015263ffffffff909116901b60e01b6001600160e01b03191660c082015260f89190911b6001600160f81b03191660c4820152600160fa1b60c882015260ca015b60408051601f198184030181529082905261085d91610bb4565b602060405180830381855afa158015610878573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061089b9190610bca565b92915050565b5f81815b84518110156108db576108d1828683815181106108c4576108c4610ed1565b6020026020010151610978565b91506001016108a5565b509392505050565b5f600280604051610906906b1c9a5cd8cc0b93dd5d1c1d5d60a21b8152600c0190565b602060405180830381855afa158015610921573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906109449190610bca565b83516020808601516040805192830194909452928101919091526060810191909152600160f91b6080820152608201610843565b5f818310610992575f8281526020849052604090206109a0565b5f8381526020839052604090205b9392505050565b6040805160a0810182525f80825260208201529081016109d6604080518082019091525f808252602082015290565b81525f6020820181905260409091015290565b5f602082840312156109f9575f80fd5b813567ffffffffffffffff811115610a0f575f80fd5b8201604081850312156109a0575f80fd5b5f60208284031215610a30575f80fd5b5035919050565b5f8083601f840112610a47575f80fd5b50813567ffffffffffffffff811115610a5e575f80fd5b602083019150836020828501011115610a75575f80fd5b9250929050565b5f805f60408486031215610a8e575f80fd5b83359250602084013567ffffffffffffffff811115610aab575f80fd5b610ab786828701610a37565b9497909650939450505050565b5f805f8060608587031215610ad7575f80fd5b843567ffffffffffffffff811115610aed575f80fd5b610af987828801610a37565b90989097506020870135966040013595509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b828152604060208201525f610b576040830184610b11565b949350505050565b602081525f6109a06020830184610b11565b5f808335601e19843603018112610b86575f80fd5b83018035915067ffffffffffffffff821115610ba0575f80fd5b602001915036819003821315610a75575f80fd5b5f82518060208501845e5f920191825250919050565b5f60208284031215610bda575f80fd5b5051919050565b60608152836060820152838560808301375f608085830101525f6080601f19601f870116830101905083602083015282604083015295945050505050565b600181811c90821680610c3357607f821691505b602082108103610c5157634e487b7160e01b5f52602260045260245ffd5b50919050565b5f8085851115610c65575f80fd5b83861115610c71575f80fd5b5050820193919092039150565b80356001600160e01b03198116906004841015610caf576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610ced57610ced610cb6565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610d1c57610d1c610cb6565b604052919050565b5f82601f830112610d33575f80fd5b813567ffffffffffffffff811115610d4d57610d4d610cb6565b610d60601f8201601f1916602001610cf3565b818152846020838601011115610d74575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610da0575f80fd5b813567ffffffffffffffff811115610db6575f80fd5b820160408185031215610dc7575f80fd5b610dcf610cca565b813567ffffffffffffffff811115610de5575f80fd5b8201601f81018613610df5575f80fd5b803567ffffffffffffffff811115610e0f57610e0f610cb6565b8060051b610e1f60208201610cf3565b91825260208184018101929081019089841115610e3a575f80fd5b6020850194505b83851015610e6057843580835260209586019590935090910190610e41565b855250505050602082013567ffffffffffffffff811115610e7f575f80fd5b610e8b86828501610d24565b602083015250949350505050565b606081525f610eab6060830186610b11565b60208301949094525060400152919050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffdfea26469706673582212205976d1ea50c2019a9a6740f3140f728d189b9264d24c00ffcf2446abd4695b2264736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b691877d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb252600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d5856763846457278687a78516953455944717744413562574c753777456e375a576346766a417366714a645700000000000000000000000000000000
-----Decoded View---------------
Arg [0] : verifier (address): 0x925d8331ddc0a1F0d96E68CF073DFE1d92b69187
Arg [1] : imageId (bytes32): 0x7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb25260
Arg [2] : _imageUrl (string): https://gateway.pinata.cloud/ipfs/QmXVv8FErxhzxQiSEYDqwDA5bWLu7wEn7ZWcFvjAsfqJdW
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000925d8331ddc0a1f0d96e68cf073dfe1d92b69187
Arg [1] : 7d75250e86556132c0e10c05b0f1d823ae72a5e277a596039576b6578cb25260
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000050
Arg [4] : 68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066
Arg [5] : 732f516d5856763846457278687a78516953455944717744413562574c753777
Arg [6] : 456e375a576346766a417366714a645700000000000000000000000000000000
Loading...
Loading
[ Download: CSV Export ]
[ 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.