文件 1 的 6:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 6:ERC721I.sol
pragma solidity ^0.8.0;
contract ERC721I {
string public name; string public symbol;
string internal baseTokenURI; string internal baseTokenURI_EXT;
constructor(string memory name_, string memory symbol_) {
name = name_; symbol = symbol_;
}
uint256 public totalSupply;
mapping(uint256 => address) public ownerOf;
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
event Transfer(address indexed from, address indexed to,
uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved,
uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator,
bool approved);
function _mint(address to_, uint256 tokenId_) internal virtual {
require(to_ != address(0x0),
"ERC721I: _mint() Mint to Zero Address");
require(ownerOf[tokenId_] == address(0x0),
"ERC721I: _mint() Token to Mint Already Exists!");
balanceOf[to_]++;
ownerOf[tokenId_] = to_;
emit Transfer(address(0x0), to_, tokenId_);
}
function _transfer(address from_, address to_, uint256 tokenId_) internal virtual {
require(from_ == ownerOf[tokenId_],
"ERC721I: _transfer() Transfer Not Owner of Token!");
require(to_ != address(0x0),
"ERC721I: _transfer() Transfer to Zero Address!");
if (getApproved[tokenId_] != address(0x0)) {
_approve(address(0x0), tokenId_);
}
ownerOf[tokenId_] = to_;
balanceOf[from_]--;
balanceOf[to_]++;
emit Transfer(from_, to_, tokenId_);
}
function _approve(address to_, uint256 tokenId_) internal virtual {
if (getApproved[tokenId_] != to_) {
getApproved[tokenId_] = to_;
emit Approval(ownerOf[tokenId_], to_, tokenId_);
}
}
function _setApprovalForAll(address owner_, address operator_, bool approved_)
internal virtual {
require(owner_ != operator_,
"ERC721I: _setApprovalForAll() Owner must not be the Operator!");
isApprovedForAll[owner_][operator_] = approved_;
emit ApprovalForAll(owner_, operator_, approved_);
}
function _setBaseTokenURI(string memory uri_) internal virtual {
baseTokenURI = uri_;
}
function _setBaseTokenURI_EXT(string memory ext_) internal virtual {
baseTokenURI_EXT = ext_;
}
function _toString(uint256 value_) internal pure returns (string memory) {
if (value_ == 0) { return "0"; }
uint256 _iterate = value_; uint256 _digits;
while (_iterate != 0) { _digits++; _iterate /= 10; }
bytes memory _buffer = new bytes(_digits);
while (value_ != 0) { _digits--; _buffer[_digits] = bytes1(uint8(
48 + uint256(value_ % 10 ))); value_ /= 10; }
return string(_buffer);
}
function _isApprovedOrOwner(address spender_, uint256 tokenId_) internal
view virtual returns (bool) {
require(ownerOf[tokenId_] != address(0x0),
"ERC721I: _isApprovedOrOwner() Owner is Zero Address!");
address _owner = ownerOf[tokenId_];
return (spender_ == _owner
|| spender_ == getApproved[tokenId_]
|| isApprovedForAll[_owner][spender_]);
}
function _exists(uint256 tokenId_) internal view virtual returns (bool) {
return ownerOf[tokenId_] != address(0x0);
}
function approve(address to_, uint256 tokenId_) public virtual {
address _owner = ownerOf[tokenId_];
require(to_ != _owner,
"ERC721I: approve() Cannot approve yourself!");
require(msg.sender == _owner || isApprovedForAll[_owner][msg.sender],
"ERC721I: Caller not owner or Approved!");
_approve(to_, tokenId_);
}
function setApprovalForAll(address operator_, bool approved_) public virtual {
_setApprovalForAll(msg.sender, operator_, approved_);
}
function transferFrom(address from_, address to_, uint256 tokenId_)
public virtual {
require(_isApprovedOrOwner(msg.sender, tokenId_),
"ERC721I: transferFrom() _isApprovedOrOwner = false!");
_transfer(from_, to_, tokenId_);
}
function safeTransferFrom(address from_, address to_, uint256 tokenId_,
bytes memory data_) public virtual {
transferFrom(from_, to_, tokenId_);
if (to_.code.length != 0) {
(, bytes memory _returned) = to_.staticcall(abi.encodeWithSelector(
0x150b7a02, msg.sender, from_, tokenId_, data_));
bytes4 _selector = abi.decode(_returned, (bytes4));
require(_selector == 0x150b7a02,
"ERC721I: safeTransferFrom() to_ not ERC721Receivable!");
}
}
function safeTransferFrom(address from_, address to_, uint256 tokenId_)
public virtual {
safeTransferFrom(from_, to_, tokenId_, "");
}
function multiTransferFrom(address from_, address to_,
uint256[] memory tokenIds_) public virtual {
for (uint256 i = 0; i < tokenIds_.length; i++) {
transferFrom(from_, to_, tokenIds_[i]);
}
}
function multiSafeTransferFrom(address from_, address to_,
uint256[] memory tokenIds_, bytes memory data_) public virtual {
for (uint256 i = 0; i < tokenIds_.length; i++) {
safeTransferFrom(from_, to_, tokenIds_[i], data_);
}
}
function supportsInterface(bytes4 interfaceId_) public pure returns (bool) {
return (interfaceId_ == 0x80ac58cd || interfaceId_ == 0x5b5e139f);
}
function tokenURI(uint256 tokenId_) public view virtual returns (string memory) {
require(ownerOf[tokenId_] != address(0x0),
"ERC721I: tokenURI() Token does not exist!");
return string(abi.encodePacked(
baseTokenURI, _toString(tokenId_), baseTokenURI_EXT));
}
function walletOfOwner(address address_) public virtual view
returns (uint256[] memory) {
uint256 _balance = balanceOf[address_];
uint256[] memory _tokens = new uint256[] (_balance);
uint256 _index;
uint256 _loopThrough = totalSupply;
for (uint256 i = 0; i < _loopThrough; i++) {
if (ownerOf[i] == address(0x0) && _tokens[_balance - 1] == 0) {
_loopThrough++;
}
if (ownerOf[i] == address_) {
_tokens[_index] = i; _index++;
}
}
return _tokens;
}
function tokenOfOwnerByIndex(address address_, uint256 index_) public
virtual view returns (uint256) {
uint256[] memory _wallet = walletOfOwner(address_);
return _wallet[index_];
}
}
文件 3 的 6:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 4 的 6:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(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++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
computedHash = _efficientHash(computedHash, proofElement);
} else {
computedHash = _efficientHash(proofElement, computedHash);
}
}
return computedHash;
}
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}
文件 5 的 6:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 6 的 6:SmithoniaWeapons.sol
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./ERC721I.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
abstract contract Security {
modifier onlySender() {
require(tx.origin == msg.sender, "The caller is another contract");
_;
}
}
contract SmithoniaWeapons is Ownable, ERC721I, Security {
uint256 public maxSupply = 12300;
bool public mintIsActive = false;
bool public publicMintIsActive = false;
address public magicAddress;
uint256 public minimumAmount;
string private _baseTokenURI;
mapping(address => bool) private minter;
bytes32 public merkleRoot;
constructor() ERC721I("Smithonia Weapons", "SMITHWEP") {}
function mintWl(bytes32[] calldata _merkleProof) external onlySender {
require(mintIsActive, "Blacksmith sleeping");
require(maxSupply > totalSupply, "Armory empty");
require(minimumAmount > 0, "Magic amount is not set");
uint256 magicBalance = IERC20(magicAddress).balanceOf(
address(msg.sender)
);
require(magicBalance >= minimumAmount, "Not enough magic");
require(!minter[msg.sender], "You have already minted");
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(
MerkleProof.verify(_merkleProof, merkleRoot, leaf),
"Not allowed to enter Smithonia"
);
minter[msg.sender] = true;
uint256 id = totalSupply + 1;
_mint(msg.sender, id);
totalSupply++;
}
function publicMint() external onlySender {
require(mintIsActive && publicMintIsActive, "Blacksmith sleeping");
require(maxSupply > totalSupply, "Armory empty");
require(!minter[msg.sender], "You have already minted");
minter[msg.sender] = true;
uint256 id = totalSupply + 1;
_mint(msg.sender, id);
totalSupply++;
}
function adminMint(uint256 quantity, address _target) external onlyOwner {
require(maxSupply >= totalSupply + quantity, "Sold out");
uint256 startId = totalSupply + 1;
for (uint256 i = 0; i < quantity; i++) {
_mint(_target, startId + i);
}
totalSupply += quantity;
}
function setBaseTokenURI(string memory baseURI) external onlyOwner {
_setBaseTokenURI(baseURI);
}
function setMagicAddress(address _magicAddress) external onlyOwner {
magicAddress = _magicAddress;
}
function setMinimumAmount(uint256 _minimumAmount) external onlyOwner {
minimumAmount = _minimumAmount;
}
function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
merkleRoot = _merkleRoot;
}
function toggleSale() public onlyOwner {
mintIsActive = !mintIsActive;
}
function togglePublicSale() public onlyOwner {
publicMintIsActive = !publicMintIsActive;
}
function hasMinted(address _addr) public view returns (bool) {
return minter[_addr];
}
}
{
"compilationTarget": {
"contracts/SmithoniaWeapons.sol": "SmithoniaWeapons"
},
"evmVersion": "london",
"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":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"_target","type":"address"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","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":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"hasMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"magicAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"mintWl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"multiSafeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"multiTransferFrom","outputs":[],"stateMutability":"nonpayable","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":"","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"publicMintIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"string","name":"baseURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_magicAddress","type":"address"}],"name":"setMagicAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimumAmount","type":"uint256"}],"name":"setMinimumAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId_","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"togglePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","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":"address","name":"address_","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]