// SPDX-License-Identifier: MIT
pragma solidity >=0.7.6 <0.8.0;
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/utils/Counters.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/access/Ownable.sol";
contract Encapsuled28 is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
mapping(string => uint8) public myTokenURI;
mapping(string => uint8) public myTokenName;
mapping(uint256 => Poem) public poems;
uint256 public constant MAX_NFT_SUPPLY = 28;
uint256 public constant currentPrice = 100000000000000000;
bool private reentrancyLock = false;
bool public communityGrant = true;
struct Poem {
string title;
string text;
string author;
}
event TokenBought(
uint256 mintedTokenID,
string poemTitle,
string poemText,
string author
);
modifier reentrancyGuard {
if (reentrancyLock) {
revert();
}
reentrancyLock = true;
_;
reentrancyLock = false;
}
constructor() public ERC721("Encapsuled28", "E28") {}
function mint(
string memory _myTokenURI,
string memory _poemTitle,
string memory _poemText
) external payable reentrancyGuard {
// Validate token to be minted
_validateTokenToBeMinted(_myTokenURI, _poemTitle);
require(getNFTPrice() == msg.value, "Ether value sent is not correct");
// mark token URI as minted
myTokenURI[_myTokenURI] = 1;
// mark token name as taken
myTokenName[_poemTitle] = 1;
// new token id
uint256 newItemId = _tokenIds.current();
// save poem on chain
poems[newItemId].text = _poemText;
poems[newItemId].title = _poemTitle;
poems[newItemId].author = "encapsuled";
// mint token && assign ownership of token to msg.sender
_safeMint(msg.sender, newItemId);
// set token url
_setTokenURI(newItemId, _myTokenURI);
// emit TokenBought event
emit TokenBought(newItemId, _poemTitle, _poemText, "encapsuled");
// increment token counter for sold token
_tokenIds.increment();
}
function _validateTokenToBeMinted(
string memory _myTokenURI,
string memory _poemName
) internal view {
require(_tokenIds.current() < MAX_NFT_SUPPLY, "Sale has already ended");
require(myTokenURI[_myTokenURI] != 1, "Token URI is already minted");
require(myTokenName[_poemName] != 1, "Token Name is already minted");
}
function withdraw() public payable onlyOwner {
uint256 balance = address(this).balance;
msg.sender.transfer(balance);
}
function getPoem(uint256 _tokenID) public view returns (string memory) {
require(_tokenID <= _tokenIds.current());
return (poems[_tokenID].text);
}
function getTitle(uint256 _tokenID) public view returns (string memory) {
require(_tokenID <= _tokenIds.current());
return (poems[_tokenID].title);
}
function getAuthor(uint256 _tokenID) public view returns (string memory) {
require(_tokenID <= _tokenIds.current());
return (poems[_tokenID].author);
}
function getNFTPrice() public pure returns (uint256) {
return currentPrice;
}
function toggleCommunityGrant() external onlyOwner {
communityGrant = !communityGrant;
}
receive() external payable {}
}
{
"compilationTarget": {
"contracts/Encapsuled28.sol": "Encapsuled28"
},
"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":false,"internalType":"uint256","name":"mintedTokenID","type":"uint256"},{"indexed":false,"internalType":"string","name":"poemTitle","type":"string"},{"indexed":false,"internalType":"string","name":"poemText","type":"string"},{"indexed":false,"internalType":"string","name":"author","type":"string"}],"name":"TokenBought","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":"MAX_NFT_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"communityGrant","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_tokenID","type":"uint256"}],"name":"getAuthor","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"getPoem","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"getTitle","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":[{"internalType":"string","name":"_myTokenURI","type":"string"},{"internalType":"string","name":"_poemTitle","type":"string"},{"internalType":"string","name":"_poemText","type":"string"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"myTokenName","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"myTokenURI","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"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":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poems","outputs":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"text","type":"string"},{"internalType":"string","name":"author","type":"string"}],"stateMutability":"view","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":[],"name":"toggleCommunityGrant","outputs":[],"stateMutability":"nonpayable","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":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]