Skip to content

Instantly share code, notes, and snippets.

@Qambar
Last active August 12, 2022 14:41
Show Gist options
  • Save Qambar/96b52813f46d45d1a6138c15556a70b8 to your computer and use it in GitHub Desktop.
Save Qambar/96b52813f46d45d1a6138c15556a70b8 to your computer and use it in GitHub Desktop.
Hashlips contract modified to work with merkle tree
// 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);
}
}
@BenRiekes
Copy link

can i ask u if i use remix where do i input the adresses

js file

@ChristianOConnor
Copy link

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.

@Qambar
Copy link
Author

Qambar commented Aug 12, 2022

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