Skip to content

Instantly share code, notes, and snippets.

@Ferk
Last active April 25, 2022 02:35
Show Gist options
  • Select an option

  • Save Ferk/607974f570f437e4356d136ecfad816b to your computer and use it in GitHub Desktop.

Select an option

Save Ferk/607974f570f437e4356d136ecfad816b to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.7+commit.e28d00a7.js&optimize=true&runs=200&gist=
Prototype Contract
// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.7;
// Gist: https://gist.github.com/Ferk/607974f570f437e4356d136ecfad816b
// ERC721A: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "erc721a/contracts/ERC721A.sol";
contract Contract is Ownable, ERC721A, ReentrancyGuard {
uint256 constant MAX_SUPPLY = 8888;
uint256 constant MAX_MINTS_PER_WALLET = 3;
uint256 constant MAX_MINTS_PER_WL_PRESALE = 2;
uint256 constant MAX_MINTS_PER_TEAM_PRESALE = 2;
// Sale configuration
uint256 constant SALE_PRICE = 0.06 ether;
uint256 constant PRESALE_PRICE = 0.04 ether;
string public baseURI = "ipfs://QmZbcUWmQE8yKpeSFYsYN4H24QxAw715pyY1zG1boRHHca/";
mapping(address => bool) public whitelist;
mapping(address => bool) public teamlist;
// cmd: date +%s -d '2022-04-24 18:00:00'
uint32 presaleStartTime = 1650816000;
uint32 saleStartTime = 1650902400;
function setPreMintTime(uint32 time) public onlyOwner {
presaleStartTime = time;
}
function setPubMintTime(uint32 time) public onlyOwner {
saleStartTime = time;
}
constructor() ERC721A('Prototype NFT', 'TEST_NFT') {
}
// prevent another contract from calling the function to prevent any malpractice
modifier callerIsUser() {
require(tx.origin == msg.sender, "Caller can't be a contract");
_;
}
function whitelistAddresses(address[] calldata wAddresses) public onlyOwner {
for (uint i = 0; i < wAddresses.length; i++) {
whitelist[wAddresses[i]] = true;
}
}
function teamlistAddresses(address[] calldata wAddresses) public onlyOwner {
for (uint i = 0; i < wAddresses.length; i++) {
teamlist[wAddresses[i]] = true;
}
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// allows the owner to withdraw the money from the contract
function withdrawMoney() external nonReentrant onlyOwner
{
(bool success, ) = msg.sender.call{value: address(this).balance}("");
require(success, "Transfer failed.");
}
// Public minting
function publicMint(uint256 quantity) external payable nonReentrant callerIsUser {
require(saleStartTime != 0 && block.timestamp >= uint256(saleStartTime),
"No public sale currently active"
);
saleMint(SALE_PRICE, quantity);
}
// Whitelist minting
function presaleMint(uint256 quantity) external payable nonReentrant callerIsUser {
require(presaleStartTime != 0 && block.timestamp >= uint256(presaleStartTime),
"No presale currently active"
);
require(whitelist[msg.sender],
"Address is not whitelisted for presale"
);
require(quantity + _numberMinted(msg.sender) <= MAX_MINTS_PER_WL_PRESALE,
"Maximum reached, try minting on public sale"
);
saleMint(PRESALE_PRICE, quantity);
}
// Team minting
function teamMint(uint256 quantity) external payable callerIsUser {
require(teamlist[msg.sender],
"Address is not part of the team"
);
// only 2 free mints allowed per team wallet
require(quantity + _numberMinted(msg.sender) <= MAX_MINTS_PER_TEAM_PRESALE,
"maximum team mints reached"
);
saleMint(0, quantity);
}
// mint the given amount at the given price
function saleMint(uint256 minPrice, uint256 quantity) private {
//require(isMintEnabled, "minting not enabled");
// one wallet can't mint too much
require(quantity + _numberMinted(msg.sender) <= MAX_MINTS_PER_WALLET,
"exceeds max per wallet"
);
// exceeded the token supply
require(totalSupply() + quantity <= MAX_SUPPLY,
"sold out"
);
// make sure it's not done for less than the mint price
require(msg.value >= minPrice,
"wrong value, not enough funds"
);
_safeMint(msg.sender, quantity);
}
/**
* @dev Burns `tokenId`. See {ERC721A-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
_burn(tokenId, true);
}
}
// Right click on the script name and hit "Run" to execute
(async () => {
try {
console.log('Running deployWithEthers script...')
const contractName = 'Storage' // Change this for other contract
const constructorArgs = [] // Put constructor args (if any) here for your contract
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json` // Change this for different path
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
let factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract = await factory.deploy(...constructorArgs);
console.log('Contract Address: ', contract.address);
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
console.log('Deployment successful.')
} catch (e) {
console.log(e.message)
}
})()
// Right click on the script name and hit "Run" to execute
(async () => {
try {
console.log('Running deployWithWeb3 script...')
const contractName = 'Storage' // Change this for other contract
const constructorArgs = [] // Put constructor args (if any) here for your contract
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/artifacts/${contractName}.json` // Change this for different path
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const accounts = await web3.eth.getAccounts()
let contract = new web3.eth.Contract(metadata.abi)
contract = contract.deploy({
data: metadata.data.bytecode.object,
arguments: constructorArgs
})
const newContractInstance = await contract.send({
from: accounts[0],
gas: 1500000,
gasPrice: '30000000000'
})
console.log('Contract deployed at address: ', newContractInstance.options.address)
} catch (e) {
console.log(e.message)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment