Sepolia Testnet

Contract

0xCc46b186bD4515Fa996AdF3c40344Ed7D546A65b

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x6080604076201712025-02-01 22:28:1280 days ago1738448892  Contract Creation0 ETH
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x6351Df4E...c1332a716
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
RollupL1DAValidator

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 5 : RollupL1DAValidator.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IL1DAValidator, L1DAValidatorOutput} from "./IL1DAValidator.sol";

import {CalldataDA} from "./CalldataDA.sol";

import {PubdataSource, BLS_MODULUS, PUBDATA_COMMITMENT_SIZE, PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET, PUBDATA_COMMITMENT_COMMITMENT_OFFSET, BLOB_DA_INPUT_SIZE, POINT_EVALUATION_PRECOMPILE_ADDR} from "./DAUtils.sol";

import {InvalidPubdataSource, PubdataCommitmentsEmpty, InvalidPubdataCommitmentsSize, BlobHashCommitmentError, EmptyBlobVersionHash, NonEmptyBlobVersionHash, PointEvalCallFailed, PointEvalFailed, BlobCommitmentNotPublished} from "./DAContractsErrors.sol";

uint256 constant BLOBS_SUPPORTED = 6;

/// @dev The number of blocks within each we allow blob to be used for DA.
/// On Ethereum blobs expire within 4096 epochs, i.e. 4096 * 32 blocks. We reserve
/// half of the time in order to ensure reader's ability to read the blob's content.
uint256 constant BLOB_EXPIRATION_BLOCKS = (4096 * 32) / 2;

