账户
0xEe...d3E6
POP

POP

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.15+commit.e14f2714
语言
Solidity
合同源代码
文件 1 的 15:Address.sol
合同源代码
文件 2 的 15:Context.sol
合同源代码
文件 3 的 15:ERC1155.sol
合同源代码
文件 4 的 15:ERC1155Supply.sol
合同源代码
文件 5 的 15:ERC165.sol
合同源代码
文件 6 的 15:EnumerableSet.sol
合同源代码
文件 7 的 15:IERC1155.sol
合同源代码
文件 8 的 15:IERC1155MetadataURI.sol
合同源代码
文件 9 的 15:IERC1155Receiver.sol
合同源代码
文件 10 的 15:IERC165.sol
合同源代码
文件 11 的 15:IERC721.sol
合同源代码
文件 12 的 15:Mintable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/utils/structs/EnumerableSet.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an minter) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the minter account will be the one that deploys the contract. This
 * can later be changed with {setMinter}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyMinter`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Mintable is Ownable {
    using EnumerableSet for EnumerableSet.AddressSet;
    // Track registered minters
    EnumerableSet.AddressSet private _minters;

    /**
     * @dev Initializes the contract setting the deployer as the initial minter.
     */
    constructor() {
    }

    /**
     * @dev Returns the address of the current minters.
     */
    function getMinters() external view returns (address[] memory minters) {
        minters = new address[](_minters.length());
        for (uint i = 0; i < _minters.length(); i++) {
            minters[i] = _minters.at(i);
        }
        return minters;
    }

    /**
     * @dev Throws if called by any account other than the Minter.
     */
    modifier onlyMinter() {
        require(owner() == _msgSender() || _minters.contains(msg.sender), "Mintable: caller is not the owner or minter");
        _;
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function addMinter(address newMinter) external virtual onlyOwner {
        require(newMinter != address(0), "Mintable: new minter is the zero address.");
        require(!_minters.contains(newMinter),"Mintable: Minter already exists.");
        _addMinter(newMinter);
    }
    
    /**
     * @dev Revoke a minter
     */
    function revokeMinter(address minter) external onlyOwner {
        if (_minters.contains(minter)) {
            _minters.remove(minter);
        }
    }

    function _addMinter(address newMinter) private {
        _minters.add(newMinter);
    }
}
合同源代码
文件 13 的 15:MovieTicket.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/utils/Strings.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/token/ERC721/IERC721.sol";
import "./library/Mintable.sol";

/**
 * @title CalladitaTickets contract
 * @author @FrankNFT.eth
 */
contract CalladitaTickets is ERC1155Supply, Mintable {
    using Strings for uint256;

    uint256 public constant POPCORN_TOKEN_MAX_SUPPLY = 100000;
    uint256 public constant MOVIE_TOKEN_MAX_SUPPLY = 20000;
    uint256 public constant MOVIE_TOKEN_ID = 0;
    uint256 public constant PORNCORN_TOKEN_ID = 1;
    uint256 public tokenPrice = 0.02 ether; 
    uint256 public teamWithdraw;
    uint256 public cyberWithdraw;  
    uint256 public totalWithdraw;

    uint public constant MAX_PURCHASE = 26; // set 1 to high to avoid some gas

    address private constant TEAM = 0xd105eA47f73A120Fd2EfE1151E73231A0f9445FD;
    address private constant CYBER = 0xA422bfFF5dABa6eeeFAFf84Debf609Edf0868C5f;
    address private constant MOVIE = 0x1Bb96B19858b12d91B8512580147A03cCa62C29e;

    bool public saleIsActive;

    IERC721 calladita;

    mapping(uint256 => bool) private tokenUsed;

    event priceChange(address _by, uint256 price);

    constructor() ERC1155("ipfs://QmSyt9T8Gsxt4so2zcB5sCMjzQhfhs9vmo3whLhNawKfWX/") {
        // ERC721's we interact with (mainnet)
        calladita = IERC721(0xdCb68d47423d244319a5101eAe78716AffBa8655);
    }

    /**
     * Pause sale if active, make active if paused
     */
    function flipSaleState() external onlyMinter {
        saleIsActive = !saleIsActive;
    }

    /**
    *  @dev set contract 
    */
    function setContract(address token) external onlyMinter {
        calladita = IERC721(token);
    }

    /**
    * @dev Set new baseURI
    */
    function setURI(string memory newuri) external onlyMinter {
        _setURI(newuri);
    }

        /**     
    * Set price 
    */
    function setPrice(uint256 price) external onlyMinter {
        tokenPrice = price;
        emit priceChange(msg.sender, tokenPrice);
    }

    /**
     * @dev Removing the token substituion and replacing it with the implementation of the ERC721
     */
    function uri(uint256 token) public view virtual override returns (string memory) {
        string memory baseURI = super.uri(token);
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, token.toString())) : "";
    }

    /**
     * @dev airdrop a specific token to a list of addresses
     */
    function airdrop(address[] calldata addresses, uint256 token, uint numberOfTokens) external onlyMinter {
        if (token==0){
            require(totalSupply(MOVIE_TOKEN_ID) + numberOfTokens <= MOVIE_TOKEN_MAX_SUPPLY, "Reserve would exceed max supply of Tokens");
        }else{
            require(totalSupply(POPCORN_TOKEN_MAX_SUPPLY) + numberOfTokens <= POPCORN_TOKEN_MAX_SUPPLY, "Reserve would exceed max supply of Tokens");
        }
        uint length = addresses.length;
        for (uint i=0; i < length;) {
            _mint(addresses[i], token, numberOfTokens, "");
            unchecked{ i++;}
        }
    }

    modifier mintConditions (uint numberOfTokens) {
        require(saleIsActive,"Sale NOT active yet");
        require(numberOfTokens != 0, "numberOfNfts cannot be 0");
        require(numberOfTokens < MAX_PURCHASE, "Can only mint 25 tokens at a time");
        require(totalSupply(MOVIE_TOKEN_ID) + numberOfTokens <= MOVIE_TOKEN_MAX_SUPPLY, "Purchase would exceed max supply of Tokens");
        _;
    }

    function mintWithCaladita(uint[] calldata tokenIds) external mintConditions(tokenIds.length){
        uint amount;
        uint length = tokenIds.length;
        for (uint i=0; i < length;) {
            if (!tokenUsed[tokenIds[i]] && calladita.ownerOf(tokenIds[i])==msg.sender){ 
                tokenUsed[tokenIds[i]]=true;
                unchecked{ amount++;}
            }
            unchecked{ i++;}
        }
        _mint(msg.sender, MOVIE_TOKEN_ID, amount, "");
        _mint(msg.sender, PORNCORN_TOKEN_ID, 10*tokenIds.length, "");
    }

    function mintWithPopcorn(uint numberOfTokens) external payable mintConditions(numberOfTokens){
        require(balanceOf(msg.sender,PORNCORN_TOKEN_ID)>=numberOfTokens,"not enough popcorn");
        require(tokenPrice * numberOfTokens <= msg.value, "Ether value sent is not correct");  
        _mint(msg.sender, MOVIE_TOKEN_ID, numberOfTokens, "");
        _burn(msg.sender, PORNCORN_TOKEN_ID, numberOfTokens);
        _mintEligiblePOPCORN(msg.sender,numberOfTokens);
        totalWithdraw += msg.value;
        if(totalWithdraw>240 ether){
            teamWithdraw += msg.value*15/100;
            cyberWithdraw += msg.value*15/100;
        }else{
            teamWithdraw+= msg.value*5/100;
        }
    }

    function calladitaUsed(uint id) external view returns (bool){
        return tokenUsed[id];
    }

    function _mintEligiblePOPCORN(address mintTo, uint multiplier) internal {
        if (totalSupply(PORNCORN_TOKEN_ID) > POPCORN_TOKEN_MAX_SUPPLY-1){
            return;
        }
        if (totalSupply(MOVIE_TOKEN_ID) < 3000) {
            _mint(mintTo, PORNCORN_TOKEN_ID, 5*multiplier, "");
        }
        else if (totalSupply(MOVIE_TOKEN_ID)  < 5000) {
            _mint(mintTo, PORNCORN_TOKEN_ID, 3*multiplier, "");
        }
        else if (totalSupply(MOVIE_TOKEN_ID)  < 10000) {
            _mint(mintTo, PORNCORN_TOKEN_ID, 2*multiplier, "");
        }
        else if (totalSupply(MOVIE_TOKEN_ID)  < 15000){
            _mint(mintTo, PORNCORN_TOKEN_ID, 1, "");
        }
    }

    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        require(balance > 0, "Insufficent balance");
        _withdraw(TEAM, teamWithdraw);
        _withdraw(CYBER, cyberWithdraw);
        _withdraw(MOVIE, address(this).balance);
        teamWithdraw=0;
        cyberWithdraw=0;
    }

        /** 
     * @dev calladitaInWallet
     * @return tokens id owned by the given address
     * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first.
     * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
     */
    function calladitaInWallet(address _owner) external view returns (uint256[] memory){
        uint256 ownerTokenCount = calladita.balanceOf(_owner);
        uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
        uint256 currentTokenId = 0;
        uint256 ownedTokenIndex = 0;

        while ( ownedTokenIndex < ownerTokenCount && currentTokenId < 2412 ) { /// MAGIC number is the calladita max token count
            if (_caladitaSafeOwnerOf(currentTokenId) == _owner) {
                ownedTokenIds[ownedTokenIndex] = currentTokenId;
                unchecked{ ownedTokenIndex++;}
            }
            unchecked{ currentTokenId++;}
        }
        return ownedTokenIds;
    }

    function _caladitaSafeOwnerOf(uint256 tokenId) private view returns (address owner){
        try calladita.ownerOf(tokenId) returns (address v) {
            return v;
        } catch (bytes memory /*lowLevelData*/) {
            return address(0);
        }
    }

    ///////////// Add name and symbol for etherscan /////////////////
    function name() public pure returns (string memory) {
        return "Calladita Movie Tickets";
    }

    function symbol() public pure returns (string memory) {
        return "POP";
    }

    /**
    * Helper method to allow ETH withdraws.
    */
    function _withdraw(address _address, uint256 _amount) internal {
        (bool success, ) = _address.call{ value: _amount }("");
        require(success, "Failed to widthdraw Ether");
    }

    // contract can recieve Ether
    receive() external payable { 
        totalWithdraw += msg.value;
        if(totalWithdraw>240 ether){
            teamWithdraw += msg.value*15/100;
            cyberWithdraw += msg.value*15/100;
        }else{
            teamWithdraw+= msg.value*5/100;
        }
    }
}
合同源代码
文件 14 的 15:Ownable.sol
合同源代码
文件 15 的 15:Strings.sol
设置
{
  "compilationTarget": {
    "contracts/MovieTicket.sol": "CalladitaTickets"
  },
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "remappings": []
}
ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_by","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"priceChange","type":"event"},{"inputs":[],"name":"MAX_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MOVIE_TOKEN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MOVIE_TOKEN_MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POPCORN_TOKEN_MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PORNCORN_TOKEN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newMinter","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"calladitaInWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"calladitaUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cyberWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getMinters","outputs":[{"internalType":"address[]","name":"minters","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"mintWithCaladita","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintWithPopcorn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"revokeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"teamWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"token","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]