编译器
0.8.13+commit.abaa5c0e
文件 1 的 9: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 的 9:ECDSA.sol
pragma solidity ^0.8.0;
import "../Strings.sol";
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 3 的 9:ERC721A.sol
pragma solidity ^0.8.4;
import './IERC721A.sol';
interface ERC721A__IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
contract ERC721A is IERC721A {
uint256 private constant BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
uint256 private constant BITPOS_NUMBER_MINTED = 64;
uint256 private constant BITPOS_NUMBER_BURNED = 128;
uint256 private constant BITPOS_AUX = 192;
uint256 private constant BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
uint256 private constant BITPOS_START_TIMESTAMP = 160;
uint256 private constant BITMASK_BURNED = 1 << 224;
uint256 private constant BITPOS_NEXT_INITIALIZED = 225;
uint256 private constant BITMASK_NEXT_INITIALIZED = 1 << 225;
uint256 private _currentIndex;
uint256 private _burnCounter;
string private _name;
string private _symbol;
mapping(uint256 => uint256) private _packedOwnerships;
mapping(address => uint256) private _packedAddressData;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
function _startTokenId() internal view virtual returns (uint256) {
return 0;
}
function _nextTokenId() internal view returns (uint256) {
return _currentIndex;
}
function totalSupply() public view override returns (uint256) {
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
function _totalMinted() internal view returns (uint256) {
unchecked {
return _currentIndex - _startTokenId();
}
}
function _totalBurned() internal view returns (uint256) {
return _burnCounter;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function balanceOf(address owner) public view override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return _packedAddressData[owner] & BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberMinted(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
}
function _numberBurned(address owner) internal view returns (uint256) {
return (_packedAddressData[owner] >> BITPOS_NUMBER_BURNED) & BITMASK_ADDRESS_DATA_ENTRY;
}
function _getAux(address owner) internal view returns (uint64) {
return uint64(_packedAddressData[owner] >> BITPOS_AUX);
}
function _setAux(address owner, uint64 aux) internal {
uint256 packed = _packedAddressData[owner];
uint256 auxCasted;
assembly {
auxCasted := aux
}
packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
_packedAddressData[owner] = packed;
}
function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr)
if (curr < _currentIndex) {
uint256 packed = _packedOwnerships[curr];
if (packed & BITMASK_BURNED == 0) {
while (packed == 0) {
packed = _packedOwnerships[--curr];
}
return packed;
}
}
}
revert OwnerQueryForNonexistentToken();
}
function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
ownership.addr = address(uint160(packed));
ownership.startTimestamp = uint64(packed >> BITPOS_START_TIMESTAMP);
ownership.burned = packed & BITMASK_BURNED != 0;
}
function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnerships[index]);
}
function _initializeOwnershipAt(uint256 index) internal {
if (_packedOwnerships[index] == 0) {
_packedOwnerships[index] = _packedOwnershipOf(index);
}
}
function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
return _unpackedOwnership(_packedOwnershipOf(tokenId));
}
function ownerOf(uint256 tokenId) public view override returns (address) {
return address(uint160(_packedOwnershipOf(tokenId)));
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
function _baseURI() internal view virtual returns (string memory) {
return '';
}
function _addressToUint256(address value) private pure returns (uint256 result) {
assembly {
result := value
}
}
function _boolToUint256(bool value) private pure returns (uint256 result) {
assembly {
result := value
}
}
function approve(address to, uint256 tokenId) public override {
address owner = address(uint160(_packedOwnershipOf(tokenId)));
if (to == owner) revert ApprovalToCurrentOwner();
if (_msgSenderERC721A() != owner)
if (!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
if (operator == _msgSenderERC721A()) revert ApproveToCaller();
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, '');
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
_transfer(from, to, tokenId);
if (to.code.length != 0)
if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
function _exists(uint256 tokenId) internal view returns (bool) {
return
_startTokenId() <= tokenId &&
tokenId < _currentIndex &&
_packedOwnerships[tokenId] & BITMASK_BURNED == 0;
}
function _safeMint(address to, uint256 quantity) internal {
_safeMint(to, quantity, '');
}
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] =
_addressToUint256(to) |
(block.timestamp << BITPOS_START_TIMESTAMP) |
(_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);
uint256 updatedIndex = startTokenId;
uint256 end = updatedIndex + quantity;
if (to.code.length != 0) {
do {
emit Transfer(address(0), to, updatedIndex);
if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (updatedIndex < end);
if (_currentIndex != startTokenId) revert();
} else {
do {
emit Transfer(address(0), to, updatedIndex++);
} while (updatedIndex < end);
}
_currentIndex = updatedIndex;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
function _mint(address to, uint256 quantity) internal {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
unchecked {
_packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);
_packedOwnerships[startTokenId] =
_addressToUint256(to) |
(block.timestamp << BITPOS_START_TIMESTAMP) |
(_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);
uint256 updatedIndex = startTokenId;
uint256 end = updatedIndex + quantity;
do {
emit Transfer(address(0), to, updatedIndex++);
} while (updatedIndex < end);
_currentIndex = updatedIndex;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
function _transfer(
address from,
address to,
uint256 tokenId
) private {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();
bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
isApprovedForAll(from, _msgSenderERC721A()) ||
getApproved(tokenId) == _msgSenderERC721A());
if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
delete _tokenApprovals[tokenId];
unchecked {
--_packedAddressData[from];
++_packedAddressData[to];
_packedOwnerships[tokenId] =
_addressToUint256(to) |
(block.timestamp << BITPOS_START_TIMESTAMP) |
BITMASK_NEXT_INITIALIZED;
if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
address from = address(uint160(prevOwnershipPacked));
if (approvalCheck) {
bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
isApprovedForAll(from, _msgSenderERC721A()) ||
getApproved(tokenId) == _msgSenderERC721A());
if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
delete _tokenApprovals[tokenId];
unchecked {
_packedAddressData[from] += (1 << BITPOS_NUMBER_BURNED) - 1;
_packedOwnerships[tokenId] =
_addressToUint256(from) |
(block.timestamp << BITPOS_START_TIMESTAMP) |
BITMASK_BURNED |
BITMASK_NEXT_INITIALIZED;
if (prevOwnershipPacked & BITMASK_NEXT_INITIALIZED == 0) {
uint256 nextTokenId = tokenId + 1;
if (_packedOwnerships[nextTokenId] == 0) {
if (nextTokenId != _currentIndex) {
_packedOwnerships[nextTokenId] = prevOwnershipPacked;
}
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
unchecked {
_burnCounter++;
}
}
function _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
bytes4 retval
) {
return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
function _toString(uint256 value) internal pure returns (string memory ptr) {
assembly {
ptr := add(mload(0x40), 128)
mstore(0x40, ptr)
let end := ptr
for {
let temp := value
ptr := sub(ptr, 1)
mstore8(ptr, add(48, mod(temp, 10)))
temp := div(temp, 10)
} temp {
temp := div(temp, 10)
} {
ptr := sub(ptr, 1)
mstore8(ptr, add(48, mod(temp, 10)))
}
let length := sub(end, ptr)
ptr := sub(ptr, 32)
mstore(ptr, length)
}
}
}
文件 4 的 9:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 5 的 9:IERC2981.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
interface IERC2981 is IERC165 {
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
文件 6 的 9:IERC721A.sol
pragma solidity ^0.8.4;
interface IERC721A {
error ApprovalCallerNotOwnerNorApproved();
error ApprovalQueryForNonexistentToken();
error ApproveToCaller();
error ApprovalToCurrentOwner();
error BalanceQueryForZeroAddress();
error MintToZeroAddress();
error MintZeroQuantity();
error OwnerQueryForNonexistentToken();
error TransferCallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
error TransferToNonERC721ReceiverImplementer();
error TransferToZeroAddress();
error URIQueryForNonexistentToken();
struct TokenOwnership {
address addr;
uint64 startTimestamp;
bool burned;
}
function totalSupply() external view returns (uint256);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
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 balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 7 的 9: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);
}
}
文件 8 的 9:StreetlabGenesis.sol
pragma solidity ^0.8.13;
import "erc721a/contracts/ERC721A.sol";
import "@openzeppelin/contracts/interfaces/IERC2981.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract StreetlabGenesis is ERC721A, Ownable {
event SalePhaseToggled(string phase, bool value);
event PriceChanged(uint256 value);
using ECDSA for bytes32;
mapping(uint256 => bool) internal _presaleNonces;
mapping(uint256 => bool) internal _giveawayNonces;
address private _openSeaProxyRegistryAddress;
address internal constant _crossMintAddress = 0xdAb1a1854214684acE522439684a145E62505233;
uint256 public giveaway = 116;
uint256 public price = 0.077 ether;
uint256 public maxSupply = 4444;
uint256 public maxTokensPerMint = 10;
uint256 public startingIndex;
bool private _isOpenSeaProxyRegistryEnabled = true;
bool public isGiveawayStarted;
bool public isPresaleStarted;
bool public isSaleStarted;
string public provenanceHash = "";
string public baseURI = "https://metadata-6e9t2e4f6v9jp.streetlab.io/";
constructor(
string memory name,
string memory symbol,
address openSeaProxyRegistryAddress
) ERC721A(name, symbol) {
_openSeaProxyRegistryAddress = openSeaProxyRegistryAddress;
}
function _mintPayable(address to, uint256 amount) internal {
uint256 supply = totalSupply();
require(supply + amount <= maxSupply - giveaway, "Not enough Tokens left.");
require(amount * price <= msg.value, "Inconsistent amount sent!");
_safeMint(to, amount);
}
function mintGiveaway(
uint256 amount,
uint256 nonce,
bytes memory sig
) external whenGiveawayStarted {
require(!_giveawayNonces[nonce], "Giveaway nonce already used.");
uint256 giveaway_ = giveaway;
require(amount <= giveaway_, "cannot exceed max giveaway.");
_giveawayNonces[nonce] = true;
giveaway = giveaway_ - amount;
_validateSig("giveaway", msg.sender, amount, nonce, sig);
_safeMint(msg.sender, amount);
}
function mintPresale(
uint256 amount,
uint256 maxToken,
uint256 nonce,
bytes memory sig
) external payable whenPresaleStarted {
require(amount <= maxToken, "Cannot mint more than maxTokens.");
require(!_presaleNonces[nonce], "Presale nonce already used.");
_presaleNonces[nonce] = true;
_validateSig("presale", msg.sender, maxToken, nonce, sig);
_mintPayable(msg.sender, amount);
}
function mintPresaleWithGiveaway(
uint256 amountGiveaway,
uint256 nonceGiveaway,
uint256 amountPresale,
uint256 maxTokenPresale,
uint256 noncePresale,
bytes memory sigGiveaway,
bytes memory sigPresale
) external payable {
if(amountPresale > 0) {
require(isPresaleStarted, "Presale not started");
require(amountPresale <= maxTokenPresale, "Cannot mint more than maxTokens.");
require(!_presaleNonces[noncePresale], "Presale nonce already used.");
_presaleNonces[noncePresale] = true;
_validateSig("presale", msg.sender, maxTokenPresale, noncePresale, sigPresale);
uint256 supply = totalSupply();
require(supply + amountPresale <= maxSupply - giveaway, "Not enough Tokens left.");
require(amountPresale * price <= msg.value, "Inconsistent amount sent!");
}
if(amountGiveaway > 0) {
require(isGiveawayStarted, "Giveaway not started");
require(!_giveawayNonces[nonceGiveaway], "Giveaway nonce already used.");
uint256 giveaway_ = giveaway;
require(amountGiveaway <= giveaway_, "cannot exceed max giveaway.");
_giveawayNonces[nonceGiveaway] = true;
giveaway = giveaway_ - amountGiveaway;
_validateSig("giveaway", msg.sender, amountGiveaway, nonceGiveaway, sigGiveaway);
}
_safeMint(msg.sender, amountGiveaway + amountPresale);
}
function mintWithGiveaway(
uint256 amountPublic,
uint256 amountGiveaway,
uint256 nonceGiveaway,
bytes memory sigGiveaway
) external payable {
if(amountPublic > 0) {
require(amountPublic <= maxTokensPerMint, "maxTokensPerMint exceeded!");
uint256 supply = totalSupply();
require(supply + amountPublic <= maxSupply - giveaway, "Not enough Tokens left.");
require(amountPublic * price <= msg.value, "Inconsistent amount sent!");
}
if(amountGiveaway > 0) {
require(isGiveawayStarted, "Giveaway not started");
require(!_giveawayNonces[nonceGiveaway], "Giveaway nonce already used.");
uint256 giveaway_ = giveaway;
require(amountGiveaway <= giveaway_, "cannot exceed max giveaway.");
_giveawayNonces[nonceGiveaway] = true;
giveaway = giveaway_ - amountGiveaway;
_validateSig("giveaway", msg.sender, amountGiveaway, nonceGiveaway, sigGiveaway);
}
_safeMint(msg.sender, amountGiveaway + amountPublic);
}
function mintTo(address to, uint256 amount) external payable whenSaleStarted {
require(msg.sender == _crossMintAddress, "This function is for Crossmint only.");
require(amount <= maxTokensPerMint, "maxTokensPerMint exceeded!");
_mintPayable(to, amount);
}
function mint(uint256 amount) public payable whenSaleStarted {
require(amount <= maxTokensPerMint, "maxTokensPerMint exceeded!");
_mintPayable(msg.sender, amount);
}
function claimGiveaway(uint256 amount, address receiver) external onlyOwner {
require(amount <= giveaway, "cannot exceed max giveaway.");
giveaway = giveaway - amount;
_safeMint(receiver, amount);
}
function _validateSig(string memory phase, address sender, uint256 amount, uint256 nonce, bytes memory sig) internal view {
bytes32 hash = keccak256(abi.encode(phase, sender, amount, nonce, address(this)));
address signerAddress = hash.toEthSignedMessageHash().recover(sig);
require(signerAddress == owner(), "Invalid signature!");
}
function isApprovedForAll(address owner, address operator) public view override returns (bool) {
if(_isOpenSeaProxyRegistryEnabled) {
ProxyRegistry proxyRegistry = ProxyRegistry(_openSeaProxyRegistryAddress);
if (address(proxyRegistry.proxies(owner)) == operator) {
return true;
}
}
return super.isApprovedForAll(owner, operator);
}
function _baseURI() internal view virtual override(ERC721A) returns (string memory) {
return baseURI;
}
modifier whenPresaleStarted {
require(isPresaleStarted, "Presale not started");
_;
}
modifier whenSaleStarted() {
require(isSaleStarted, "Sale not started");
_;
}
modifier whenGiveawayStarted() {
require(isGiveawayStarted, "Giveaway not started");
_;
}
function withdraw() public onlyOwner {
uint256 balance = address(this).balance;
require(payable(owner()).send(balance), "Balance transfer failed.");
}
function setBaseURI(string calldata uri) external onlyOwner {
baseURI = uri;
}
function setPrice(uint256 newPrice) external onlyOwner {
price = newPrice;
emit PriceChanged(newPrice);
}
function setProvenanceHash(string memory provenanceHash_) public onlyOwner {
provenanceHash = provenanceHash_;
}
function setOpenSeaProxyRegistryEnabled(bool enabled) external onlyOwner {
_isOpenSeaProxyRegistryEnabled = enabled;
}
function toggleGiveawayStarted() external onlyOwner {
bool status = isGiveawayStarted;
isGiveawayStarted = !status;
if (isGiveawayStarted && startingIndex == 0) {
setStartingIndex();
}
emit SalePhaseToggled('giveaway', !status);
}
function togglePresaleStarted() external onlyOwner {
bool status = isPresaleStarted;
isPresaleStarted = !status;
if (isPresaleStarted && startingIndex == 0) {
setStartingIndex();
}
emit SalePhaseToggled('presale', !status);
}
function toggleSaleStarted() external onlyOwner {
bool status = isSaleStarted;
isSaleStarted = !status;
if (!status) {
isPresaleStarted = false;
emit SalePhaseToggled('presale', false);
}
if (isSaleStarted && startingIndex == 0) {
setStartingIndex();
}
emit SalePhaseToggled('public', !status);
}
function validGiveawayNonce(uint256 nonce) external view returns(bool) {
return !_giveawayNonces[nonce];
}
function validPresaleNonce(uint256 nonce) external view returns(bool) {
return !_presaleNonces[nonce];
}
function setStartingIndex() public {
require(startingIndex == 0, "Starting index is already set");
uint256 blockShift = uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp)));
blockShift = 1 + (blockShift % 255);
if (block.number < blockShift) {
blockShift = 1;
}
uint256 blockRef = block.number - blockShift;
startingIndex = uint(blockhash(blockRef)) % maxSupply;
if (startingIndex == 0) {
startingIndex = startingIndex + 1;
}
}
}
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
文件 9 的 9:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
{
"compilationTarget": {
"contracts/StreetlabGenesis.sol": "StreetlabGenesis"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"openSeaProxyRegistryAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"value","type":"uint256"}],"name":"PriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"phase","type":"string"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"SalePhaseToggled","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":"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":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"claimGiveaway","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":"giveaway","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"isGiveawayStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPresaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensPerMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"mintGiveaway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxToken","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"mintPresale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountGiveaway","type":"uint256"},{"internalType":"uint256","name":"nonceGiveaway","type":"uint256"},{"internalType":"uint256","name":"amountPresale","type":"uint256"},{"internalType":"uint256","name":"maxTokenPresale","type":"uint256"},{"internalType":"uint256","name":"noncePresale","type":"uint256"},{"internalType":"bytes","name":"sigGiveaway","type":"bytes"},{"internalType":"bytes","name":"sigPresale","type":"bytes"}],"name":"mintPresaleWithGiveaway","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountPublic","type":"uint256"},{"internalType":"uint256","name":"amountGiveaway","type":"uint256"},{"internalType":"uint256","name":"nonceGiveaway","type":"uint256"},{"internalType":"bytes","name":"sigGiveaway","type":"bytes"}],"name":"mintWithGiveaway","outputs":[],"stateMutability":"payable","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":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provenanceHash","outputs":[{"internalType":"string","name":"","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":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setOpenSeaProxyRegistryEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"provenanceHash_","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"toggleGiveawayStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePresaleStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleSaleStarted","outputs":[],"stateMutability":"nonpayable","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":"nonce","type":"uint256"}],"name":"validGiveawayNonce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"validPresaleNonce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]