contract RollupL1DAValidator is IL1DAValidator, CalldataDA {
    /// @notice The published blob commitments. Note, that the correctness of blob commitment with relation to the linear hash
    /// is *not* checked in this contract, but is expected to be checked at the verification stage of the ZK contract.
    mapping(bytes32 blobCommitment => uint256 blockOfPublishing) public publishedBlobCommitments;

    /// @notice Publishes certain blobs, marking commitments to them as published.
    /// @param _pubdataCommitments The commitments to the blobs to be published.
    /// `_pubdataCommitments` is a packed list of commitments of the following format:
    /// opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)
    function publishBlobs(bytes calldata _pubdataCommitments) external {
        if (_pubdataCommitments.length == 0) {
            revert PubdataCommitmentsEmpty();
        }
        if (_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE != 0) {
            revert InvalidPubdataCommitmentsSize();
        }

        uint256 versionedHashIndex = 0;
        // solhint-disable-next-line gas-length-in-loops
        for (uint256 i = 0; i < _pubdataCommitments.length; i += PUBDATA_COMMITMENT_SIZE) {
            bytes32 blobCommitment = _getPublishedBlobCommitment(
                versionedHashIndex,
                _pubdataCommitments[i:i + PUBDATA_COMMITMENT_SIZE]
            );
            publishedBlobCommitments[blobCommitment] = block.number;
            ++versionedHashIndex;
        }
    }

    function isBlobAvailable(bytes32 _blobCommitment) public view returns (bool) {
        uint256 blockOfPublishing = publishedBlobCommitments[_blobCommitment];

        // While `block.number` on all used L1 networks is much higher than `BLOB_EXPIRATION_BLOCKS`,
        // we still check that `blockOfPublishing > 0` just in case.
        return blockOfPublishing > 0 && block.number - blockOfPublishing <= BLOB_EXPIRATION_BLOCKS;
    }

    /// @inheritdoc IL1DAValidator
    function checkDA(
        uint256, // _chainId
        uint256, // _batchNumber
        bytes32 _l2DAValidatorOutputHash,
        bytes calldata _operatorDAInput,
        uint256 _maxBlobsSupported
    ) external view returns (L1DAValidatorOutput memory output) {
        (
            bytes32 stateDiffHash,
            bytes32 fullPubdataHash,
            bytes32[] memory blobsLinearHashes,
            uint256 blobsProvided,
            bytes calldata l1DaInput
        ) = _processL2RollupDAValidatorOutputHash(_l2DAValidatorOutputHash, _maxBlobsSupported, _operatorDAInput);

        uint8 pubdataSource = uint8(l1DaInput[0]);
        bytes32[] memory blobCommitments;

        if (pubdataSource == uint8(PubdataSource.Blob)) {
            blobCommitments = _processBlobDA(blobsProvided, _maxBlobsSupported, l1DaInput[1:]);
        } else if (pubdataSource == uint8(PubdataSource.Calldata)) {
            (blobCommitments, ) = _processCalldataDA(blobsProvided, fullPubdataHash, _maxBlobsSupported, l1DaInput[1:]);
        } else {
            revert InvalidPubdataSource(pubdataSource);
        }

        // We verify that for each set of blobHash/blobCommitment are either both empty
        // or there are values for both.
        // This is mostly a sanity check and it is not strictly required.
        for (uint256 i = 0; i < _maxBlobsSupported; ++i) {
            if (
                (blobsLinearHashes[i] == bytes32(0) && blobCommitments[i] != bytes32(0)) ||
                (blobsLinearHashes[i] != bytes32(0) && blobCommitments[i] == bytes32(0))
            ) {
                revert BlobHashCommitmentError(i, blobsLinearHashes[i] == bytes32(0), blobCommitments[i] == bytes32(0));
            }
        }

        output.stateDiffHash = stateDiffHash;
        output.blobsLinearHashes = blobsLinearHashes;
        output.blobsOpeningCommitments = blobCommitments;
    }

    /// @notice Generated the blob commitemnt to be used in the cryptographic proof by calling the point evaluation precompile.
    /// @param _index The index of the blob in this transaction.
    /// @param _commitment The packed: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes
    /// @return The commitment to be used in the cryptographic proof.
    function _getPublishedBlobCommitment(uint256 _index, bytes calldata _commitment) internal view returns (bytes32) {
        bytes32 blobVersionedHash = _getBlobVersionedHash(_index);

        if (blobVersionedHash == bytes32(0)) {
            revert EmptyBlobVersionHash(_index);
        }

        // First 16 bytes is the opening point. While we get the point as 16 bytes, the point evaluation precompile
        // requires it to be 32 bytes. The blob commitment must use the opening point as 16 bytes though.
        bytes32 openingPoint = bytes32(
            uint256(uint128(bytes16(_commitment[:PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET])))
        );

        _pointEvaluationPrecompile(
            blobVersionedHash,
            openingPoint,
            _commitment[PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET:PUBDATA_COMMITMENT_SIZE]
        );

        // Take the hash of the versioned hash || opening point || claimed value
        return keccak256(abi.encodePacked(blobVersionedHash, _commitment[:PUBDATA_COMMITMENT_COMMITMENT_OFFSET]));
    }

    /// @notice Verify that the blob DA was correctly provided.
    /// @param _blobsProvided The number of blobs provided.
    /// @param _maxBlobsSupported Maximum number of blobs supported.
    /// @param _operatorDAInput Input used to verify that the blobs contain the data we expect.
    function _processBlobDA(
        uint256 _blobsProvided,
        uint256 _maxBlobsSupported,
        bytes calldata _operatorDAInput
    ) internal view returns (bytes32[] memory blobsCommitments) {
        blobsCommitments = new bytes32[](_maxBlobsSupported);

        // For blobs we expect to receive the commitments in the following format:
        // 144 bytes for commitment data
        // 32 bytes for the prepublished commitment. If it is non-zero, it means that it is expected that
        // such commitment was published before. Otherwise, it is expected that it is published in this transaction
        if (_operatorDAInput.length != _blobsProvided * BLOB_DA_INPUT_SIZE) {
            revert InvalidPubdataCommitmentsSize();
        }

        uint256 versionedHashIndex = 0;

        // we iterate over the `_operatorDAInput`, while advancing the pointer by `BLOB_DA_INPUT_SIZE` each time
        for (uint256 i = 0; i < _blobsProvided; ++i) {
            bytes calldata commitmentData = _operatorDAInput[:PUBDATA_COMMITMENT_SIZE];
            bytes32 prepublishedCommitment = bytes32(_operatorDAInput[PUBDATA_COMMITMENT_SIZE:BLOB_DA_INPUT_SIZE]);

            if (prepublishedCommitment != bytes32(0)) {
                // We double check that this commitment has indeed been published.
                // If that is the case, we do not care about the actual underlying data.
                if (!isBlobAvailable(prepublishedCommitment)) {
                    revert BlobCommitmentNotPublished();
                }
                blobsCommitments[i] = prepublishedCommitment;
            } else {
                blobsCommitments[i] = _getPublishedBlobCommitment(versionedHashIndex, commitmentData);
                ++versionedHashIndex;
            }

            // Advance the pointer
            _operatorDAInput = _operatorDAInput[BLOB_DA_INPUT_SIZE:];
        }

        // This check is required because we want to ensure that there aren't any extra blobs trying to be published.
        // Calling the BLOBHASH opcode with an index > # blobs - 1 yields bytes32(0)
        bytes32 versionedHash = _getBlobVersionedHash(versionedHashIndex);
        if (versionedHash != bytes32(0)) {
            revert NonEmptyBlobVersionHash(versionedHashIndex);
        }
    }

    /// @notice Calls the point evaluation precompile and verifies the output
    /// Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.
    /// Also verify that the provided commitment matches the provided versioned_hash.
    ///
    function _pointEvaluationPrecompile(
        bytes32 _versionedHash,
        bytes32 _openingPoint,
        bytes calldata _openingValueCommitmentProof
    ) internal view {
        bytes memory precompileInput = abi.encodePacked(_versionedHash, _openingPoint, _openingValueCommitmentProof);

        (bool success, bytes memory data) = POINT_EVALUATION_PRECOMPILE_ADDR.staticcall(precompileInput);

        // We verify that the point evaluation precompile call was successful by testing the latter 32 bytes of the
        // response is equal to BLS_MODULUS as defined in https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
        if (!success) {
            revert PointEvalCallFailed(precompileInput);
        }
        (, uint256 result) = abi.decode(data, (uint256, uint256));
        if (result != BLS_MODULUS) {
            revert PointEvalFailed(abi.encode(result));
        }
    }

    function _getBlobVersionedHash(uint256 _index) internal view virtual returns (bytes32 versionedHash) {
        assembly {
            versionedHash := blobhash(_index)
        }
    }
}

