Commit 07e6f43a authored by Kegan's avatar Kegan
Browse files

added in payment requirement

parent 8948f807
......@@ -152,8 +152,14 @@ contract SkinZNFT is ERC721Enumerable, ReentrancyGuard, Ownable {
uint256 internal max_token_id;
uint256 internal nft_cost;
bool internal allow_claims;
constructor() ERC721("Skin-Z", "SKZ") Ownable() {
max_token_id = 0;
nft_cost = 10000000000000000; // 0.01 ETH
allow_claims = false;
//NOTE: if we move away from arbitrum, this needs removed!
/*address arbsys_addr = address(0x64);
......@@ -177,7 +183,18 @@ contract SkinZNFT is ERC721Enumerable, ReentrancyGuard, Ownable {
max_token_id += data[i].count;
function transferFunds(address payable reciever, uint256 amount) public onlyOwner nonReentrant {
require(address(this).balance >= amount, "invalid transfer amount");
require(reciever != address(0x0), "cannot burn payments");
function enableClaims() public onlyOwner {
allow_claims = true;
function disableClaims() public onlyOwner {
allow_claims = false;
// NOTE: if moving from arbitrum to another blockchain, this source of randomness would need uodated!
// generate a random number (changes between arbitrum and ethereum mainnet!)
function random(uint256 seed) internal view returns(uint256)
......@@ -222,18 +239,33 @@ contract SkinZNFT is ERC721Enumerable, ReentrancyGuard, Ownable {
string memory output = string(abi.encodePacked('data:application/json;base64,', json));
return output;
function claim(uint256 tokenId) public nonReentrant {
function claim(uint256 tokenId) public payable nonReentrant {
require(allow_claims, "claims are disabled");
require(!_msgSender().isContract(),"smart contracts cannot mint");
require(_unmintedSkins.length > 0, "no more skins to claim");
require(tokenId <= max_token_id && tokenId > 0, "Invalid Token ID"); //tokenIds start from 1!
require(!_exists(tokenId), "token already claimed");
require(msg.value >= nft_cost,"deposit too small");
_nftData[tokenId] = randomSkin(tokenId);
assert(bytes(_nftData[tokenId].image).length > 0);
assert(bytes(_nftData[tokenId].name).length > 0);
_safeMint(_msgSender(), tokenId);
if(msg.value > nft_cost)
payable(_msgSender()).transfer(msg.value - nft_cost);
// ETH can only be sent to this wallet during claims (otherwise we revert)
receive() external payable {
fallback() external payable {
\ No newline at end of file
......@@ -90,3 +90,12 @@ For example, say we had `SkinData[]` which contained all the NFTs to mint. If we
We'll likely mint all of the "rare" NFTs early, leaving only common ones to be minted by the end.
1. Deploy to arbitrum testnet w/ testing artwork
2. ~~Require 0.01 deposit to run claim method~~
3. ~~Refund any excess funds deposited above 0.01 cost~~
4. ~~allow owner to transfer ETH out of contract to target wallet~~
5. ~~Block claims until owner flips a bool ~~
6. ~~refund any deposits not made during a claim~~
7. Depoy to arbitrum mainnet w/ real artwork
# Solidity smart contract notes
Solidity is the prefered language to write smart contracts in. See [[Hardhat]] for a development environment.
Here is an awesome learning site:
## View vs Pure
the `VIEW` keyword is for functions that read, but do not modify the state of the blockchian.
the `PURE` keybword is for functions that neither read nor modify the blockchain.
## Depositing ETH to functions
to allow a function to accept ETH, it needs the `payable` keyword.
ETH value transfered can be found in the `msg.value` field.
## Payable addresses
there is the `address` type and the `address payable` type.
To convert an address to payable do `payable(ADDRESS_HERE)`
Transfer funds with `payableaddr.transfer(amount)`; (2300 gas fee)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment