编译器
0.8.24+commit.e11b9ed9
文件 6 的 17:ERC721Enumerable.sol
文件 8 的 17:IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 10 的 17:IERC721Enumerable.sol
文件 11 的 17:IERC721Metadata.sol
文件 12 的 17:IERC721Receiver.sol
文件 13 的 17:MerkleProof.sol
pragma solidity ^0.8.20;
library MerkleProof {
error MerkleProofInvalidMultiproof();
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
if (leavesLen + proofLen != totalHashes + 1) {
revert MerkleProofInvalidMultiproof();
}
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
if (proofPos != proofLen) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
if (leavesLen + proofLen != totalHashes + 1) {
revert MerkleProofInvalidMultiproof();
}
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
if (proofPos != proofLen) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 15 的 17:ReentrancyGuard.sol
文件 17 的 17:erctamagotchi.sol
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/security/ReentrancyGuard.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.5.0/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract TamagotchiERC is ERC721Enumerable, ReentrancyGuard, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
mapping(uint256 => uint256) public tokenMintTimestamps;
mapping(uint256 => uint256) public claimCounts;
mapping(uint256 => string) private _evolvedURIs;
mapping(uint256 => bool) public hasEvolved;
string private _baseTokenURI;
string private _baseEvolvedTokenURI;
string private _contractURI;
uint256 public evolvedCount;
bytes32 public merkleRoot;
uint256 public HOLDING_PERIOD = 6 hours;
uint256 public constant REWARD_AMOUNT = 10 * (10 ** 18);
uint256 public constant EVOLVED_REWARD_AMOUNT = 30 * (10 ** 18);
uint256 public constant INITIAL_CLAIM_AMOUNT = 100 * (10 ** 18);
IERC20 public rewardToken;
mapping(uint256 => bool) public hasClaimedInitialAmount;
uint256 public evolveInterval = 800;
bool public gameStarted = false;
uint256 public constant MINT_PRICE = 0.012 ether;
uint256 public constant WL_MINT_PRICE = 0.006 ether;
uint256 public constant MAX_MINT_PER_WALLET = 200;
uint256 public constant MAX_MINT_AT_ONCE = 100;
uint256 public constant MAX_WL_MINT_PER_WALLET = 20;
uint256 public constant MAX_WL_MINT_AT_ONCE = 20;
uint256 constant public MAX_TIME_DURATION = 1 hours;
mapping(address => uint256) public mintedPerWallet;
bool public mintingOpen = false;
bool public WLopen = false;
constructor() ERC721("BASED PETS", "GOTCHI") Ownable() {}
function isValidTimestamp(uint256 _timestamp) internal view returns (bool) {
uint256 currentBlockTime = block.timestamp;
uint256 currentBlockStart = currentBlockTime - (currentBlockTime % MAX_TIME_DURATION);
uint256 currentBlockEnd = currentBlockStart + MAX_TIME_DURATION;
return (_timestamp >= currentBlockStart && _timestamp < currentBlockEnd);
}
function setRewardToken(address _rewardTokenAddress) public onlyOwner {
require(address(rewardToken) == address(0), "RewardToken contract address already set");
rewardToken = IERC20(_rewardTokenAddress);
}
function setURIs(string memory baseTokenURI_, string memory baseEvolvedTokenURI_) public onlyOwner {
_baseTokenURI = baseTokenURI_;
_baseEvolvedTokenURI = baseEvolvedTokenURI_;
}
function setContractURI(string memory contractURI_) public onlyOwner {
_contractURI = contractURI_;
}
function startGame() public onlyOwner {
gameStarted = true;
}
function openMint() public onlyOwner {
if (mintingOpen == true) {
mintingOpen = false;
} else {
mintingOpen = true;
}
}
function openWL() public onlyOwner {
if (WLopen == true) {
WLopen = false;
} else {
WLopen = true;
}
}
function numberOfEvolvedPets(address user) public view returns (uint256 count) {
uint256 ownerTokenCount = balanceOf(user);
count = 0;
for (uint256 i = 0; i < ownerTokenCount; i++) {
uint256 tokenId = tokenOfOwnerByIndex(user, i);
if (hasEvolved[tokenId]) {
count += 1;
}
}
}
function mintNFT(uint256 quantity) public payable {
require(mintingOpen, "Minting is closed");
require(quantity > 0 && quantity <= MAX_MINT_AT_ONCE, "Cannot mint specified number at once");
require(mintedPerWallet[msg.sender] + quantity <= MAX_MINT_PER_WALLET, "Exceeds maximum per wallet");
require(msg.value >= MINT_PRICE * quantity, "Ether sent is not correct");
for (uint256 i = 0; i < quantity; i++) {
_tokenIdCounter.increment();
uint256 tokenId = _tokenIdCounter.current();
_mint(msg.sender, tokenId);
tokenMintTimestamps[tokenId] = block.timestamp;
claimCounts[tokenId] = 0;
}
mintedPerWallet[msg.sender] += quantity;
}
function whitelistMint(uint256 quantity, bytes32[] calldata merkleProof) public payable {
require(WLopen, "Whitelist is closed");
require(mintingOpen, "Minting is closed");
require(quantity > 0 && quantity <= MAX_WL_MINT_AT_ONCE, "Cannot mint specified number at once");
require(mintedPerWallet[msg.sender] + quantity <= MAX_WL_MINT_PER_WALLET, "Exceeds maximum whitelist mint per wallet");
require(msg.value >= WL_MINT_PRICE * quantity, "Ether sent is not correct");
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(MerkleProof.verify(merkleProof, merkleRoot, leaf), "Invalid Merkle Proof");
for (uint256 i = 0; i < quantity; i++) {
_tokenIdCounter.increment();
uint256 tokenId = _tokenIdCounter.current();
_mint(msg.sender, tokenId);
tokenMintTimestamps[tokenId] = block.timestamp;
claimCounts[tokenId] = 0;
}
mintedPerWallet[msg.sender] += quantity;
}
function claimAllRewards() public nonReentrant {
require(gameStarted, "Game has not started yet");
uint256 ownerTokenCount = balanceOf(msg.sender);
require(ownerTokenCount > 0, "No NFTs owned.");
uint256 totalReward = 0;
for (uint256 i = 0; i < ownerTokenCount; i++) {
uint256 tokenId = tokenOfOwnerByIndex(msg.sender, i);
if (!hasClaimedInitialAmount[tokenId] || block.timestamp >= tokenMintTimestamps[tokenId] + HOLDING_PERIOD) {
tokenMintTimestamps[tokenId] = block.timestamp;
uint256 rewardAmount;
if (!hasClaimedInitialAmount[tokenId]) {
rewardAmount = INITIAL_CLAIM_AMOUNT;
hasClaimedInitialAmount[tokenId] = true;
} else {
rewardAmount = hasEvolved[tokenId] ? EVOLVED_REWARD_AMOUNT : REWARD_AMOUNT;
}
totalReward += rewardAmount;
claimCounts[tokenId] += 1;
if (claimCounts[tokenId] >= 5) {
evolve(tokenId);
}
}
}
require(totalReward > 0, "No rewards available to claim.");
bool sent = rewardToken.transfer(msg.sender, totalReward);
require(sent, "Reward token transfer failed.");
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
if (hasEvolved[tokenId]) {
return string(abi.encodePacked(_baseEvolvedTokenURI, Strings.toString(tokenId)));
} else {
return string(abi.encodePacked(_baseTokenURI, Strings.toString(tokenId)));
}
}
function contractURI() public view returns (string memory) {
return _contractURI;
}
function setEvolveInterval(uint256 interval) public onlyOwner {
evolveInterval = interval;
}
function evolve(uint256 tokenId) public {
require(ownerOf(tokenId) == msg.sender, "Caller is not the owner");
require(claimCounts[tokenId] >= 5, "Not enough claims to evolve");
require(isValidTimestamp(block.timestamp), "Invalid timestamp");
require(!hasEvolved[tokenId], "Token has already evolved");
hasEvolved[tokenId] = true;
evolvedCount++;
if (evolvedCount % evolveInterval == 0) {
HOLDING_PERIOD += 6 hours;
}
}
function withdraw(uint256 amount) public onlyOwner {
require(amount <= address(this).balance, "Insufficient balance");
(bool sent, ) = owner().call{value: amount}("");
require(sent, "Failed to send Ether");
}
function setMerkleRoot(bytes32 _merkleRoot) public onlyOwner {
merkleRoot = _merkleRoot;
}
}
{
"compilationTarget": {
"contracts/erctamagotchi.sol": "TamagotchiERC"
},
"evmVersion": "shanghai",
"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":"EVOLVED_REWARD_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HOLDING_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INITIAL_CLAIM_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINT_AT_ONCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINT_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TIME_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WL_MINT_AT_ONCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WL_MINT_PER_WALLET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WL_MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WLopen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"claimAllRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"evolve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"evolveInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"evolvedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hasClaimedInitialAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hasEvolved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"quantity","type":"uint256"}],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"numberOfEvolvedPets","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openWL","outputs":[],"stateMutability":"nonpayable","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":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","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":"contractURI_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"interval","type":"uint256"}],"name":"setEvolveInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardTokenAddress","type":"address"}],"name":"setRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseTokenURI_","type":"string"},{"internalType":"string","name":"baseEvolvedTokenURI_","type":"string"}],"name":"setURIs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startGame","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":"uint256","name":"","type":"uint256"}],"name":"tokenMintTimestamps","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":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]