File 2 of 5 : IL1DAValidator.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

struct L1DAValidatorOutput {
    /// @dev The hash of the uncompressed state diff.
    bytes32 stateDiffHash;
    /// @dev The hashes of the blobs on L1. The array is dynamic to account for forward compatibility.
    /// The length of it must be equal to `maxBlobsSupported`.
    bytes32[] blobsLinearHashes;
    /// @dev The commitments to the blobs on L1. The array is dynamic to account for forward compatibility.
    /// Its length must be equal to the length of blobsLinearHashes.
    /// @dev If the system supports more blobs than returned, the rest of the array should be filled with zeros.
    bytes32[] blobsOpeningCommitments;
}

interface IL1DAValidator {
    /// @notice The function that checks the data availability for the given batch input.
    /// @param _chainId The chain id of the chain that is being committed.
    /// @param _batchNumber The batch number for which the data availability is being checked.
    /// @param _l2DAValidatorOutputHash The hash of that was returned by the l2DAValidator.
    /// @param _operatorDAInput The DA input by the operator provided on L1.
    /// @param _maxBlobsSupported The maximal number of blobs supported by the chain.
    /// We provide this value for future compatibility.
    /// This is needed because the corresponding `blobsLinearHashes`/`blobsOpeningCommitments`
    /// in the `L1DAValidatorOutput` struct will have to have this length as it is required
    /// to be static by the circuits.
    function checkDA(
        uint256 _chainId,
        uint256 _batchNumber,
        bytes32 _l2DAValidatorOutputHash,
        bytes calldata _operatorDAInput,
        uint256 _maxBlobsSupported
    ) external returns (L1DAValidatorOutput memory output);
}

File 3 of 5 : CalldataDA.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {OperatorDAInputTooSmall, InvalidNumberOfBlobs, InvalidL2DAOutputHash, OnlyOneBlobWithCalldataAllowed, PubdataInputTooSmall, PubdataLengthTooBig, InvalidPubdataHash} from "./DAContractsErrors.sol";

