Source Code
Overview
ETH Balance
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 21 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH | ||||
| 8776233 | 521 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RiscZeroGroth16Verifier
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Copyright 2024 RISC Zero, Inc.
//
// The RiscZeroGroth16Verifier is a free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The RiscZeroGroth16Verifier is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// the RiscZeroGroth16Verifier. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.9;
import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol";
import {ControlID} from "./ControlID.sol";
import {Groth16Verifier} from "./Groth16Verifier.sol";
import {
ExitCode,
IRiscZeroVerifier,
Output,
OutputLib,
Receipt,
ReceiptClaim,
ReceiptClaimLib,
SystemExitCode,
VerificationFailed
} from "../IRiscZeroVerifier.sol";
import {StructHash} from "../StructHash.sol";
import {reverseByteOrderUint256, reverseByteOrderUint32} from "../Util.sol";
/// @notice A Groth16 seal over the claimed receipt claim.
struct Seal {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}
/// @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);
/// @notice Groth16 verifier contract for RISC Zero receipts of execution.
contract RiscZeroGroth16Verifier is IRiscZeroVerifier, Groth16Verifier {
using ReceiptClaimLib for ReceiptClaim;
using OutputLib for Output;
using SafeCast for uint256;
/// Semantic version of the the RISC Zero system of which this contract is part.
string public constant VERSION = "1.1.0-rc.3";
/// @notice Control root hash binding the set of circuits in the RISC Zero system.
/// @dev This value controls what set of recursion programs (e.g. lift, join, resolve), and
/// therefore what version of the zkVM circuit, will be accepted by this contract. Each
/// instance of this verifier contract will accept a single release of the RISC Zero circuits.
///
/// New releases of RISC Zero's zkVM require updating these values. These values can be
/// calculated from the [risc0 monorepo][1] using: `cargo xtask bootstrap`.
///
/// [1]: https://github.com/risc0/risc0
bytes16 public immutable CONTROL_ROOT_0;
bytes16 public immutable CONTROL_ROOT_1;
bytes32 public immutable BN254_CONTROL_ID;
/// @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;
/// @notice Identifier for the Groth16 verification key encoded into the base contract.
/// @dev This value is computed at compile time.
function verifier_key_digest() internal pure returns (bytes32) {
bytes32[] memory ic_digests = new bytes32[](6);
ic_digests[0] = sha256(abi.encodePacked(IC0x, IC0y));
ic_digests[1] = sha256(abi.encodePacked(IC1x, IC1y));
ic_digests[2] = sha256(abi.encodePacked(IC2x, IC2y));
ic_digests[3] = sha256(abi.encodePacked(IC3x, IC3y));
ic_digests[4] = sha256(abi.encodePacked(IC4x, IC4y));
ic_digests[5] = sha256(abi.encodePacked(IC5x, IC5y));
return sha256(
abi.encodePacked(
// tag
sha256("risc0_groth16.VerifyingKey"),
// down
sha256(abi.encodePacked(alphax, alphay)),
sha256(abi.encodePacked(betax1, betax2, betay1, betay2)),
sha256(abi.encodePacked(gammax1, gammax2, gammay1, gammay2)),
sha256(abi.encodePacked(deltax1, deltax2, deltay1, deltay2)),
StructHash.taggedList(sha256("risc0_groth16.VerifyingKey.IC"), ic_digests),
// down length
uint16(5) << 8
)
);
}
constructor(bytes32 control_root, bytes32 bn254_control_id) {
(CONTROL_ROOT_0, CONTROL_ROOT_1) = splitDigest(control_root);
BN254_CONTROL_ID = bn254_control_id;
SELECTOR = bytes4(
sha256(
abi.encodePacked(
// tag
sha256("risc0.Groth16ReceiptVerifierParameters"),
// down
control_root,
reverseByteOrderUint256(uint256(bn254_control_id)),
verifier_key_digest(),
// down length
uint16(3) << 8
)
)
);
}
/// @notice splits a digest into two 128-bit halves to use as public signal inputs.
/// @dev RISC Zero's Circom verifier circuit takes each of two hash digests in two 128-bit
/// chunks. These values can be derived from the digest by splitting the digest in half and
/// then reversing the bytes of each.
function splitDigest(bytes32 digest) internal pure returns (bytes16, bytes16) {
uint256 reversed = reverseByteOrderUint256(uint256(digest));
return (bytes16(uint128(reversed)), bytes16(uint128(reversed >> 128)));
}
/// @inheritdoc IRiscZeroVerifier
function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view {
_verifyIntegrity(seal, ReceiptClaimLib.ok(imageId, journalDigest).digest());
}
/// @inheritdoc IRiscZeroVerifier
function verifyIntegrity(Receipt calldata receipt) external view {
return _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 {
// 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});
}
// Run the Groth16 verify procedure.
(bytes16 claim0, bytes16 claim1) = splitDigest(claimDigest);
Seal memory decodedSeal = abi.decode(seal[4:], (Seal));
bool verified = this.verifyProof(
decodedSeal.a,
decodedSeal.b,
decodedSeal.c,
[
uint256(uint128(CONTROL_ROOT_0)),
uint256(uint128(CONTROL_ROOT_1)),
uint256(uint128(claim0)),
uint256(uint128(claim1)),
uint256(BN254_CONTROL_ID)
]
);
// Revert is verification failed.
if (!verified) {
revert VerificationFailed();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
}// 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
// This file is automatically generated by:
// cargo xtask bootstrap-groth16
pragma solidity ^0.8.9;
library ControlID {
bytes32 public constant CONTROL_ROOT = hex"8b6dcf11d463ac455361b41fb3ed053febb817491bdea00fdb340e45013b852e";
// NOTE: This has the opposite byte order to the value in the risc0 repository.
bytes32 public constant BN254_CONTROL_ID = hex"05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e";
}// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
contract Groth16Verifier {
// Scalar field size
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// Verification Key data
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant deltax1 = 1668323501672964604911431804142266013250380587483576094566949227275849579036;
uint256 constant deltax2 = 12043754404802191763554326994664886008979042643626290185762540825416902247219;
uint256 constant deltay1 = 7710631539206257456743780535472368339139328733484942210876916214502466455394;
uint256 constant deltay2 = 13740680757317479711909903993315946540841369848973133181051452051592786724563;
uint256 constant IC0x = 8446592859352799428420270221449902464741693648963397251242447530457567083492;
uint256 constant IC0y = 1064796367193003797175961162477173481551615790032213185848276823815288302804;
uint256 constant IC1x = 3179835575189816632597428042194253779818690147323192973511715175294048485951;
uint256 constant IC1y = 20895841676865356752879376687052266198216014795822152491318012491767775979074;
uint256 constant IC2x = 5332723250224941161709478398807683311971555792614491788690328996478511465287;
uint256 constant IC2y = 21199491073419440416471372042641226693637837098357067793586556692319371762571;
uint256 constant IC3x = 12457994489566736295787256452575216703923664299075106359829199968023158780583;
uint256 constant IC3y = 19706766271952591897761291684837117091856807401404423804318744964752784280790;
uint256 constant IC4x = 19617808913178163826953378459323299110911217259216006187355745713323154132237;
uint256 constant IC4y = 21663537384585072695701846972542344484111393047775983928357046779215877070466;
uint256 constant IC5x = 6834578911681792552110317589222010969491336870276623105249474534788043166867;
uint256 constant IC5y = 15060583660288623605191393599883223885678013570733629274538391874953353488393;
// Memory data
uint16 constant pVk = 0;
uint16 constant pPairing = 128;
uint16 constant pLastMem = 896;
function verifyProof(
uint256[2] calldata _pA,
uint256[2][2] calldata _pB,
uint256[2] calldata _pC,
uint256[5] calldata _pubSignals
) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
}
// G1 function to multiply a G1 value(x,y) to value in an address
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn, 32), y)
mstore(add(mIn, 64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
mstore(add(mIn, 64), mload(pR))
mstore(add(mIn, 96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
}
function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
let _pPairing := add(pMem, pPairing)
let _pVk := add(pMem, pVk)
mstore(_pVk, IC0x)
mstore(add(_pVk, 32), IC0y)
// Compute the linear combination vk_x
g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
// -A
mstore(_pPairing, calldataload(pA))
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
// B
mstore(add(_pPairing, 64), calldataload(pB))
mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
mstore(add(_pPairing, 160), calldataload(add(pB, 96)))
// alpha1
mstore(add(_pPairing, 192), alphax)
mstore(add(_pPairing, 224), alphay)
// beta2
mstore(add(_pPairing, 256), betax1)
mstore(add(_pPairing, 288), betax2)
mstore(add(_pPairing, 320), betay1)
mstore(add(_pPairing, 352), betay2)
// vk_x
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))
// gamma2
mstore(add(_pPairing, 448), gammax1)
mstore(add(_pPairing, 480), gammax2)
mstore(add(_pPairing, 512), gammay1)
mstore(add(_pPairing, 544), gammay2)
// C
mstore(add(_pPairing, 576), calldataload(pC))
mstore(add(_pPairing, 608), calldataload(add(pC, 32)))
// delta2
mstore(add(_pPairing, 640), deltax1)
mstore(add(_pPairing, 672), deltax2)
mstore(add(_pPairing, 704), deltay1)
mstore(add(_pPairing, 736), deltay2)
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)
isOk := and(success, mload(_pPairing))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, pLastMem))
// Validate that all evaluations ∈ F
checkField(calldataload(add(_pubSignals, 0)))
checkField(calldataload(add(_pubSignals, 32)))
checkField(calldataload(add(_pubSignals, 64)))
checkField(calldataload(add(_pubSignals, 96)))
checkField(calldataload(add(_pubSignals, 128)))
checkField(calldataload(add(_pubSignals, 160)))
// Validate all evaluations
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
mstore(0, isValid)
return(0, 0x20)
}
}
}// 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.9;
import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol";
import {reverseByteOrderUint16} from "./Util.sol";
/// @notice Structural hashing routines used for RISC Zero data structures.
/// @dev
/// StructHash implements hashing for structs, incorporating type tags for domain separation.
/// The goals of this library are:
/// * Collision resistance: it should not be possible to find two semantically distinct values that
/// produce the same digest.
/// * Simplicity: implementations should be simple to understand and write, as these methods must
/// be implemented in multiple languages and environments, including zkSNARK circuits.
/// * Incremental openings: it should be possible to incrementally open a nested struct without
/// needing to open (very many) extra fields (i.e. the struct should be "Merkle-ized").
library StructHash {
using SafeCast for uint256;
// @notice Compute the struct digest with the given tag digest and digest fields down.
function taggedStruct(bytes32 tagDigest, bytes32[] memory down) internal pure returns (bytes32) {
bytes memory data = new bytes(0);
return taggedStruct(tagDigest, down, data);
}
// @notice Compute the struct digest with the given tag digest, digest fields down, and data.
function taggedStruct(bytes32 tagDigest, bytes32[] memory down, bytes memory data)
internal
pure
returns (bytes32)
{
uint16 downLen = down.length.toUint16();
// swap the byte order to encode as little-endian.
bytes2 downLenLE = bytes2((downLen << 8) | (downLen >> 8));
return sha256(abi.encodePacked(tagDigest, down, data, downLenLE));
}
// @notice Add an element (head) to the incremental hash of a list (tail).
function taggedListCons(bytes32 tagDigest, bytes32 head, bytes32 tail) internal pure returns (bytes32) {
bytes32[] memory down = new bytes32[](2);
down[0] = head;
down[1] = tail;
return taggedStruct(tagDigest, down);
}
// @notice Hash the list by using taggedListCons to repeatedly add to the head of the list.
function taggedList(bytes32 tagDigest, bytes32[] memory list) internal pure returns (bytes32) {
bytes32 curr = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000);
for (uint256 i = 0; i < list.length; i++) {
curr = taggedListCons(tagDigest, list[list.length - 1 - i], curr);
}
return curr;
}
}// 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/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"bytes32","name":"control_root","type":"bytes32"},{"internalType":"bytes32","name":"bn254_control_id","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"bytes4","name":"received","type":"bytes4"},{"internalType":"bytes4","name":"expected","type":"bytes4"}],"name":"SelectorMismatch","type":"error"},{"inputs":[],"name":"VerificationFailed","type":"error"},{"inputs":[],"name":"BN254_CONTROL_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTROL_ROOT_0","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTROL_ROOT_1","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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"},{"inputs":[{"internalType":"uint256[2]","name":"_pA","type":"uint256[2]"},{"internalType":"uint256[2][2]","name":"_pB","type":"uint256[2][2]"},{"internalType":"uint256[2]","name":"_pC","type":"uint256[2]"},{"internalType":"uint256[5]","name":"_pubSignals","type":"uint256[5]"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
61010060405234801561001157600080fd5b5060405161251b38038061251b83398101604081905261003091611074565b610039826102bf565b6001600160801b031990811660a0521660805260c08190526040517f72697363302e47726f74683136526563656970745665726966696572506172618152656d657465727360d01b60208201526002908190602601602060405180830381855afa1580156100ab573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906100ce9190611098565b8361021f8460008190506008817eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff16901b6008827fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0016901c1790506010817dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff16901b6010827fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff000016901c1790506020817bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16901b6020827fffffffff00000000ffffffff00000000ffffffff00000000ffffffff0000000016901c17905060408177ffffffffffffffff0000000000000000ffffffffffffffff16901b6040827fffffffffffffffff0000000000000000ffffffffffffffff000000000000000016901c179050608081901b608082901c179050919050565b61022761042d565b60408051602081019590955284019290925260608301526080820152600360f81b60a082015260a20160408051601f198184030181529082905261026a916110e1565b602060405180830381855afa158015610287573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906102aa9190611098565b6001600160e01b03191660e052506111869050565b600080806104138460008190506008817eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff16901b6008827fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0016901c1790506010817dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff16901b6010827fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff000016901c1790506020817bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16901b6020827fffffffff00000000ffffffff00000000ffffffff00000000ffffffff0000000016901c17905060408177ffffffffffffffff0000000000000000ffffffffffffffff16901b6040827fffffffffffffffff0000000000000000ffffffffffffffff000000000000000016901c179050608081901b608082901c179050919050565b608081901b956001600160801b0319909116945092505050565b60408051600680825260e082019092526000918291906020820160c08036833701905050905060027f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be47f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd46040516020016104b1929190918252602082015260400190565b60408051601f19818403018152908290526104cb916110e1565b602060405180830381855afa1580156104e8573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061050b9190611098565b8160008151811061051e5761051e6110f4565b60200260200101818152505060027f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f7f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff6642604051602001610588929190918252602082015260400190565b60408051601f19818403018152908290526105a2916110e1565b602060405180830381855afa1580156105bf573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906105e29190611098565b816001815181106105f5576105f56110f4565b60200260200101818152505060027f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc3477f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b60405160200161065f929190918252602082015260400190565b60408051601f1981840301815290829052610679916110e1565b602060405180830381855afa158015610696573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906106b99190611098565b816002815181106106cc576106cc6110f4565b60200260200101818152505060027f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a77f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd6604051602001610736929190918252602082015260400190565b60408051601f1981840301815290829052610750916110e1565b602060405180830381855afa15801561076d573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107909190611098565b816003815181106107a3576107a36110f4565b60200260200101818152505060027f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d7f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e8260405160200161080d929190918252602082015260400190565b60408051601f1981840301815290829052610827916110e1565b602060405180830381855afa158015610844573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906108679190611098565b8160048151811061087a5761087a6110f4565b60200260200101818152505060027f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d4937f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e8096040516020016108e4929190918252602082015260400190565b60408051601f19818403018152908290526108fe916110e1565b602060405180830381855afa15801561091b573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061093e9190611098565b81600581518110610951576109516110f4565b602002602001018181525050600280604051610990907f72697363305f67726f746831362e566572696679696e674b65790000000000008152601a0190565b602060405180830381855afa1580156109ad573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109d09190611098565b60027f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e27f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d1926604051602001610a2e929190918252602082015260400190565b60408051601f1981840301815290829052610a48916110e1565b602060405180830381855afa158015610a65573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610a889190611098565b604080517f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c60208201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab918101919091527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a760608201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8608082015260029060a00160408051601f1981840301815290829052610b46916110e1565b602060405180830381855afa158015610b63573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610b869190611098565b604080517f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c260208201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed918101919091527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60608201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa608082015260029060a00160408051601f1981840301815290829052610c44916110e1565b602060405180830381855afa158015610c61573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610c849190611098565b604080517f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c60208201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e0333918101919091527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d03076260608201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d3608082015260029060a00160408051601f1981840301815290829052610d42916110e1565b602060405180830381855afa158015610d5f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d829190611098565b610dfd6002604051610db7907f72697363305f67726f746831362e566572696679696e674b65792e49430000008152601d0190565b602060405180830381855afa158015610dd4573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610df79190611098565b88610e93565b6040805160208101979097528601949094526060850192909252608084015260a083015260c0820152600560f81b60e082015260e20160408051601f1981840301815290829052610e4d916110e1565b602060405180830381855afa158015610e6a573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e8d9190611098565b91505090565b600080805b8351811015610eed57610ee385858360018851610eb5919061110a565b610ebf919061110a565b81518110610ecf57610ecf6110f4565b602002602001015184610ef760201b60201c565b9150600101610e98565b5090505b92915050565b604080516002808252606082018352600092839291906020830190803683370190505090508381600081518110610f3057610f306110f4565b6020026020010181815250508281600181518110610f5057610f506110f4565b6020908102919091010152610f658582610f6e565b95945050505050565b60408051600080825260208201909252610f89848483610f91565b949350505050565b600080610fa4845161103d60201b60201c565b9050600060088261ffff16901c60088361ffff16901b1760f01b9050600286868684604051602001610fd9949392919061112b565b60408051601f1981840301815290829052610ff3916110e1565b602060405180830381855afa158015611010573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110339190611098565b9695505050505050565b600061ffff821115611070576040516306dfcc6560e41b8152601060048201526024810183905260440160405180910390fd5b5090565b6000806040838503121561108757600080fd5b505080516020909101519092909150565b6000602082840312156110aa57600080fd5b5051919050565b6000815160005b818110156110d257602081850181015186830152016110b8565b50600093019283525090919050565b60006110ed82846110b1565b9392505050565b634e487b7160e01b600052603260045260246000fd5b81810381811115610ef157634e487b7160e01b600052601160045260246000fd5b84815260006020820185516020870160005b8281101561115b57815184526020938401939091019060010161113d565b50505061116881866110b1565b6001600160f01b031994909416845250506002909101949350505050565b60805160a05160c05160e05161133b6111e060003960008181609201528181610820015261088501526000818160ec015261095e015260008181610144015261092501526000818161018401526108fd015261133b6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638989fa2e1161005b5780638989fa2e1461013f5780639181e4b11461017f578063ab750e75146101a6578063ffa1ad74146101b957600080fd5b8063053c238d1461008d5780631599ead5146100d2578063258038e2146100e757806334baeab91461011c575b600080fd5b6100b47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160e01b031990911681526020015b60405180910390f35b6100e56100e0366004610e4b565b6101ef565b005b61010e7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016100c9565b61012f61012a366004610e9e565b610209565b60405190151581526020016100c9565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160801b031990911681526020016100c9565b6101667f000000000000000000000000000000000000000000000000000000000000000081565b6100e56101b4366004610f05565b6107db565b6101e26040518060400160405280600a815260200169312e312e302d72632e3360b01b81525081565b6040516100c99190610faa565b6102066101fc8280610fdd565b83602001356107fd565b50565b6000610769565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110610206576000805260206000f35b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610274576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa915050806102a5576000805260206000f35b5050505050565b7f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be485527f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd460208601526000608086018661034987357f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff66427f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f84610241565b61039960208801357f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b7f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34784610241565b6103e960408801357f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd67f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a784610241565b61043960608801357f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e827f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d84610241565b61048960808801357f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e8097f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49384610241565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6102808201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336102a08201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626102c08201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526107816000840135610210565b61078e6020840135610210565b61079b6040840135610210565b6107a86060840135610210565b6107b56080840135610210565b6107c260a0840135610210565b6107cf818486888a6102ac565b90508060005260206000f35b6107f784846107f26107ed8686610a18565b610aa8565b6107fd565b50505050565b61080b60046000848661102b565b61081491611055565b6001600160e01b0319167f00000000000000000000000000000000000000000000000000000000000000006001600160e01b031916146108b85761085c60046000848661102b565b61086591611055565b604051632e2ce35360e21b81526001600160e01b031991821660048201527f0000000000000000000000000000000000000000000000000000000000000000909116602482015260440160405180910390fd5b6000806108c483610c07565b909250905060006108d8856004818961102b565b8101906108e5919061114f565b8051602080830151604080850151815160a0810183527f0000000000000000000000000000000000000000000000000000000000000000608090811c82527f0000000000000000000000000000000000000000000000000000000000000000811c9582019590955289851c8184015288851c60608201527f00000000000000000000000000000000000000000000000000000000000000009481019490945290516334baeab960e01b815294955060009430946334baeab9946109ae9491939192600401611213565b602060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190611298565b905080610a0f5760405163439cc0cd60e01b815260040160405180910390fd5b50505050505050565b610a20610e06565b6040805160a0810182528481527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e260208201528151808301835290918201908060008152602001600060ff1681525081526020016000801b8152602001610a9d60405180604001604052808681526020016000801b815250610d6e565b905290505b92915050565b6000600280604051610ad2907172697363302e52656365697074436c61696d60701b815260120190565b602060405180830381855afa158015610aef573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610b1291906112d0565b60608401518451602086015160808701516040880151516018906002811115610b3d57610b3d6112ba565b60408a810151602090810151825191820199909952908101969096526060860194909452608085019290925260a084015263ffffffff909116901b60e01b6001600160e01b03191660c082015260f89190911b6001600160f81b03191660c4820152600160fa1b60c882015260ca015b60408051601f1981840301815290829052610bc7916112e9565b602060405180830381855afa158015610be4573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610aa291906112d0565b60008080610d548460008190506008817eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff16901b6008827fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0016901c1790506010817dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff16901b6010827fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff000016901c1790506020817bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16901b6020827fffffffff00000000ffffffff00000000ffffffff00000000ffffffff0000000016901c17905060408177ffffffffffffffff0000000000000000ffffffffffffffff16901b60408277ffffffffffffffff0000000000000000ffffffffffffffff1916901c179050608081901b608082901c179050919050565b608081901b956001600160801b0319909116945092505050565b6000600280604051610d92906b1c9a5cd8cc0b93dd5d1c1d5d60a21b8152600c0190565b602060405180830381855afa158015610daf573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610dd291906112d0565b83516020808601516040805192830194909452928101919091526060810191909152600160f91b6080820152608201610bad565b6040805160a08101825260008082526020820152908101610e37604080518082019091526000808252602082015290565b815260006020820181905260409091015290565b600060208284031215610e5d57600080fd5b813567ffffffffffffffff811115610e7457600080fd5b820160408185031215610e8657600080fd5b9392505050565b8060408101831015610aa257600080fd5b6000806000806101a08587031215610eb557600080fd5b610ebf8686610e8d565b935060c0850186811115610ed257600080fd5b604086019350610ee28782610e8d565b925050856101a086011115610ef657600080fd5b50919490935090916101000190565b60008060008060608587031215610f1b57600080fd5b843567ffffffffffffffff811115610f3257600080fd5b8501601f81018713610f4357600080fd5b803567ffffffffffffffff811115610f5a57600080fd5b876020828401011115610f6c57600080fd5b602091820198909750908601359560400135945092505050565b60005b83811015610fa1578181015183820152602001610f89565b50506000910152565b6020815260008251806020840152610fc9816040850160208701610f86565b601f01601f19169190910160400192915050565b6000808335601e19843603018112610ff457600080fd5b83018035915067ffffffffffffffff82111561100f57600080fd5b60200191503681900382131561102457600080fd5b9250929050565b6000808585111561103b57600080fd5b8386111561104857600080fd5b5050820193919092039150565b80356001600160e01b03198116906004841015611086576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156110c6576110c661108d565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156110f5576110f561108d565b604052919050565b600082601f83011261110e57600080fd5b61111860406110cc565b80604084018581111561112a57600080fd5b845b8181101561114457803584526020938401930161112c565b509095945050505050565b600061010082840312801561116357600080fd5b50600061116e6110a3565b61117885856110fd565b815284605f850112611188578182fd5b6040611193816110cc565b8060c08701888111156111a4578586fd5b6040880195505b808610156111ce576111bd89876110fd565b8352948301946020909201916111ab565b8160208601526111de89826110fd565b60408601525092979650505050505050565b8060005b60028110156107f75781518452602093840193909101906001016111f4565b6101a0810161122282876111f0565b604082018560005b60028110156112545761123e8383516111f0565b604092909201916020919091019060010161122a565b50505061126460c08301856111f0565b61010082018360005b600581101561128c57815183526020928301929091019060010161126d565b50505095945050505050565b6000602082840312156112aa57600080fd5b81518015158114610e8657600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156112e257600080fd5b5051919050565b600082516112fb818460208701610f86565b919091019291505056fea26469706673582212203fe49f9ecb25f4bac5624cea644bc0c051f88ccf9b48840b01228b1ba42c215d64736f6c634300081a00338b6dcf11d463ac455361b41fb3ed053febb817491bdea00fdb340e45013b852e05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100885760003560e01c80638989fa2e1161005b5780638989fa2e1461013f5780639181e4b11461017f578063ab750e75146101a6578063ffa1ad74146101b957600080fd5b8063053c238d1461008d5780631599ead5146100d2578063258038e2146100e757806334baeab91461011c575b600080fd5b6100b47f50bd17690000000000000000000000000000000000000000000000000000000081565b6040516001600160e01b031990911681526020015b60405180910390f35b6100e56100e0366004610e4b565b6101ef565b005b61010e7f05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e81565b6040519081526020016100c9565b61012f61012a366004610e9e565b610209565b60405190151581526020016100c9565b6101667f2e853b01450e34db0fa0de1b4917b8eb0000000000000000000000000000000081565b6040516001600160801b031990911681526020016100c9565b6101667f3f05edb31fb4615345ac63d411cf6d8b0000000000000000000000000000000081565b6100e56101b4366004610f05565b6107db565b6101e26040518060400160405280600a815260200169312e312e302d72632e3360b01b81525081565b6040516100c99190610faa565b6102066101fc8280610fdd565b83602001356107fd565b50565b6000610769565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110610206576000805260206000f35b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610274576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa915050806102a5576000805260206000f35b5050505050565b7f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be485527f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd460208601526000608086018661034987357f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff66427f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f84610241565b61039960208801357f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b7f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34784610241565b6103e960408801357f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd67f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a784610241565b61043960608801357f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e827f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d84610241565b61048960808801357f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e8097f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49384610241565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6102808201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336102a08201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626102c08201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526107816000840135610210565b61078e6020840135610210565b61079b6040840135610210565b6107a86060840135610210565b6107b56080840135610210565b6107c260a0840135610210565b6107cf818486888a6102ac565b90508060005260206000f35b6107f784846107f26107ed8686610a18565b610aa8565b6107fd565b50505050565b61080b60046000848661102b565b61081491611055565b6001600160e01b0319167f50bd1769000000000000000000000000000000000000000000000000000000006001600160e01b031916146108b85761085c60046000848661102b565b61086591611055565b604051632e2ce35360e21b81526001600160e01b031991821660048201527f50bd176900000000000000000000000000000000000000000000000000000000909116602482015260440160405180910390fd5b6000806108c483610c07565b909250905060006108d8856004818961102b565b8101906108e5919061114f565b8051602080830151604080850151815160a0810183527f3f05edb31fb4615345ac63d411cf6d8b00000000000000000000000000000000608090811c82527f2e853b01450e34db0fa0de1b4917b8eb00000000000000000000000000000000811c9582019590955289851c8184015288851c60608201527f05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e9481019490945290516334baeab960e01b815294955060009430946334baeab9946109ae9491939192600401611213565b602060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190611298565b905080610a0f5760405163439cc0cd60e01b815260040160405180910390fd5b50505050505050565b610a20610e06565b6040805160a0810182528481527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e260208201528151808301835290918201908060008152602001600060ff1681525081526020016000801b8152602001610a9d60405180604001604052808681526020016000801b815250610d6e565b905290505b92915050565b6000600280604051610ad2907172697363302e52656365697074436c61696d60701b815260120190565b602060405180830381855afa158015610aef573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610b1291906112d0565b60608401518451602086015160808701516040880151516018906002811115610b3d57610b3d6112ba565b60408a810151602090810151825191820199909952908101969096526060860194909452608085019290925260a084015263ffffffff909116901b60e01b6001600160e01b03191660c082015260f89190911b6001600160f81b03191660c4820152600160fa1b60c882015260ca015b60408051601f1981840301815290829052610bc7916112e9565b602060405180830381855afa158015610be4573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610aa291906112d0565b60008080610d548460008190506008817eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff16901b6008827fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0016901c1790506010817dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff16901b6010827fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff000016901c1790506020817bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16901b6020827fffffffff00000000ffffffff00000000ffffffff00000000ffffffff0000000016901c17905060408177ffffffffffffffff0000000000000000ffffffffffffffff16901b60408277ffffffffffffffff0000000000000000ffffffffffffffff1916901c179050608081901b608082901c179050919050565b608081901b956001600160801b0319909116945092505050565b6000600280604051610d92906b1c9a5cd8cc0b93dd5d1c1d5d60a21b8152600c0190565b602060405180830381855afa158015610daf573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610dd291906112d0565b83516020808601516040805192830194909452928101919091526060810191909152600160f91b6080820152608201610bad565b6040805160a08101825260008082526020820152908101610e37604080518082019091526000808252602082015290565b815260006020820181905260409091015290565b600060208284031215610e5d57600080fd5b813567ffffffffffffffff811115610e7457600080fd5b820160408185031215610e8657600080fd5b9392505050565b8060408101831015610aa257600080fd5b6000806000806101a08587031215610eb557600080fd5b610ebf8686610e8d565b935060c0850186811115610ed257600080fd5b604086019350610ee28782610e8d565b925050856101a086011115610ef657600080fd5b50919490935090916101000190565b60008060008060608587031215610f1b57600080fd5b843567ffffffffffffffff811115610f3257600080fd5b8501601f81018713610f4357600080fd5b803567ffffffffffffffff811115610f5a57600080fd5b876020828401011115610f6c57600080fd5b602091820198909750908601359560400135945092505050565b60005b83811015610fa1578181015183820152602001610f89565b50506000910152565b6020815260008251806020840152610fc9816040850160208701610f86565b601f01601f19169190910160400192915050565b6000808335601e19843603018112610ff457600080fd5b83018035915067ffffffffffffffff82111561100f57600080fd5b60200191503681900382131561102457600080fd5b9250929050565b6000808585111561103b57600080fd5b8386111561104857600080fd5b5050820193919092039150565b80356001600160e01b03198116906004841015611086576001600160e01b0319600485900360031b81901b82161691505b5092915050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156110c6576110c661108d565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156110f5576110f561108d565b604052919050565b600082601f83011261110e57600080fd5b61111860406110cc565b80604084018581111561112a57600080fd5b845b8181101561114457803584526020938401930161112c565b509095945050505050565b600061010082840312801561116357600080fd5b50600061116e6110a3565b61117885856110fd565b815284605f850112611188578182fd5b6040611193816110cc565b8060c08701888111156111a4578586fd5b6040880195505b808610156111ce576111bd89876110fd565b8352948301946020909201916111ab565b8160208601526111de89826110fd565b60408601525092979650505050505050565b8060005b60028110156107f75781518452602093840193909101906001016111f4565b6101a0810161122282876111f0565b604082018560005b60028110156112545761123e8383516111f0565b604092909201916020919091019060010161122a565b50505061126460c08301856111f0565b61010082018360005b600581101561128c57815183526020928301929091019060010161126d565b50505095945050505050565b6000602082840312156112aa57600080fd5b81518015158114610e8657600080fd5b634e487b7160e01b600052602160045260246000fd5b6000602082840312156112e257600080fd5b5051919050565b600082516112fb818460208701610f86565b919091019291505056fea26469706673582212203fe49f9ecb25f4bac5624cea644bc0c051f88ccf9b48840b01228b1ba42c215d64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
8b6dcf11d463ac455361b41fb3ed053febb817491bdea00fdb340e45013b852e05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e
-----Decoded View---------------
Arg [0] : control_root (bytes32): 0x8b6dcf11d463ac455361b41fb3ed053febb817491bdea00fdb340e45013b852e
Arg [1] : bn254_control_id (bytes32): 0x05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 8b6dcf11d463ac455361b41fb3ed053febb817491bdea00fdb340e45013b852e
Arg [1] : 05a022e1db38457fb510bc347b30eb8f8cf3eda95587653d0eac19e1f10d164e
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.