MATIC Price: $0.99 (-2.35%)
Gas: 241 GWei
 

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 MATIC

MATIC Value

$0.00

Token Holdings

Sponsored

Transaction Hash
Method
Block
From
To
Value
Select Contest W...193201922021-09-20 18:34:13920 days ago1632162853IN
0x78F3577E...fA753E6c7
0 MATIC0.0022390225
Select Contest W...193200482021-09-20 18:28:13920 days ago1632162493IN
0x78F3577E...fA753E6c7
0 MATIC0.0026868330
Select Contest W...193197512021-09-20 18:14:47920 days ago1632161687IN
0x78F3577E...fA753E6c7
0 MATIC0.0587102220
Set Tickets Numb...193197292021-09-20 18:13:59920 days ago1632161639IN
0x78F3577E...fA753E6c7
0 MATIC0.000131431.344
Set Participants...193195942021-09-20 18:09:21920 days ago1632161361IN
0x78F3577E...fA753E6c7
0 MATIC0.0014401810
Set Participants...193195942021-09-20 18:09:21920 days ago1632161361IN
0x78F3577E...fA753E6c7
0 MATIC0.000776464.662
Get Random Numbe...193194682021-09-20 18:00:45920 days ago1632160845IN
0x78F3577E...fA753E6c7
0 MATIC0.000478643.5
0x60c06040193192992021-09-20 17:54:58920 days ago1632160498IN
 Contract Creation
0 MATIC0.0269450715

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

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

Contract Name:
ContestSelector

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 8 : ContestSelector.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "./external/chainlink/VRFConsumerBase.sol";
import "./external/openzeppelin/EnumerableSet.sol";
import "./abstract/Ownable.sol";
import "./libraries/SafeERC20.sol";