/// @dev Total number of bytes in a blob. Blob = 4096 field elements * 31 bytes per field element
/// @dev EIP-4844 defines it as 131_072 but we use 4096 * 31 within our circuits to always fit within a field element
/// @dev Our circuits will prove that a EIP-4844 blob and our internal blob are the same.
uint256 constant BLOB_SIZE_BYTES = 126_976;

/// @dev The state diff hash, hash of pubdata + the number of blobs.
uint256 constant BLOB_DATA_OFFSET = 65;

/// @dev The size of the commitment for a single blob.
uint256 constant BLOB_COMMITMENT_SIZE = 32;

/// @notice Contract that contains the functionality for process the calldata DA.
/// @dev The expected l2DAValidator that should be used with it `RollupL2DAValidator`.
abstract contract CalldataDA {
    /// @notice Parses the input that the L2 DA validator has provided to the contract.
    /// @param _l2DAValidatorOutputHash The hash of the output of the L2 DA validator.
    /// @param _maxBlobsSupported The maximal number of blobs supported by the chain.
    /// @param _operatorDAInput The DA input by the operator provided on L1.
    function _processL2RollupDAValidatorOutputHash(
        bytes32 _l2DAValidatorOutputHash,
        uint256 _maxBlobsSupported,
        bytes calldata _operatorDAInput
    )
        internal
        pure
        returns (
            bytes32 stateDiffHash,
            bytes32 fullPubdataHash,
            bytes32[] memory blobsLinearHashes,
            uint256 blobsProvided,
            bytes calldata l1DaInput
        )
    {
        // The preimage under the hash `_l2DAValidatorOutputHash` is expected to be in the following format:
        // - First 32 bytes are the hash of the uncompressed state diff.
        // - Then, there is a 32-byte hash of the full pubdata.
        // - Then, there is the 1-byte number of blobs published.
        // - Then, there are linear hashes of the published blobs, 32 bytes each.

        // Check that it accommodates enough pubdata for the state diff hash, hash of pubdata + the number of blobs.
        if (_operatorDAInput.length < BLOB_DATA_OFFSET) {
            revert OperatorDAInputTooSmall(_operatorDAInput.length, BLOB_DATA_OFFSET);
        }

        stateDiffHash = bytes32(_operatorDAInput[:32]);
        fullPubdataHash = bytes32(_operatorDAInput[32:64]);
        blobsProvided = uint256(uint8(_operatorDAInput[64]));

        if (blobsProvided > _maxBlobsSupported) {
            revert InvalidNumberOfBlobs(blobsProvided, _maxBlobsSupported);
        }

        // Note that the API of the contract requires that the returned blobs linear hashes have length of
        // the `_maxBlobsSupported`
        blobsLinearHashes = new bytes32[](_maxBlobsSupported);

        if (_operatorDAInput.length < BLOB_DATA_OFFSET + 32 * blobsProvided) {
            revert OperatorDAInputTooSmall(_operatorDAInput.length, BLOB_DATA_OFFSET + 32 * blobsProvided);
        }

        _cloneCalldata(blobsLinearHashes, _operatorDAInput[BLOB_DATA_OFFSET:], blobsProvided);

        uint256 ptr = BLOB_DATA_OFFSET + 32 * blobsProvided;

        // Now, we need to double check that the provided input was indeed returned by the L2 DA validator.
        if (keccak256(_operatorDAInput[:ptr]) != _l2DAValidatorOutputHash) {
            revert InvalidL2DAOutputHash(_l2DAValidatorOutputHash);
        }

        // The rest of the output was provided specifically by the operator
        l1DaInput = _operatorDAInput[ptr:];
    }

    /// @notice Verify that the calldata DA was correctly provided.
    /// @param _blobsProvided The number of blobs provided.
    /// @param _fullPubdataHash Hash of the pubdata preimage.
    /// @param _maxBlobsSupported Maximum number of blobs supported.
    /// @param _pubdataInput Full pubdata + an additional 32 bytes containing the blob commitment for the pubdata.
    /// @dev We supply the blob commitment as part of the pubdata because even with calldata the prover will check these values.
    function _processCalldataDA(
        uint256 _blobsProvided,
        bytes32 _fullPubdataHash,
        uint256 _maxBlobsSupported,
        bytes calldata _pubdataInput
    ) internal pure virtual returns (bytes32[] memory blobCommitments, bytes calldata _pubdata) {
        if (_blobsProvided != 1) {
            revert OnlyOneBlobWithCalldataAllowed();
        }
        if (_pubdataInput.length < BLOB_COMMITMENT_SIZE) {
            revert PubdataInputTooSmall(_pubdataInput.length, BLOB_COMMITMENT_SIZE);
        }

        // We typically do not know whether we'll use calldata or blobs at the time when
        // we start proving the batch. That's why the blob commitment for a single blob is still present in the case of calldata.

        blobCommitments = new bytes32[](_maxBlobsSupported);

        _pubdata = _pubdataInput[:_pubdataInput.length - BLOB_COMMITMENT_SIZE];

        if (_pubdata.length > BLOB_SIZE_BYTES) {
            revert PubdataLengthTooBig(_pubdata.length, BLOB_SIZE_BYTES);
        }
        if (_fullPubdataHash != keccak256(_pubdata)) {
            revert InvalidPubdataHash(_fullPubdataHash, keccak256(_pubdata));
        }
        blobCommitments[0] = bytes32(_pubdataInput[_pubdataInput.length - BLOB_COMMITMENT_SIZE:_pubdataInput.length]);
    }

    /// @notice Method that clones a slice of calldata into a bytes32[] memory array.
    /// @param _dst The destination array.
    /// @param _input The input calldata.
    /// @param _len The length of the slice in 32-byte words to clone.
    function _cloneCalldata(bytes32[] memory _dst, bytes calldata _input, uint256 _len) internal pure {
        assembly {
            // The pointer to the allocated memory above. We skip 32 bytes to avoid overwriting the length.
            let dstPtr := add(_dst, 0x20)
            let inputPtr := _input.offset
            calldatacopy(dstPtr, inputPtr, mul(_len, 32))
        }
    }
}

