pragma solidity ^0.7.3;
import "./NFT.sol";
contract CryptoBeasts is NFT {
using SafeMath for uint256;
constructor() NFT(
"CryptoBeasts",
"rare-eggs",
"87d13e0e44453b2ed9195eec21af62451a07d811de8ca593d507ee06f01744a4",
100000000000000000 wei,
10000,
2000,
"ipfs://QmTMSCeXsgexBYj7pNjarzzRe1fZK6P7B9uMCv61BwakSX/") {
}
function becomeEggLord() public payable{
uint numberOfTokens = 10;
require(_price.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
require(totalSupply().add(numberOfTokens) <= _max_supply, "Minting would exceed max supply");
uint[10] memory eggTypes = [uint(0), 0, 0, 0, 0, 0, 0, 0, 0, 0];
uint tokensMinted = 0;
uint i = _current_purchase_index;
while(i < _max_supply){
uint eggType = getEggType(i);
if (tokensMinted == numberOfTokens){
return;
}
else if (!_exists(i) && eggTypes[eggType] == 0){
_secureMint(msg.sender, i);
tokensMinted = tokensMinted.add(1);
eggTypes[eggType] = 1;
i = ((i / 100)+1) * 100;
}
else{
i++;
}
}
require(tokensMinted == numberOfTokens, "Not enough tokens to become Egg Lord");
}
function getEggType(uint eggNumber) public view virtual returns (uint){
return (eggNumber % 1000) / 100;
}
function getEggTypeSupply() public view virtual returns (uint[10] memory) {
uint[10] memory eggTypeSupply = [uint(0), 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (uint i = 0; i < _max_supply; i++){
if (_exists(i)){
uint eggType = getEggType(i);
eggTypeSupply[eggType] += 1;
}
}
return eggTypeSupply;
}
}
pragma solidity ^0.7.3;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/access/Ownable.sol";
contract NFT is ERC721, Ownable {
using SafeMath for uint256;
bool[10000] public _locations;
string public _provenance_hash = "";
uint256 public _price = 0;
uint256 public _max_supply = 0;
string public _baseURI = "";
uint256 public _initial_purchase_index = 0;
uint256 public _current_purchase_index = 0;
address public _owner;
constructor(string memory name, string memory symbol, string memory provenance_hash, uint256 price, uint256 max_supply, uint256 initial_purchase_index, string memory base_uri) ERC721(name, symbol) {
_owner = msg.sender;
_provenance_hash = provenance_hash;
_price = price;
_max_supply = max_supply;
_initial_purchase_index = initial_purchase_index;
_current_purchase_index = initial_purchase_index;
updateBaseTokenURI(string(abi.encodePacked(base_uri)));
}
function update(string memory provenance_hash, uint256 price, uint256 max_supply, uint256 initial_purchase_index, uint256 current_purchase_index, string memory base_uri) public onlyOwner {
_provenance_hash = provenance_hash;
_price = price;
_max_supply = max_supply;
_initial_purchase_index = initial_purchase_index;
_current_purchase_index = current_purchase_index;
updateBaseTokenURI(string(abi.encodePacked(base_uri)));
}
function updateBaseTokenURI(string memory baseURI) public onlyOwner {
_setBaseURI(baseURI);
_baseURI = baseURI;
}
function withdraw() public onlyOwner {
uint balance = address(this).balance;
msg.sender.transfer(balance);
}
function ownerMint(uint tokenId) public onlyOwner {
_secureMint(msg.sender, tokenId);
}
function ownerMint(uint[] memory tokenIds) public onlyOwner {
for (uint i = 0; i < tokenIds.length; i++){
uint tokenId = tokenIds[i];
_secureMint(msg.sender, tokenId);
}
}
function ownerMint(uint tokenId, address to) public onlyOwner {
_secureMint(to, tokenId);
}
function ownerMint(uint[] memory tokenIds, address to) public onlyOwner {
for (uint i = 0; i < tokenIds.length; i++){
uint tokenId = tokenIds[i];
_secureMint(to, tokenId);
}
}
function purchaseToken(uint tokenId) public payable {
require(tokenId >= _initial_purchase_index, "Token index out of bounds");
require(_price <= msg.value, "Ether value sent is not correct");
_secureMint(msg.sender, tokenId);
}
function purchaseTokens(uint[] memory tokenIds) public payable {
require(_price.mul(tokenIds.length) <= msg.value, "Ether value sent is not correct");
for (uint i = 0; i < tokenIds.length; i++){
uint tokenId = tokenIds[i];
require(tokenId >= _initial_purchase_index, "Token index out of bounds");
_secureMint(msg.sender, tokenId);
}
}
function purchaseNextToken() public payable {
purchaseNextTokens(1);
}
function purchaseNextTokens(uint numberOfTokens) public payable {
require(_price.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
require(totalSupply().add(numberOfTokens) <= _max_supply, "Minting would exceed max supply");
uint tokensMinted = 0;
for(uint i = _current_purchase_index; i < _max_supply; i++) {
if (tokensMinted == numberOfTokens){
break;
}
else if (!_exists(i)){
_secureMint(msg.sender, i);
tokensMinted += 1;
_current_purchase_index = i;
}
}
require(tokensMinted == numberOfTokens, "Not enough tokens to mint");
}
function claimTokenForAddress(uint256 tokenId, bytes memory sig) public{
require(verifySignature(tokenId, sig, true));
_secureMint(msg.sender, tokenId);
}
function claimTokenNoAddress(uint256 tokenId, bytes memory sig) public {
require(verifySignature(tokenId, sig, false));
_secureMint(msg.sender, tokenId);
}
function _secureMint(address to, uint256 tokenId) internal virtual {
require(tokenId < _max_supply, "Token index out of bounds");
require(tokenId >= 0, "Token index out of bounds");
_mint(to, tokenId);
_locations[tokenId] = true;
}
function verifySignature(uint256 tokenId, bytes memory sig, bool addr) internal view returns (bool)
{
bytes32 message;
if (addr){
message = prefixed(keccak256(abi.encodePacked(tokenId, msg.sender)));
}
else{
message = prefixed(keccak256(abi.encodePacked(tokenId)));
}
address signer = recoverSigner(message, sig);
return signer == _owner;
}
// Signature methods
function splitSignature(bytes memory sig)
internal
pure
returns (uint8, bytes32, bytes32)
{
require(sig.length == 65);
bytes32 r;
bytes32 s;
uint8 v;
assembly {
// first 32 bytes, after the length prefix
r := mload(add(sig, 32))
// second 32 bytes
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
function recoverSigner(bytes32 message, bytes memory sig)
internal
pure
returns (address)
{
uint8 v;
bytes32 r;
bytes32 s;
(v, r, s) = splitSignature(sig);
return ecrecover(message, v, r, s);
}
// Builds a prefixed hash to mimic the behavior of eth_sign.
function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function getBaseURI() public view returns (string memory) {
return _baseURI;
}
function getProvenanceHash() public view virtual returns (string memory) {
return _provenance_hash;
}
function getPrice() public view virtual returns (uint256) {
return _price;
}
function getMaxSupply() public view virtual returns (uint256) {
return _max_supply;
}
function getLocations() public view virtual returns (bool[10000] memory) {
return _locations;
}
}
{
"compilationTarget": {
"contracts/CryptoBeasts.sol": "CryptoBeasts"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"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":"_baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_current_purchase_index","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_initial_purchase_index","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_locations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_max_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_provenance_hash","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"becomeEggLord","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"claimTokenForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"claimTokenNoAddress","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":[],"name":"getBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"eggNumber","type":"uint256"}],"name":"getEggType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEggTypeSupply","outputs":[{"internalType":"uint256[10]","name":"","type":"uint256[10]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLocations","outputs":[{"internalType":"bool[10000]","name":"","type":"bool[10000]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProvenanceHash","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"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":"tokenIds","type":"uint256[]"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"purchaseNextToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"purchaseNextTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"purchaseToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"purchaseTokens","outputs":[],"stateMutability":"payable","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":"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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"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":"string","name":"provenance_hash","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"max_supply","type":"uint256"},{"internalType":"uint256","name":"initial_purchase_index","type":"uint256"},{"internalType":"uint256","name":"current_purchase_index","type":"uint256"},{"internalType":"string","name":"base_uri","type":"string"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"updateBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]