contract ContestSelector is Ownable, VRFConsumerBase {
    using SafeERC20 for IERC20;
    using EnumerableSet for EnumerableSet.UintSet;

    // Contest step

    event ContestWinnerSelected(uint256 timestamp, uint256 contestWinner);

    uint256 public ticketsCount;
    string public participantsListLink;
    string public participantsListSha256;

    EnumerableSet.UintSet private contestWinners;

    bool public contestWinnersSelected = false;
    EnumerableSet.UintSet internal stepsBeforeContestSelection;

    // Chainlink + Randomness

    bytes32 internal keyHash;
    uint256 internal fee;

    uint256 public randomResult;
    uint256 public previousWinnerSeed;

    /**
     * Constructor inherits VRFConsumerBase
     */
    constructor(
        address _vrfCoordinator,
        address _link,
        bytes32 _keyHash,
        uint256 _fee
    )
        Ownable(msg.sender)
        VRFConsumerBase(
            _vrfCoordinator, // VRF Coordinator
            _link // LINK Token
        )
    {
        keyHash = _keyHash;
        fee = _fee; // LINK fee
    }

    /// @notice Allows owner to set the VRF keyHash
    /// @param _keyHash The keyHash to be used by the VRF
    function setKeyHash(bytes32 _keyHash) external onlyOwner {
        keyHash = _keyHash;
    }

    /// @notice Allows owner to set the fee per request required by the VRF
    /// @param _fee The fee to be charged for a request
    function setFee(uint256 _fee) external onlyOwner {
        fee = _fee;
    }

    /**
     * Requests randomness
     */
    function getRandomNumber() public returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - provide LINK to the contract");
        return requestRandomness(keyHash, fee);
    }

    /**
     * Callback function used by VRF Coordinator
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        randomResult = randomness;
        if (!stepsBeforeContestSelection.contains(1)) {
            stepsBeforeContestSelection.add(1);
        }
    }

    function setTicketsNumber(uint256 number) public onlyOwner {
        require(!contestWinnersSelected, "Contest selection performed");
        ticketsCount = number;
        if (!stepsBeforeContestSelection.contains(4)) {
            stepsBeforeContestSelection.add(4);
        }
    }

    function setParticipantsListLink(string memory link) public onlyOwner {
        require(!contestWinnersSelected, "Contest selection performed");
        participantsListLink = link;
        if (!stepsBeforeContestSelection.contains(2)) {
            stepsBeforeContestSelection.add(2);
        }
    }

    function setParticipantsListSha256(string memory sha256Hash) public onlyOwner {
        require(!contestWinnersSelected, "Contest selection performed");
        participantsListSha256 = sha256Hash;
        if (!stepsBeforeContestSelection.contains(3)) {
            stepsBeforeContestSelection.add(3);
        }
    }

    function selectContestWinners(uint256 count) public onlyOwner {
        require(stepsBeforeContestSelection.length() == 4, "Contest: Not all steps performed");
        require(randomResult != 0, "Contest: Chainlink data recheck");
        require((count + contestWinners.length()) <= ticketsCount, "Contest: Outside of ticket range");

        if (previousWinnerSeed == 0) {
            previousWinnerSeed = randomResult;
        }

        for (uint256 i = 0; i < count; i++) {
            uint256 winnerSeed;
            uint256 winnerIndex;

            bool winnerSelected = false;
            uint256 nonce = 0;
            do {
                winnerSeed = uint256(keccak256(abi.encodePacked(previousWinnerSeed, i, nonce)));
                winnerIndex = (winnerSeed % ticketsCount) + 1;
                nonce++;

                winnerSelected = !contestWinners.contains(winnerIndex);
            } while (!winnerSelected);

            contestWinners.add(winnerIndex);
            previousWinnerSeed = winnerSeed;

            emit ContestWinnerSelected(block.timestamp, winnerIndex);
        }

        contestWinnersSelected = true;
    }

    function getContestWinners() external view returns (uint256[] memory) {
        uint256[] memory winners = new uint256[](contestWinners.length());

        for (uint256 i = 0; i < contestWinners.length(); i++) {
            winners[i] = contestWinners.at(i);
        }

        return winners;
    }

    function getContestWinnersInRange(uint256 from, uint256 to) external view returns (uint256[] memory) {
        require(from < to, "Incorrect range");
        require(to < contestWinners.length(), "Incorrect range");

        uint256[] memory winners = new uint256[](to - from + 1);

        for (uint256 i = 0; i <= to - from; i++) {
            winners[i] = contestWinners.at(i + from);
        }

        return winners;
    }

    function recoverErc20(address token) external onlyOwner {
        uint256 amount = IERC20(token).balanceOf(address(this));
        if (amount > 0) {
            IERC20(token).safeTransfer(owner, amount);
        }
    }

    function recover() external onlyOwner {
        payable(owner).transfer(address(this).balance);
    }
}

File 2 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT

// Source: https://github.com/boringcrypto/BoringSolidity/blob/master/contracts/BoringOwnable.sol

pragma solidity ^0.8.4;

abstract contract OwnableData {
    address public owner;
    address public pendingOwner;
}

abstract contract Ownable is OwnableData {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor(address _owner) {
        require(_owner != address(0), "Ownable: zero address");
        owner = _owner;
        emit OwnershipTransferred(address(0), msg.sender);
    }

    /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner.
    /// Can only be invoked by the current `owner`.
    /// @param newOwner Address of the new owner.
    /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.
    function transferOwnership(address newOwner, bool direct) public onlyOwner {
        if (direct) {
            // Checks
            require(newOwner != address(0), "Ownable: zero address");

            // Effects
            emit OwnershipTransferred(owner, newOwner);
            owner = newOwner;
            pendingOwner = address(0);
        } else {
            // Effects
            pendingOwner = newOwner;
        }
    }

    /// @notice Needs to be called by `pendingOwner` to claim ownership.
    function claimOwnership() public {
        address _pendingOwner = pendingOwner;

        // Checks
        require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");

        // Effects
        emit OwnershipTransferred(owner, _pendingOwner);
        owner = _pendingOwner;
        pendingOwner = address(0);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Ownable: caller is not the owner");
        _;
    }
}

File 3 of 8 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {

  function allowance(
    address owner,
    address spender
  )
    external
    view
    returns (
      uint256 remaining
    );

  function approve(
    address spender,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function balanceOf(
    address owner
  )
    external
    view
    returns (
      uint256 balance
    );

  function decimals()
    external
    view
    returns (
      uint8 decimalPlaces
    );

  function decreaseApproval(
    address spender,
    uint256 addedValue
  )
    external
    returns (
      bool success
    );

  function increaseApproval(
    address spender,
    uint256 subtractedValue
  ) external;

  function name()
    external
    view
    returns (
      string memory tokenName
    );

  function symbol()
    external
    view
    returns (
      string memory tokenSymbol
    );

  function totalSupply()
    external
    view
    returns (
      uint256 totalTokensIssued
    );

  function transfer(
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  )
    external
    returns (
      bool success
    );

  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

}

File 4 of 8 : VRFConsumerBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./LinkTokenInterface.sol";

import "./VRFRequestIDBase.sol";

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {
    /**
     * @notice fulfillRandomness handles the VRF response. Your contract must
     * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
     * @notice principles to keep in mind when implementing your fulfillRandomness
     * @notice method.
     *
     * @dev VRFConsumerBase expects its subcontracts to have a method with this
     * @dev signature, and will call it once it has verified the proof
     * @dev associated with the randomness. (It is triggered via a call to
     * @dev rawFulfillRandomness, below.)
     *
     * @param requestId The Id initially returned by requestRandomness
     * @param randomness the VRF output
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual;

    /**
     * @dev In order to keep backwards compatibility we have kept the user
     * seed field around. We remove the use of it because given that the blockhash
     * enters later, it overrides whatever randomness the used seed provides.
     * Given that it adds no security, and can easily lead to misunderstandings,
     * we have removed it from usage and can now provide a simpler API.
     */
    uint256 private constant USER_SEED_PLACEHOLDER = 0;

    /**
     * @notice requestRandomness initiates a request for VRF output given _seed
     *
     * @dev The fulfillRandomness method receives the output, once it's provided
     * @dev by the Oracle, and verified by the vrfCoordinator.
     *
     * @dev The _keyHash must already be registered with the VRFCoordinator, and
     * @dev the _fee must exceed the fee specified during registration of the
     * @dev _keyHash.
     *
     * @dev The _seed parameter is vestigial, and is kept only for API
     * @dev compatibility with older versions. It can't *hurt* to mix in some of
     * @dev your own randomness, here, but it's not necessary because the VRF
     * @dev oracle will mix the hash of the block containing your request into the
     * @dev VRF seed it ultimately uses.
     *
     * @param _keyHash ID of public key against which randomness is generated
     * @param _fee The amount of LINK to send with the request
     *
     * @return requestId unique ID for this request
     *
     * @dev The returned requestId can be used to distinguish responses to
     * @dev concurrent requests. It is passed as the first argument to
     * @dev fulfillRandomness.
     */
    function requestRandomness(bytes32 _keyHash, uint256 _fee) internal returns (bytes32 requestId) {
        LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
        // This is the seed passed to VRFCoordinator. The oracle will mix this with
        // the hash of the block containing this request to obtain the seed/input
        // which is finally passed to the VRF cryptographic machinery.
        uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
        // nonces[_keyHash] must stay in sync with
        // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
        // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
        // This provides protection against the user repeating their input seed,
        // which would result in a predictable/duplicate output, if multiple such
        // requests appeared in the same block.
        nonces[_keyHash] = nonces[_keyHash] + 1;
        return makeRequestId(_keyHash, vRFSeed);
    }

    LinkTokenInterface internal immutable LINK;
    address private immutable vrfCoordinator;

    // Nonces for each VRF key from which randomness has been requested.
    //
    // Must stay in sync with VRFCoordinator[_keyHash][this]
    mapping(bytes32 => uint256) /* keyHash */ /* nonce */
        private nonces;

    /**
     * @param _vrfCoordinator address of VRFCoordinator contract
     * @param _link address of LINK token contract
     *
     * @dev https://docs.chain.link/docs/link-token-contracts
     */
    constructor(address _vrfCoordinator, address _link) {
        vrfCoordinator = _vrfCoordinator;
        LINK = LinkTokenInterface(_link);
    }

    // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
    // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
    // the origin of the call
    function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external {
        require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
        fulfillRandomness(requestId, randomness);
    }
}

File 5 of 8 : VRFRequestIDBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  )
    internal
    pure
    returns (
      uint256
    )
  {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash,
    uint256 _vRFInputSeed
  )
    internal
    pure
    returns (
      bytes32
    )
  {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

File 6 of 8 : EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

File 7 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);

    // EIP 2612
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function nonces(address owner) external view returns (uint256);
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}

File 8 of 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../interfaces/IERC20.sol";

library SafeERC20 {
    function safeSymbol(IERC20 token) internal view returns (string memory) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41));
        return success && data.length > 0 ? abi.decode(data, (string)) : "???";
    }

    function safeName(IERC20 token) internal view returns (string memory) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03));
        return success && data.length > 0 ? abi.decode(data, (string)) : "???";
    }

    function safeDecimals(IERC20 token) internal view returns (uint8) {
        (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567));
        return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
    }

    function safeTransfer(IERC20 token, address to, uint256 amount) internal {
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: Transfer failed");
    }

    function safeTransferFrom(IERC20 token, address from, uint256 amount) internal {
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: TransferFrom failed");
    }
}

Settings
{
  "evmVersion": "berlin",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"contestWinner","type":"uint256"}],"name":"ContestWinnerSelected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contestWinnersSelected","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContestWinners","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"}],"name":"getContestWinnersInRange","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRandomNumber","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"participantsListLink","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"participantsListSha256","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previousWinnerSeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"recoverErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"selectContestWinners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"name":"setKeyHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"link","type":"string"}],"name":"setParticipantsListLink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sha256Hash","type":"string"}],"name":"setParticipantsListSha256","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"setTicketsNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ticketsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"bool","name":"direct","type":"bool"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101825760003560e01c806398544710116100d8578063baa6a1671161008c578063ce74602411610066578063ce74602414610311578063dbdff2c114610319578063e30c39781461032157600080fd5b8063baa6a167146102e3578063c6eb3b02146102f6578063cc8f86221461030957600080fd5b8063aefa214d116100bd578063aefa214d146102a0578063b242e534146102bd578063b95e099e146102d057600080fd5b8063985447101461027a578063a38acf391461028d57600080fd5b806354ffc4e41161013a5780638801f824116101145780638801f8241461020d5780638da5cb5b1461022257806394985ddd1461026757600080fd5b806354ffc4e4146101df57806369fe0e2d146101f2578063830cb3281461020557600080fd5b80634568b70f1161016b5780634568b70f146101ac5780634847313f146101cc5780634e71e0c8146101d557600080fd5b80631644e7af1461018757806342619f66146101a3575b600080fd5b61019060035481565b6040519081526020015b60405180910390f35b610190600d5481565b6101bf6101ba366004611a66565b610341565b60405161019a9190611c14565b610190600e5481565b6101dd6104df565b005b6101dd6101ed366004611a88565b6105f5565b6101dd610200366004611a4d565b610718565b6101bf61079e565b610215610844565b60405161019a9190611c58565b6000546102429073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019a565b6101dd610275366004611a66565b6108d2565b6101dd610288366004611a4d565b61097b565b6101dd61029b366004611a4d565b610a01565b6008546102ad9060ff1681565b604051901515815260200161019a565b6101dd6102cb3660046119f9565b610b10565b6101dd6102de3660046119de565b610cf1565b6101dd6102f1366004611a88565b610e41565b6101dd610304366004611a4d565b610f5f565b610215611261565b6101dd61126e565b610190611336565b6001546102429073ffffffffffffffffffffffffffffffffffffffff1681565b60608183106103b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e636f72726563742072616e6765000000000000000000000000000000000060448201526064015b60405180910390fd5b6103bb600661149b565b8210610423576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e636f72726563742072616e6765000000000000000000000000000000000060448201526064016103a8565b600061042f8484611c83565b61043a906001611c6b565b67ffffffffffffffff81111561045257610452611dea565b60405190808252806020026020018201604052801561047b578160200160208202803683370190505b50905060005b61048b8585611c83565b81116104d5576104a661049e8683611c6b565b6006906114a5565b8282815181106104b8576104b8611dbb565b6020908102919091010152806104cd81611d18565b915050610481565b5090505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff16338114610561576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e657260448201526064016103a8565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff9092167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179055600180549091169055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610676576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b60085460ff16156106e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f436f6e746573742073656c656374696f6e20706572666f726d6564000000000060448201526064016103a8565b80516106f690600490602084019061191c565b50610703600960026114b8565b61071557610713600960026114d0565b505b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b600c55565b606060006107ac600661149b565b67ffffffffffffffff8111156107c4576107c4611dea565b6040519080825280602002602001820160405280156107ed578160200160208202803683370190505b50905060005b6107fd600661149b565b81101561083e5761080f6006826114a5565b82828151811061082157610821611dbb565b60209081029190910101528061083681611d18565b9150506107f3565b50919050565b6004805461085190611cca565b80601f016020809104026020016040519081016040528092919081815260200182805461087d90611cca565b80156108ca5780601f1061089f576101008083540402835291602001916108ca565b820191906000526020600020905b8154815290600101906020018083116108ad57829003601f168201915b505050505081565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae01614610971576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c0060448201526064016103a8565b61071382826114dc565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b600b55565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b60085460ff1615610aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f436f6e746573742073656c656374696f6e20706572666f726d6564000000000060448201526064016103a8565b6003819055610b00600960046114b8565b61071557610713600960046114d0565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b8015610cab5773ffffffffffffffffffffffffffffffffffffffff8216610c14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4f776e61626c653a207a65726f2061646472657373000000000000000000000060448201526064016103a8565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808616939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617909155600180549091169055610713565b6001805473ffffffffffffffffffffffffffffffffffffffff84167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015610dda57600080fd5b505afa158015610dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e129190611b57565b90508015610713576000546107139073ffffffffffffffffffffffffffffffffffffffff848116911683611502565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ec2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b60085460ff1615610f2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f436f6e746573742073656c656374696f6e20706572666f726d6564000000000060448201526064016103a8565b8051610f4290600590602084019061191c565b50610f4f600960036114b8565b61071557610713600960036114d0565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fe0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b610fea600961149b565b600414611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f436f6e746573743a204e6f7420616c6c20737465707320706572666f726d656460448201526064016103a8565b600d546110bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f436f6e746573743a20436861696e6c696e6b2064617461207265636865636b0060448201526064016103a8565b6003546110c9600661149b565b6110d39083611c6b565b111561113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f436f6e746573743a204f757473696465206f66207469636b65742072616e676560448201526064016103a8565b600e5461114957600d54600e555b60005b81811015611232576000806000805b600e546040805160208101929092528101869052606081018290526080016040516020818303038152906040528051906020012060001c9350600354846111a29190611d51565b6111ad906001611c6b565b9250806111b981611d18565b91506111c890506006846114b8565b159150811561115b576111dc6006846114d0565b50600e84905560408051428152602081018590527f9609566e1c082a791361d8c8d71d92799f593e53bda394598b98f15fc0c5d8d7910160405180910390a150505050808061122a90611d18565b91505061114c565b5050600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6005805461085190611cca565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103a8565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116914780156108fc02929091818181858888f19350505050158015610715573d6000803e3d6000fd5b600c546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000919073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f116906370a082319060240160206040518083038186803b1580156113c257600080fd5b505afa1580156113d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113fa9190611b57565b1015611488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4e6f7420656e6f756768204c494e4b202d2070726f76696465204c494e4b207460448201527f6f2074686520636f6e747261637400000000000000000000000000000000000060648201526084016103a8565b611496600b54600c54611672565b905090565b60006104d9825490565b60006114b18383611812565b9392505050565b600081815260018301602052604081205415156114b1565b60006114b183836118cd565b600d8190556114ed600960016114b8565b610713576114fd600960016114d0565b505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916115999190611bba565b6000604051808303816000865af19150503d80600081146115d6576040519150601f19603f3d011682016040523d82523d6000602084013e6115db565b606091505b50915091508180156116055750805115806116055750808060200190518101906116059190611a30565b61166b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a205472616e73666572206661696c656400000000000060448201526064016103a8565b5050505050565b60007f000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f173ffffffffffffffffffffffffffffffffffffffff16634000aea07f0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0848660006040516020016116ef929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161171c93929190611bd6565b602060405180830381600087803b15801561173657600080fd5b505af115801561174a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061176e9190611a30565b50600083815260026020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a0909101909252815191830191909120938790529190526117ca906001611c6b565b60008581526002602052604090205561180a8482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b949350505050565b815460009082106118a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60448201527f647300000000000000000000000000000000000000000000000000000000000060648201526084016103a8565b8260000182815481106118ba576118ba611dbb565b9060005260206000200154905092915050565b6000818152600183016020526040812054611914575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104d9565b5060006104d9565b82805461192890611cca565b90600052602060002090601f01602090048101928261194a5760008555611990565b82601f1061196357805160ff1916838001178555611990565b82800160010185558215611990579182015b82811115611990578251825591602001919060010190611975565b5061199c9291506119a0565b5090565b5b8082111561199c57600081556001016119a1565b803573ffffffffffffffffffffffffffffffffffffffff811681146119d957600080fd5b919050565b6000602082840312156119f057600080fd5b6114b1826119b5565b60008060408385031215611a0c57600080fd5b611a15836119b5565b91506020830135611a2581611e19565b809150509250929050565b600060208284031215611a4257600080fd5b81516114b181611e19565b600060208284031215611a5f57600080fd5b5035919050565b60008060408385031215611a7957600080fd5b50508035926020909101359150565b600060208284031215611a9a57600080fd5b813567ffffffffffffffff80821115611ab257600080fd5b818401915084601f830112611ac657600080fd5b813581811115611ad857611ad8611dea565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b1e57611b1e611dea565b81604052828152876020848701011115611b3757600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215611b6957600080fd5b5051919050565b60008151808452611b88816020860160208601611c9a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251611bcc818460208701611c9a565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611c0b6060830184611b70565b95945050505050565b6020808252825182820181905260009190848201906040850190845b81811015611c4c57835183529284019291840191600101611c30565b50909695505050505050565b6020815260006114b16020830184611b70565b60008219821115611c7e57611c7e611d8c565b500190565b600082821015611c9557611c95611d8c565b500390565b60005b83811015611cb5578181015183820152602001611c9d565b83811115611cc4576000848401525b50505050565b600181811c90821680611cde57607f821691505b6020821081141561083e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611d4a57611d4a611d8c565b5060010190565b600082611d87577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b801515811461071557600080fdfea2646970667358221220f191d0efd5b3155f912e60edc7c4feca4fdca374be14876d587de6b531f8c4f864736f6c63430008060033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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