File 4 of 5 : DAUtils.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @dev Total number of bytes in a blob. Blob = 4096 field elements * 31 bytes per field element
/// @dev EIP-4844 defines it as 131_072 but we use 4096 * 31 within our circuits to always fit within a field element
/// @dev Our circuits will prove that a EIP-4844 blob and our internal blob are the same.
uint256 constant BLOB_SIZE_BYTES = 126_976;

/// @dev Enum used to determine the source of pubdata. At first we will support calldata and blobs but this can be extended.
enum PubdataSource {
    Calldata,
    Blob
}

/// @dev BLS Modulus value defined in EIP-4844 and the magic value returned from a successful call to the
/// point evaluation precompile
uint256 constant BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513;

/// @dev Packed pubdata commitments.
/// @dev Format: list of: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes
uint256 constant PUBDATA_COMMITMENT_SIZE = 144;

/// @dev Offset in pubdata commitment of blobs for claimed value
uint256 constant PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET = 16;

/// @dev Offset in pubdata commitment of blobs for kzg commitment
uint256 constant PUBDATA_COMMITMENT_COMMITMENT_OFFSET = 48;

/// @dev For each blob we expect that the commitment is provided as well as the marker whether a blob with such commitment has been published before.
uint256 constant BLOB_DA_INPUT_SIZE = PUBDATA_COMMITMENT_SIZE + 32;

/// @dev Address of the point evaluation precompile used for EIP-4844 blob verification.
address constant POINT_EVALUATION_PRECOMPILE_ADDR = address(0x0A);

/// @dev The address of the special smart contract that can send arbitrary length message as an L2 log
address constant L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR = address(0x8008);

File 5 of 5 : DAContractsErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

// 0x53dee67b
error PubdataCommitmentsEmpty();
// 0x53e6d04d
error InvalidPubdataCommitmentsSize();
// 0xafd53e2f
error BlobHashCommitmentError(uint256 index, bool blobHashEmpty, bool blobCommitmentEmpty);
// 0xfc7ab1d3
error EmptyBlobVersionHash(uint256 index);
// 0x92290acc
error NonEmptyBlobVersionHash(uint256 index);
// 0x8d5851de
error PointEvalCallFailed(bytes);
// 0x4daa985d
error PointEvalFailed(bytes);

