EthereumEthereum
0xaD...517A
Eternal Royals Official

Eternal Royals Official

RYLS

收藏品
底价
0.0019 ETH
$2,345.34
大小
9,198
收藏品
所有者
2,173
24% 独特的所有者
此合同的源代码已经过验证!
合同元数据
编译器
0.8.7+commit.e28d00a7
语言
Solidity
合同源代码
文件 1 的 13:Address.sol
合同源代码
文件 2 的 13:Context.sol
合同源代码
文件 3 的 13:ERC165.sol
合同源代码
文件 4 的 13:ERC721.sol
合同源代码
文件 5 的 13:EternalRoyals.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

    interface IMerkleDistributor {
       // function token() external view returns (address);
        // Returns the merkle root of the merkle tree containing account balances available to claim.
        function merkleRoot() external view returns (bytes32);
    }

    import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
    import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol';
    import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol';
    import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

    contract ETRY is IMerkleDistributor,ERC721, Ownable, ReentrancyGuard{
        uint256 public constant MINT_PRICE = 70000000000000000;
        uint public REMAINING_SUPPLY = 9224;
        bool MINTING_ALLOWED = true;
        bool PRESALE_ONLY = true;
        uint PRESALE_TOKEN_MAXIMUM_AMOUNT = 10;
        uint WALLET_TOKEN_MAXIMUM_AMOUNT = 10;
        uint MINTING_STAGE = 1;
        
        using Strings for uint256;
        address FUNDS_RECIPIENT = 0x16583250954Ff09EF3adBa9Cc6c94d883D26465e;
        
        //address public  override token;
        bytes32 public  override merkleRoot;

        // Optional mapping for token URIs
        mapping (uint256 => string) private _tokenURIs;
        mapping(uint256 => uint256) claimedMints;

        // Base URI
        string private _baseURIextended;
        uint private counter = 0;
   
        constructor( string memory _name, string memory _symbol, bytes32 merkleRoot_ )
            ERC721(_name, _symbol){
                merkleRoot = merkleRoot_;
        }
        
        
        function markMint(uint256 index, uint256 amount) internal{
            if (claimedMints[index]!= 0){
                claimedMints[index] = claimedMints[index] + amount;
            } else {
              claimedMints[index] = amount;     
            }
           
        }
        /*
         * Stop minting. This function should just be used by the owner
         */
        function stopMinting() public onlyOwner(){
            MINTING_ALLOWED = false;
        }
    
        /*
         * Start minting. This function should just be used by the owner
         */
        function startMinting() public onlyOwner(){
            MINTING_ALLOWED = true;
        }
        
        //Set the MerkleProofRoot
        function changeMerkleProofRoot( bytes32 merkleRoot_ ) external onlyOwner() {
            merkleRoot = merkleRoot_;
        }
        
        //Internal function to verify merkleProof
         function verify(uint256 index, address account, uint stage, bytes32[] calldata merkleProof) internal {
           // Verify the merkle proof.
          bytes32 node = keccak256(abi.encodePacked(index, account, stage));
          require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');
         }
         
         
          function contractURI() public  view returns (string memory) {
            return _baseURI();
          }
    

        
        function _baseURI() internal view virtual override returns (string memory) {
            return _baseURIextended;
        }
        
        
        /*
         * Owner can withdraw the contract's ETH to an external address
         */
        function withdrawETH( address ethAddress, uint amount) public onlyOwner(){
            payable(ethAddress).transfer(amount);
        }
        
        function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
            require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

            string memory _tokenURI = _tokenURIs[tokenId];
            string memory base = _baseURI();
            
            // If there is no base URI, return the token URI.
            if (bytes(base).length == 0) {
                return _tokenURI;
            }
            // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
            if (bytes(_tokenURI).length > 0) {
                return string(abi.encodePacked(base, _tokenURI));
            }
            // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
            return string(abi.encodePacked(base, tokenId.toString()));
        }
        
         /*
          * Mint function
          */
         function mintByOwner(uint256 _amount,address recipient) public  onlyOwner() {
               uint index = counter;
               uint lastIndex = counter + _amount;
               for (uint _index = index;_index < lastIndex;_index++ ){
                  _mint(recipient, _index+1);
                  _setTokenURI(_index+1, Strings.toString(_index+1));
                  counter++;
                  REMAINING_SUPPLY--;
               }
        }
        
         
         /*
          * Mint function
          */
         function mint(uint256 _amount, uint256 merketree_index,bytes32[] calldata merkleProof, uint stage) public payable nonReentrant() {
           require(MINTING_ALLOWED, "Minting is not allowed");
           require(_amount <= REMAINING_SUPPLY,"There are not this many tokens left");
           require(_amount <= 10,"10 Tokens is the limit per transaction");
            
           if (PRESALE_ONLY){
               require(MINTING_STAGE >= stage, "Address not allowed in this stage");
               verify(merketree_index,msg.sender, stage, merkleProof);
               require(claimedMints[merketree_index]+_amount <=PRESALE_TOKEN_MAXIMUM_AMOUNT, "User already minted 10 times");
              
            }
               
             uint256 totalCost = getMintingCost(_amount);
              require(msg.value >= totalCost,"Insufficient Gas.");
             
               uint index = counter;
               uint lastIndex = counter + _amount;
               for (uint _index = index;_index < lastIndex;_index++ ){
                  _mint(msg.sender, _index+1);
                  _setTokenURI(_index+1, Strings.toString(_index+1));
                  counter++;
                  REMAINING_SUPPLY--;
               }
               if (PRESALE_ONLY){
                   markMint(merketree_index,_amount);
               }
           
             // payable(FUNDS_RECIPIENT).send(totalCost);
               // send the funds
         }
        
           //Return minting cost
          function getMintingCost(uint totalItems)
            private
            pure
            returns (uint256)
          {
            return totalItems * MINT_PRICE;
          }
 
     function totalTokensMinted() public view returns(uint){
        return counter;
    }
    
     function totalSupply() public view returns(uint){
        return 9224;
    }
    
      function preSaleFlag() public view returns(bool){
        return PRESALE_ONLY;
    }
    
    
    function enablePresale() external onlyOwner() {
            PRESALE_ONLY = true;
    }
    
    function disablePresale() external onlyOwner() {
            PRESALE_ONLY = false;
    }
        
        
    function setMintingStage(uint stage) external onlyOwner() {
            MINTING_STAGE = stage;
    }
    
      function remainingSupply() public view returns(uint){
        return REMAINING_SUPPLY;
    }
            //Set the Base URI
    function setBaseURI(string memory baseURI_) external onlyOwner() {
            _baseURIextended = baseURI_;
        }
        
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
            require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
            _tokenURIs[tokenId] = _tokenURI;
    }
    
}
合同源代码
文件 6 的 13:IERC165.sol
合同源代码
文件 7 的 13:IERC721.sol
合同源代码
文件 8 的 13:IERC721Metadata.sol
合同源代码
文件 9 的 13:IERC721Receiver.sol
合同源代码
文件 10 的 13:MerkleProof.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        bytes32 computedHash = leaf;

        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];

            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }

        // Check if the computed hash (root) is equal to the provided root
        return computedHash == root;
    }
}
合同源代码
文件 11 的 13:Ownable.sol
合同源代码
文件 12 的 13:ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}
合同源代码
文件 13 的 13:Strings.sol
设置
{
  "compilationTarget": {
    "contracts/EternalRoyals.sol": "ETRY"
  },
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REMAINING_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"changeMerkleProofRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disablePresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enablePresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"merketree_index","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"stage","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mintByOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preSaleFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remainingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stage","type":"uint256"}],"name":"setMintingStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopMinting","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":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ethAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"}]