Last active
August 12, 2022 14:41
-
-
Save Qambar/96b52813f46d45d1a6138c15556a70b8 to your computer and use it in GitHub Desktop.
Hashlips contract modified to work with merkle tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: GPL-3.0 | |
// # # # | |
// # # # # #### # ###### # # ## ##### #### # # | |
// # # ## # # # # # # # # # # # # # # # | |
// # # # # # # # ##### # # # # # # # # ###### | |
// # # # # # # # # ####### ###### ##### # # # # | |
// # # # ## # # # # # # # # # # # # # # | |
// ##### # # #### ###### ###### # # # # # # #### # # | |
// Amended by HashLips, improved by Uncle Aaroh ! | |
/** | |
!Disclaimer! | |
These contracts have been used to create tutorials, | |
and was created for the purpose to teach people | |
how to create smart contracts on the blockchain. | |
please review this code on your own before using any of | |
the following code for production. | |
HashLips will not be liable in any way if for the use | |
of the code. That being said, the code has been tested | |
to the best of the developers' knowledge to work as intended. | |
*/ | |
pragma solidity >=0.7.0 <0.9.0; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; | |
contract NFT is ERC721Enumerable, Ownable { | |
using Strings for uint256; | |
string public baseURI; | |
string public baseExtension = ".json"; | |
string public notRevealedUri; | |
uint256 public cost = 1 ether; | |
uint256 public whiteListCost = 0.5 ether; | |
uint256 public maxSupply = 10000; | |
uint256 public maxMintAmount = 20; | |
uint256 public nftPerAddressLimit = 3; | |
bool public paused = false; | |
bool public revealed = false; | |
mapping(address => uint256) public addressMintedBalance; | |
//////// Uncle Aaroh Addition /////// | |
//// Merkle Tree Root Address - Gas Optimisation | |
bytes32 public whitelistMerkleRoot; | |
////////////////// | |
constructor( | |
string memory _name, | |
string memory _symbol, | |
string memory _initBaseURI, | |
string memory _initNotRevealedUri | |
) ERC721(_name, _symbol) { | |
setBaseURI(_initBaseURI); | |
setNotRevealedURI(_initNotRevealedUri); | |
} | |
// internal | |
function _baseURI() internal view virtual override returns (string memory) { | |
return baseURI; | |
} | |
// public | |
function mint(uint256 _mintAmount) public payable { | |
require(!paused, "the contract is paused"); | |
uint256 supply = totalSupply(); | |
require(_mintAmount > 0, "need to mint at least 1 NFT"); | |
require( | |
_mintAmount <= maxMintAmount, | |
"max mint amount per session exceeded" | |
); | |
require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded"); | |
if (msg.sender != owner()) { | |
require(msg.value >= cost * _mintAmount, "insufficient funds"); | |
} | |
for (uint256 i = 1; i <= _mintAmount; i++) { | |
addressMintedBalance[msg.sender]++; | |
_safeMint(msg.sender, supply + i); | |
} | |
} | |
//////// Uncle Aaroh Addition /////// | |
modifier isValidMerkleProof(bytes32[] calldata merkleProof, bytes32 root) { | |
require( | |
MerkleProof.verify( | |
merkleProof, | |
root, | |
keccak256(abi.encodePacked(msg.sender)) | |
), | |
"Address does not exist in list" | |
); | |
_; | |
} | |
modifier isCorrectPayment(uint256 price, uint256 numberOfTokens) { | |
require( | |
price * numberOfTokens == msg.value, | |
"Incorrect ETH value sent" | |
); | |
_; | |
} | |
function mintWhitelist(bytes32[] calldata merkleProof) | |
public | |
payable | |
isValidMerkleProof(merkleProof, whitelistMerkleRoot) | |
isCorrectPayment(whiteListCost, 1) | |
{ | |
uint256 supply = totalSupply(); | |
require(supply + 1 <= maxSupply, "max NFT limit exceeded"); | |
_safeMint(msg.sender, supply + 1); | |
} | |
function setWhitelistMerkleRoot(bytes32 merkleRoot) external onlyOwner { | |
whitelistMerkleRoot = merkleRoot; | |
} | |
////////////////////////////////////// | |
function walletOfOwner(address _owner) | |
public | |
view | |
returns (uint256[] memory) | |
{ | |
uint256 ownerTokenCount = balanceOf(_owner); | |
uint256[] memory tokenIds = new uint256[](ownerTokenCount); | |
for (uint256 i; i < ownerTokenCount; i++) { | |
tokenIds[i] = tokenOfOwnerByIndex(_owner, i); | |
} | |
return tokenIds; | |
} | |
function tokenURI(uint256 tokenId) | |
public | |
view | |
virtual | |
override | |
returns (string memory) | |
{ | |
require( | |
_exists(tokenId), | |
"ERC721Metadata: URI query for nonexistent token" | |
); | |
if (revealed == false) { | |
return notRevealedUri; | |
} | |
string memory currentBaseURI = _baseURI(); | |
return | |
bytes(currentBaseURI).length > 0 | |
? string( | |
abi.encodePacked( | |
currentBaseURI, | |
tokenId.toString(), | |
baseExtension | |
) | |
) | |
: ""; | |
} | |
//only owner | |
function reveal() public onlyOwner { | |
revealed = true; | |
} | |
function setNftPerAddressLimit(uint256 _limit) public onlyOwner { | |
nftPerAddressLimit = _limit; | |
} | |
function setCost(uint256 _newCost) public onlyOwner { | |
cost = _newCost; | |
} | |
function setWhitelistCost(uint256 _newCost) public onlyOwner { | |
whiteListCost = _newCost; | |
} | |
function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner { | |
maxMintAmount = _newmaxMintAmount; | |
} | |
function setBaseURI(string memory _newBaseURI) public onlyOwner { | |
baseURI = _newBaseURI; | |
} | |
function setBaseExtension(string memory _newBaseExtension) | |
public | |
onlyOwner | |
{ | |
baseExtension = _newBaseExtension; | |
} | |
function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner { | |
notRevealedUri = _notRevealedURI; | |
} | |
function pause(bool _state) public onlyOwner { | |
paused = _state; | |
} | |
function withdraw() public payable onlyOwner { | |
(bool os, ) = payable(owner()).call{value: address(this).balance}(""); | |
require(os); | |
} | |
} |
Great work! Very useful code thank you very much for the doing this! Since Hashlips's original contract is MIT licensed, could you change the license to MIT? I want to save money on minting fees, but I don't want my entire dapp to have to switch to a GPL license.
Hi @ChristianOConnor, take inspiration, don't copy 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great work! Very useful code thank you very much for the doing this! Since Hashlips's original contract is MIT licensed, could you change the license to MIT? I want to save money on minting fees, but I don't want my entire dapp to have to switch to a GPL license.