// 0x885ae069
error OperatorDAInputTooSmall(uint256 operatorDAInputLength, uint256 minAllowedLength);

// 0xbeb96791
error InvalidNumberOfBlobs(uint256 blobsProvided, uint256 maxBlobsSupported);

// 0xd2531c15
error InvalidL2DAOutputHash(bytes32 l2DAValidatorOutputHash);

// 0x04e05fd1
error OnlyOneBlobWithCalldataAllowed();

// 0x2dc9747d
error PubdataInputTooSmall(uint256 pubdataInputLength, uint256 totalBlobsCommitmentSize);

// 0x9044dff9
error PubdataLengthTooBig(uint256 pubdataLength, uint256 totalBlobSizeBytes);

// 0x5513177c
error InvalidPubdataHash(bytes32 fullPubdataHash, bytes32 providedPubdataHash);

// 0xc771423e
error BlobCommitmentNotPublished();

// 0x5717f940
error InvalidPubdataSource(uint8 pubdataSource);
// 0x52595598
error ValL1DAWrongInputLength(uint256 inputLength, uint256 expectedLength);

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "l2-contracts/=../l2-contracts/contracts/",
    "@openzeppelin/=node_modules/@openzeppelin/"
  ],
  "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": {}
}

Contract ABI

API
[{"inputs":[],"name":"BlobCommitmentNotPublished","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"blobHashEmpty","type":"bool"},{"internalType":"bool","name":"blobCommitmentEmpty","type":"bool"}],"name":"BlobHashCommitmentError","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"EmptyBlobVersionHash","type":"error"},{"inputs":[{"internalType":"bytes32","name":"l2DAValidatorOutputHash","type":"bytes32"}],"name":"InvalidL2DAOutputHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"blobsProvided","type":"uint256"},{"internalType":"uint256","name":"maxBlobsSupported","type":"uint256"}],"name":"InvalidNumberOfBlobs","type":"error"},{"inputs":[],"name":"InvalidPubdataCommitmentsSize","type":"error"},{"inputs":[{"internalType":"bytes32","name":"fullPubdataHash","type":"bytes32"},{"internalType":"bytes32","name":"providedPubdataHash","type":"bytes32"}],"name":"InvalidPubdataHash","type":"error"},{"inputs":[{"internalType":"uint8","name":"pubdataSource","type":"uint8"}],"name":"InvalidPubdataSource","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"NonEmptyBlobVersionHash","type":"error"},{"inputs":[],"name":"OnlyOneBlobWithCalldataAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"operatorDAInputLength","type":"uint256"},{"internalType":"uint256","name":"minAllowedLength","type":"uint256"}],"name":"OperatorDAInputTooSmall","type":"error"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"PointEvalCallFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"PointEvalFailed","type":"error"},{"inputs":[],"name":"PubdataCommitmentsEmpty","type":"error"},{"inputs":[{"internalType":"uint256","name":"pubdataInputLength","type":"uint256"},{"internalType":"uint256","name":"totalBlobsCommitmentSize","type":"uint256"}],"name":"PubdataInputTooSmall","type":"error"},{"inputs":[{"internalType":"uint256","name":"pubdataLength","type":"uint256"},{"internalType":"uint256","name":"totalBlobSizeBytes","type":"uint256"}],"name":"PubdataLengthTooBig","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"_l2DAValidatorOutputHash","type":"bytes32"},{"internalType":"bytes","name":"_operatorDAInput","type":"bytes"},{"internalType":"uint256","name":"_maxBlobsSupported","type":"uint256"}],"name":"checkDA","outputs":[{"components":[{"internalType":"bytes32","name":"stateDiffHash","type":"bytes32"},{"internalType":"bytes32[]","name":"blobsLinearHashes","type":"bytes32[]"},{"internalType":"bytes32[]","name":"blobsOpeningCommitments","type":"bytes32[]"}],"internalType":"struct L1DAValidatorOutput","name":"output","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_blobCommitment","type":"bytes32"}],"name":"isBlobAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_pubdataCommitments","type":"bytes"}],"name":"publishBlobs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"blobCommitment","type":"bytes32"}],"name":"publishedBlobCommitments","outputs":[{"internalType":"uint256","name":"blockOfPublishing","type":"uint256"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c80630a8c31f61461004e578063381c3f131461007657806373c58a2d146100965780637b574586146100ab575b5f80fd5b61006161005c366004610a87565b6100d8565b60405190151581526020015b60405180910390f35b610089610084366004610ae3565b610108565b60405161006d9190610b81565b6100a96100a4366004610bcc565b610303565b005b6100ca6100b9366004610a87565b5f6020819052908152604090205481565b60405190815260200161006d565b5f8181526020819052604081205480158015906101015750620100006100fe8243610c1f565b11155b9392505050565b60408051606080820183525f80835260208301829052928201529080808036816101348b898c8c6103b4565b9550955095509550955095505f82825f81811061015357610153610c38565b919091013560f81c9150606090505f19820161018757610180858b61017b866001818a610c4c565b61058e565b90506101d5565b60ff82166101b2576101a785888c6101a2876001818b610c4c565b61072f565b5050809150506101d5565b60405163015c5fe560e61b815260ff831660048201526024015b60405180910390fd5b5f5b8a8110156102e6575f801b8782815181106101f4576101f4610c38565b602002602001015114801561022457505f801b82828151811061021957610219610c38565b602002602001015114155b8061026f57505f801b87828151811061023f5761023f610c38565b60200260200101511415801561026f57505f801b82828151811061026557610265610c38565b6020026020010151145b156102de57805f801b88838151811061028a5761028a610c38565b6020026020010151145f801b8484815181106102a8576102a8610c38565b602090810291909101015160405163afd53e2f60e01b8152600481019490945291151560248401521460448201526064016101cc565b6001016101d7565b509688525050505060208401525060408201529695505050505050565b5f819003610324576040516353dee67b60e01b815260040160405180910390fd5b61032f609082610c73565b1561034d576040516353e6d04d60e01b815260040160405180910390fd5b5f805b828110156103ae575f61037d8386848761036b609083610c92565b9261037893929190610c4c565b6108b8565b5f818152602081905260409020439055905061039883610ca5565b92506103a79050609082610c92565b9050610350565b50505050565b5f80606081368160418710156103e75760405163885ae06960e01b815260048101889052604160248201526044016101cc565b6103f460205f898b610c4c565b6103fd91610cbd565b955061040d60406020898b610c4c565b61041691610cbd565b94508787604081811061042b5761042b610c38565b919091013560f81c935050888311156104615760405163beb9679160e01b815260048101849052602481018a90526044016101cc565b8867ffffffffffffffff81111561047a5761047a610cda565b6040519080825280602002602001820160405280156104a3578160200160208202803683370190505b5093506104b1836020610cee565b6104bc906041610c92565b8710156104fc57866104cf846020610cee565b6104da906041610c92565b60405163885ae06960e01b8152600481019290925260248201526044016101cc565b6105138461050d896041818d610c4c565b86610951565b5f61051f846020610cee565b61052a906041610c92565b90508a610539825f8b8d610c4c565b604051610547929190610d05565b6040518091039020146105705760405163d2531c1560e01b8152600481018c90526024016101cc565b61057c8882818c610c4c565b92509250509499939850945094509450565b60608367ffffffffffffffff8111156105a9576105a9610cda565b6040519080825280602002602001820160405280156105d2578160200160208202803683370190505b5090506105e160906020610c92565b6105eb9086610cee565b821461060a576040516353e6d04d60e01b815260040160405180910390fd5b5f805b8681101561070057365f610624609082888a610c4c565b90925090505f87609088610639826020610c92565b9261064693929190610c4c565b61064f91610cbd565b905080156106a157610660816100d8565b61067d576040516363b8a11f60e11b815260040160405180910390fd5b8086858151811061069057610690610c38565b6020026020010181815250506106d5565b6106ac8584846108b8565b8685815181106106be576106be610c38565b60209081029190910101526106d285610ca5565b94505b87876106e360906020610c92565b6106ee928290610c4c565b9750975050505080600101905061060d565b50804980156107255760405163248a42b360e21b8152600481018390526024016101cc565b5050949350505050565b6060365f87600114610754576040516304e05fd160e01b815260040160405180910390fd5b602084101561078057604051632dc9747d60e01b815260048101859052602060248201526044016101cc565b8567ffffffffffffffff81111561079957610799610cda565b6040519080825280602002602001820160405280156107c2578160200160208202803683370190505b509250845f856107d3602082610c1f565b926107e093929190610c4c565b90925090506201f00081111561081557604051639044dff960e01b8152600481018290526201f00060248201526044016101cc565b8181604051610825929190610d05565b6040518091039020871461086d57868282604051610844929190610d05565b604051908190038120631544c5df60e21b82526101cc9291600401918252602082015260400190565b848461087a602082610c1f565b61088692879290610c4c565b61088f91610cbd565b835f815181106108a1576108a1610c38565b602002602001018181525050955095509592505050565b5f8349806108dc5760405163fc7ab1d360e01b8152600481018690526024016101cc565b5f6108ea6010828688610c4c565b6108f391610d14565b60801c9050610910828261090b60906010898b610c4c565b610965565b8161091e60305f8789610c4c565b60405160200161093093929190610d4d565b60405160208183030381529060405280519060200120925050509392505050565b602084018360208302818337505050505050565b5f8484848460405160200161097d9493929190610d66565b60405160208183030381529060405290505f80600a6001600160a01b0316836040516109a99190610da8565b5f60405180830381855afa9150503d805f81146109e1576040519150601f19603f3d011682016040523d82523d5f602084013e6109e6565b606091505b509150915081610a0b57826040516346ac28ef60e11b81526004016101cc9190610dc3565b5f81806020019051810190610a209190610df5565b9150507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114610a7d5760408051602081018390520160408051601f1981840301815290829052634daa985d60e01b82526101cc91600401610dc3565b5050505050505050565b5f60208284031215610a97575f80fd5b5035919050565b5f8083601f840112610aae575f80fd5b50813567ffffffffffffffff811115610ac5575f80fd5b602083019150836020828501011115610adc575f80fd5b9250929050565b5f805f805f8060a08789031215610af8575f80fd5b863595506020870135945060408701359350606087013567ffffffffffffffff811115610b23575f80fd5b610b2f89828a01610a9e565b979a9699509497949695608090950135949350505050565b5f815180845260208085019450602084015f5b83811015610b7657815187529582019590820190600101610b5a565b509495945050505050565b60208152815160208201525f602083015160606040840152610ba66080840182610b47565b90506040840151601f19848303016060850152610bc38282610b47565b95945050505050565b5f8060208385031215610bdd575f80fd5b823567ffffffffffffffff811115610bf3575f80fd5b610bff85828601610a9e565b90969095509350505050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610c3257610c32610c0b565b92915050565b634e487b7160e01b5f52603260045260245ffd5b5f8085851115610c5a575f80fd5b83861115610c66575f80fd5b5050820193919092039150565b5f82610c8d57634e487b7160e01b5f52601260045260245ffd5b500690565b80820180821115610c3257610c32610c0b565b5f60018201610cb657610cb6610c0b565b5060010190565b80356020831015610c32575f19602084900360031b1b1692915050565b634e487b7160e01b5f52604160045260245ffd5b8082028115828204841417610c3257610c32610c0b565b818382375f9101908152919050565b6fffffffffffffffffffffffffffffffff198135818116916010851015610d455780818660100360031b1b83161692505b505092915050565b838152818360208301375f910160200190815292915050565b848152836020820152818360408301375f91016040019081529392505050565b5f5b83811015610da0578181015183820152602001610d88565b50505f910152565b5f8251610db9818460208701610d86565b9190910192915050565b602081525f8251806020840152610de1816040850160208701610d86565b601f01601f19169190910160400192915050565b5f8060408385031215610e06575f80fd5b50508051602090910151909290915056fea2646970667358221220a6860c6173beda85375a7d9f196a9ff8fc85b903b1b7a47d26e20516789aaf6b64736f6c63430008180033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.