¡El código fuente de este contrato está verificado!
Metadatos del Contrato
Compilador
0.8.19+commit.7dd6d404
Idioma
Solidity
¡El código fuente de este contrato está verificado!
Metadatos del Contrato
Compilador
0.8.9+commit.e5eed63a
Idioma
Solidity
Código Fuente del Contrato
Archivo 1 de 30: Address.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)pragmasolidity ^0.8.0;/**
* @dev Collection of functions related to the address type
*/libraryAddress{
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;
assembly {
size :=extcodesize(account)
}
return size >0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target,
bytesmemory data,
uint256 value
) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target,
bytesmemory data,
uint256 value,
stringmemory errorMessage
) internalreturns (bytesmemory) {
require(address(this).balance>= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytesmemory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data) internalviewreturns (bytesmemory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalviewreturns (bytesmemory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytesmemory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalreturns (bytesmemory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytesmemory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/functionverifyCallResult(bool success,
bytesmemory returndata,
stringmemory errorMessage
) internalpurereturns (bytesmemory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if presentif (returndata.length>0) {
// The easiest way to bubble the revert reason is using memory via assemblyassembly {
let returndata_size :=mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Código Fuente del Contrato
Archivo 2 de 30: Base64.sol
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;// shamelessly stolen from the anonymice contractlibraryBase64{
stringinternalconstant TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* @dev Converts the input data into a base64 string.
*/functionencode(bytesmemory data) internalpurereturns (stringmemory) {
if (data.length==0) return"";
// load the table into memorystringmemory table = TABLE;
// multiply by 4/3 rounded upuint256 encodedLen =4* ((data.length+2) /3);
// add some extra buffer at the end required for the writingstringmemory result =newstring(encodedLen +32);
assembly {
// set the actual output lengthmstore(result, encodedLen)
// prepare the lookup tablelet tablePtr :=add(table, 1)
// input ptrlet dataPtr := data
let endPtr :=add(dataPtr, mload(data))
// result ptr, jump over lengthlet resultPtr :=add(result, 32)
// run over the input, 3 bytes at a timefor {
} lt(dataPtr, endPtr) {
} {
dataPtr :=add(dataPtr, 3)
// read 3 byteslet input :=mload(dataPtr)
// write 4 charactersmstore(
resultPtr,
shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))
)
resultPtr :=add(resultPtr, 1)
mstore(
resultPtr,
shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))
)
resultPtr :=add(resultPtr, 1)
mstore(
resultPtr,
shl(248, mload(add(tablePtr, and(shr(6, input), 0x3F))))
)
resultPtr :=add(resultPtr, 1)
mstore(
resultPtr,
shl(248, mload(add(tablePtr, and(input, 0x3F))))
)
resultPtr :=add(resultPtr, 1)
}
// padding with '='switchmod(mload(data), 3)
case1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
}
return result;
}
}
Código Fuente del Contrato
Archivo 3 de 30: BaseTokenURIProvider.sol
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./ITokenURIProvider.sol";
import"./OpenSeaMetadata.sol";
import"./ChainScoutsExtension.sol";
import"@openzeppelin/contracts/utils/Strings.sol";
/**
* Base class for all Token URI providers. Giving a new implementation of this class allows you to change how the metadata is created.
*/abstractcontractBaseTokenURIProviderisITokenURIProvider, ChainScoutsExtension{
stringprivate baseName;
stringprivate defaultDescription;
mapping (uint=>string) private names;
mapping (uint=>string) private descriptions;
constructor(stringmemory _baseName, stringmemory _defaultDescription) {
baseName = _baseName;
defaultDescription = _defaultDescription;
}
modifierstringIsJsonSafe(stringmemory str) {
bytesmemory b =bytes(str);
for (uint i =0; i < b.length; ++i) {
uint8 char =uint8(b[i]);
// 0-9 A-Z a-z spaceif (!(char >=48&& char <=57|| char >=65&& char <=90|| char >=97&& char <=122|| char ==32)) {
revert("BaseTokenURIProvider: All chars must be spaces or alphanumeric");
}
}
_;
}
/**
* @dev Sets the description of a token on OpenSea.
* Must be an admin or the owner of the token.
*
* The description may only contain A-Z, a-z, 0-9, or spaces.
*/functionsetDescription(uint tokenId, stringmemory description) externalcanAccessToken(tokenId) stringIsJsonSafe(description) {
descriptions[tokenId] = description;
}
/**
* @dev Sets the description of a token on OpenSea.
* Must be an admin or the owner of the token.
*
* The name may only contain A-Z, a-z, 0-9, or spaces.
*/functionsetName(uint tokenId, stringmemory name) externalcanAccessToken(tokenId) stringIsJsonSafe(name) {
names[tokenId] = name;
}
/**
* @dev Gets the background color of the given token ID as it appears on OpenSea.
*/functiontokenBgColor(uint tokenId) internalviewvirtualreturns (uint24);
/**
* @dev Gets the SVG of the given token ID.
*/functiontokenSvg(uint tokenId) publicviewvirtualreturns (stringmemory);
/**
* @dev Gets the OpenSea attributes of the given token ID.
*/functiontokenAttributes(uint tokenId) internalviewvirtualreturns (Attribute[] memory);
/**
* @dev Gets the OpenSea token URI of the given token ID.
*/functiontokenURI(uint tokenId) externalviewoverridereturns (stringmemory) {
stringmemory name = names[tokenId];
if (bytes(name).length==0) {
name =string(abi.encodePacked(
baseName,
" #",
Strings.toString(tokenId)
));
}
stringmemory description = descriptions[tokenId];
if (bytes(description).length==0) {
description = defaultDescription;
}
return OpenSeaMetadataLibrary.makeMetadata(OpenSeaMetadata(
tokenSvg(tokenId),
description,
name,
tokenBgColor(tokenId),
tokenAttributes(tokenId)
));
}
}
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./IChainScouts.sol";
abstractcontractChainScoutsExtension{
IChainScouts internal chainScouts;
boolpublic enabled =true;
modifiercanAccessToken(uint tokenId) {
require(chainScouts.canAccessToken(msg.sender, tokenId), "ChainScoutsExtension: you don't own the token");
_;
}
modifieronlyAdmin() {
require(chainScouts.isAdmin(msg.sender), "ChainScoutsExtension: admins only");
_;
}
modifierwhenEnabled() {
require(enabled, "ChainScoutsExtension: currently disabled");
_;
}
functionadminSetEnabled(bool e) externalonlyAdmin{
enabled = e;
}
functionextensionKey() publicvirtualviewreturns (stringmemory);
functionsetChainScouts(IChainScouts _contract) external{
require(address(0) ==address(chainScouts) || chainScouts.isAdmin(msg.sender), "ChainScoutsExtension: The Chain Scouts contract must not be set or you must be an admin");
chainScouts = _contract;
chainScouts.adminSetExtension(extensionKey(), this);
}
}
Código Fuente del Contrato
Archivo 7 de 30: Context.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)pragmasolidity ^0.8.0;/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
returnmsg.data;
}
}
Código Fuente del Contrato
Archivo 8 de 30: ERC165.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)pragmasolidity ^0.8.0;import"./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/abstractcontractERC165isIERC165{
/**
* @dev See {IERC165-supportsInterface}.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualoverridereturns (bool) {
return interfaceId ==type(IERC165).interfaceId;
}
}
Código Fuente del Contrato
Archivo 9 de 30: ERC721A.sol
// SPDX-License-Identifier: MIT// Creator: Chiru Labspragmasolidity ^0.8.4;import'@openzeppelin/contracts/token/ERC721/IERC721.sol';
import'@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
import'@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';
import'@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol';
import'@openzeppelin/contracts/utils/Address.sol';
import'@openzeppelin/contracts/utils/Context.sol';
import'@openzeppelin/contracts/utils/Strings.sol';
import'@openzeppelin/contracts/utils/introspection/ERC165.sol';
errorApprovalCallerNotOwnerNorApproved();
errorApprovalQueryForNonexistentToken();
errorApproveToCaller();
errorApprovalToCurrentOwner();
errorBalanceQueryForZeroAddress();
errorMintedQueryForZeroAddress();
errorBurnedQueryForZeroAddress();
errorMintToZeroAddress();
errorMintZeroQuantity();
errorOwnerIndexOutOfBounds();
errorOwnerQueryForNonexistentToken();
errorTokenIndexOutOfBounds();
errorTransferCallerNotOwnerNorApproved();
errorTransferFromIncorrectOwner();
errorTransferToNonERC721ReceiverImplementer();
errorTransferToZeroAddress();
errorURIQueryForNonexistentToken();
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints.
*
* Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..).
*
* Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
*
* Assumes that the maximum token id cannot exceed 2**128 - 1 (max value of uint128).
*/contractERC721AisContext, ERC165, IERC721, IERC721Metadata, IERC721Enumerable{
usingAddressforaddress;
usingStringsforuint256;
// Compiler will pack this into a single 256bit word.structTokenOwnership {
// The address of the owner.address addr;
// Keeps track of the start time of ownership with minimal overhead for tokenomics.uint64 startTimestamp;
// Whether the token has been burned.bool burned;
}
// Compiler will pack this into a single 256bit word.structAddressData {
// Realistically, 2**64-1 is more than enough.uint64 balance;
// Keeps track of mint count with minimal overhead for tokenomics.uint64 numberMinted;
// Keeps track of burn count with minimal overhead for tokenomics.uint64 numberBurned;
}
// Compiler will pack the following // _currentIndex and _burnCounter into a single 256bit word.// The tokenId of the next token to be minted.uint128internal _currentIndex;
// The number of tokens burned.uint128internal _burnCounter;
// Token namestringprivate _name;
// Token symbolstringprivate _symbol;
// Mapping from token ID to ownership details// An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.mapping(uint256=> TokenOwnership) internal _ownerships;
// Mapping owner address to address datamapping(address=> AddressData) private _addressData;
// Mapping from token ID to approved addressmapping(uint256=>address) private _tokenApprovals;
// Mapping from owner to operator approvalsmapping(address=>mapping(address=>bool)) private _operatorApprovals;
constructor(stringmemory name_, stringmemory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC721Enumerable-totalSupply}.
*/functiontotalSupply() publicviewoverridereturns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented// more than _currentIndex timesunchecked {
return _currentIndex - _burnCounter;
}
}
/**
* @dev See {IERC721Enumerable-tokenByIndex}.
* This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first.
* It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
*/functiontokenByIndex(uint256 index) publicviewoverridereturns (uint256) {
uint256 numMintedSoFar = _currentIndex;
uint256 tokenIdsIdx;
// Counter overflow is impossible as the loop breaks when// uint256 i is equal to another uint256 numMintedSoFar.unchecked {
for (uint256 i; i < numMintedSoFar; i++) {
TokenOwnership memory ownership = _ownerships[i];
if (!ownership.burned) {
if (tokenIdsIdx == index) {
return i;
}
tokenIdsIdx++;
}
}
}
revert TokenIndexOutOfBounds();
}
/**
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
* This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first.
* It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
*/functiontokenOfOwnerByIndex(address owner, uint256 index) publicviewoverridereturns (uint256) {
if (index >= balanceOf(owner)) revert OwnerIndexOutOfBounds();
uint256 numMintedSoFar = _currentIndex;
uint256 tokenIdsIdx;
address currOwnershipAddr;
// Counter overflow is impossible as the loop breaks when// uint256 i is equal to another uint256 numMintedSoFar.unchecked {
for (uint256 i; i < numMintedSoFar; i++) {
TokenOwnership memory ownership = _ownerships[i];
if (ownership.burned) {
continue;
}
if (ownership.addr !=address(0)) {
currOwnershipAddr = ownership.addr;
}
if (currOwnershipAddr == owner) {
if (tokenIdsIdx == index) {
return i;
}
tokenIdsIdx++;
}
}
}
// Execution should never reach this point.revert();
}
/**
* @dev See {IERC165-supportsInterface}.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualoverride(ERC165, IERC165) returns (bool) {
return
interfaceId ==type(IERC721).interfaceId||
interfaceId ==type(IERC721Metadata).interfaceId||
interfaceId ==type(IERC721Enumerable).interfaceId||super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/functionbalanceOf(address owner) publicviewoverridereturns (uint256) {
if (owner ==address(0)) revert BalanceQueryForZeroAddress();
returnuint256(_addressData[owner].balance);
}
function_numberMinted(address owner) internalviewreturns (uint256) {
if (owner ==address(0)) revert MintedQueryForZeroAddress();
returnuint256(_addressData[owner].numberMinted);
}
function_numberBurned(address owner) internalviewreturns (uint256) {
if (owner ==address(0)) revert BurnedQueryForZeroAddress();
returnuint256(_addressData[owner].numberBurned);
}
/**
* Gas spent here starts off proportional to the maximum mint batch size.
* It gradually moves to O(1) as tokens get transferred around in the collection over time.
*/functionownershipOf(uint256 tokenId) internalviewreturns (TokenOwnership memory) {
uint256 curr = tokenId;
unchecked {
if (curr < _currentIndex) {
TokenOwnership memory ownership = _ownerships[curr];
if (!ownership.burned) {
if (ownership.addr !=address(0)) {
return ownership;
}
// Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned.// Hence, curr will not underflow.while (true) {
curr--;
ownership = _ownerships[curr];
if (ownership.addr !=address(0)) {
return ownership;
}
}
}
}
}
revert OwnerQueryForNonexistentToken();
}
/**
* @dev See {IERC721-ownerOf}.
*/functionownerOf(uint256 tokenId) publicviewoverridereturns (address) {
return ownershipOf(tokenId).addr;
}
/**
* @dev See {IERC721Metadata-name}.
*/functionname() publicviewvirtualoverridereturns (stringmemory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/functionsymbol() publicviewvirtualoverridereturns (stringmemory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/functiontokenURI(uint256 tokenId) publicviewvirtualoverridereturns (stringmemory) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
stringmemory baseURI = _baseURI();
returnbytes(baseURI).length!=0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/function_baseURI() internalviewvirtualreturns (stringmemory) {
return'';
}
/**
* @dev See {IERC721-approve}.
*/functionapprove(address to, uint256 tokenId) publicoverride{
address owner = ERC721A.ownerOf(tokenId);
if (to == owner) revert ApprovalToCurrentOwner();
if (_msgSender() != owner &&!isApprovedForAll(owner, _msgSender())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_approve(to, tokenId, owner);
}
/**
* @dev See {IERC721-getApproved}.
*/functiongetApproved(uint256 tokenId) publicviewoverridereturns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/functionsetApprovalForAll(address operator, bool approved) publicoverride{
if (operator == _msgSender()) revert ApproveToCaller();
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/functionisApprovedForAll(address owner, address operator) publicviewvirtualoverridereturns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/functiontransferFrom(addressfrom,
address to,
uint256 tokenId
) publicvirtualoverride{
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId
) publicvirtualoverride{
safeTransferFrom(from, to, tokenId, '');
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId,
bytesmemory _data
) publicvirtualoverride{
_transfer(from, to, tokenId);
if (!_checkOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
*/function_exists(uint256 tokenId) internalviewreturns (bool) {
return tokenId < _currentIndex &&!_ownerships[tokenId].burned;
}
function_safeMint(address to, uint256 quantity) internal{
_safeMint(to, quantity, '');
}
/**
* @dev Safely mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event.
*/function_safeMint(address to,
uint256 quantity,
bytesmemory _data
) internal{
_mint(to, quantity, _data, true);
}
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event.
*/function_mint(address to,
uint256 quantity,
bytesmemory _data,
bool safe
) internal{
uint256 startTokenId = _currentIndex;
if (to ==address(0)) revert MintToZeroAddress();
if (quantity ==0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.// balance or numberMinted overflow if current value of either + quantity > 3.4e38 (2**128) - 1// updatedIndex overflows if _currentIndex + quantity > 3.4e38 (2**128) - 1unchecked {
_addressData[to].balance+=uint64(quantity);
_addressData[to].numberMinted +=uint64(quantity);
_ownerships[startTokenId].addr = to;
_ownerships[startTokenId].startTimestamp =uint64(block.timestamp);
uint256 updatedIndex = startTokenId;
for (uint256 i; i < quantity; i++) {
emit Transfer(address(0), to, updatedIndex);
if (safe &&!_checkOnERC721Received(address(0), to, updatedIndex, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
updatedIndex++;
}
_currentIndex =uint128(updatedIndex);
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/function_transfer(addressfrom,
address to,
uint256 tokenId
) private{
TokenOwnership memory prevOwnership = ownershipOf(tokenId);
bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
isApprovedForAll(prevOwnership.addr, _msgSender()) ||
getApproved(tokenId) == _msgSender());
if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
if (prevOwnership.addr !=from) revert TransferFromIncorrectOwner();
if (to ==address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
// Clear approvals from the previous owner
_approve(address(0), tokenId, prevOwnership.addr);
// Underflow of the sender's balance is impossible because we check for// ownership above and the recipient's balance can't realistically overflow.// Counter overflow is incredibly unrealistic as tokenId would have to be 2**128.unchecked {
_addressData[from].balance-=1;
_addressData[to].balance+=1;
_ownerships[tokenId].addr = to;
_ownerships[tokenId].startTimestamp =uint64(block.timestamp);
// If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.// Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.uint256 nextTokenId = tokenId +1;
if (_ownerships[nextTokenId].addr ==address(0)) {
// This will suffice for checking _exists(nextTokenId),// as a burned slot cannot contain the zero address.if (nextTokenId < _currentIndex) {
_ownerships[nextTokenId].addr = prevOwnership.addr;
_ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/function_burn(uint256 tokenId) internalvirtual{
TokenOwnership memory prevOwnership = ownershipOf(tokenId);
_beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);
// Clear approvals from the previous owner
_approve(address(0), tokenId, prevOwnership.addr);
// Underflow of the sender's balance is impossible because we check for// ownership above and the recipient's balance can't realistically overflow.// Counter overflow is incredibly unrealistic as tokenId would have to be 2**128.unchecked {
_addressData[prevOwnership.addr].balance-=1;
_addressData[prevOwnership.addr].numberBurned +=1;
// Keep track of who burned the token, and the timestamp of burning.
_ownerships[tokenId].addr = prevOwnership.addr;
_ownerships[tokenId].startTimestamp =uint64(block.timestamp);
_ownerships[tokenId].burned =true;
// If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.// Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.uint256 nextTokenId = tokenId +1;
if (_ownerships[nextTokenId].addr ==address(0)) {
// This will suffice for checking _exists(nextTokenId),// as a burned slot cannot contain the zero address.if (nextTokenId < _currentIndex) {
_ownerships[nextTokenId].addr = prevOwnership.addr;
_ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
}
}
}
emit Transfer(prevOwnership.addr, address(0), tokenId);
_afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.unchecked {
_burnCounter++;
}
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/function_approve(address to,
uint256 tokenId,
address owner
) private{
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/function_checkOnERC721Received(addressfrom,
address to,
uint256 tokenId,
bytesmemory _data
) privatereturns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytesmemory reason) {
if (reason.length==0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
returntrue;
}
}
/**
* @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
* And also called before burning one token.
*
* startTokenId - the first token id to be transferred
* quantity - the amount to be transferred
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/function_beforeTokenTransfers(addressfrom,
address to,
uint256 startTokenId,
uint256 quantity
) internalvirtual{}
/**
* @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
* minting.
* And also called after one token has been burned.
*
* startTokenId - the first token id to be transferred
* quantity - the amount to be transferred
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
* transferred to `to`.
* - When `from` is zero, `tokenId` has been minted for `to`.
* - When `to` is zero, `tokenId` has been burned by `from`.
* - `from` and `to` are never both zero.
*/function_afterTokenTransfers(addressfrom,
address to,
uint256 startTokenId,
uint256 quantity
) internalvirtual{}
}
Código Fuente del Contrato
Archivo 10 de 30: Enums.sol
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;enumAccessory {
GOLD_EARRINGS,
SCARS,
GOLDEN_CHAIN,
AMULET,
CUBAN_LINK_GOLD_CHAIN,
FANNY_PACK,
NONE
}
enumBackAccessory {
NETRUNNER,
MERCENARY,
RONIN,
ENCHANTER,
VANGUARD,
MINER,
PATHFINDER,
SCOUT
}
enumBackground {
STARRY_PINK,
STARRY_YELLOW,
STARRY_PURPLE,
STARRY_GREEN,
NEBULA,
STARRY_RED,
STARRY_BLUE,
SUNSET,
MORNING,
INDIGO,
CITY__PURPLE,
CONTROL_ROOM,
LAB,
GREEN,
ORANGE,
PURPLE,
CITY__GREEN,
CITY__RED,
STATION,
BOUNTY,
BLUE_SKY,
RED_SKY,
GREEN_SKY
}
enumClothing {
MARTIAL_SUIT,
AMETHYST_ARMOR,
SHIRT_AND_TIE,
THUNDERDOME_ARMOR,
FLEET_UNIFORM__BLUE,
BANANITE_SHIRT,
EXPLORER,
COSMIC_GHILLIE_SUIT__BLUE,
COSMIC_GHILLIE_SUIT__GOLD,
CYBER_JUMPSUIT,
ENCHANTER_ROBES,
HOODIE,
SPACESUIT,
MECHA_ARMOR,
LAB_COAT,
FLEET_UNIFORM__RED,
GOLD_ARMOR,
ENERGY_ARMOR__BLUE,
ENERGY_ARMOR__RED,
MISSION_SUIT__BLACK,
MISSION_SUIT__PURPLE,
COWBOY,
GLITCH_ARMOR,
NONE
}
enumEyes {
SPACE_VISOR,
ADORABLE,
VETERAN,
SUNGLASSES,
WHITE_SUNGLASSES,
RED_EYES,
WINK,
CASUAL,
CLOSED,
DOWNCAST,
HAPPY,
BLUE_EYES,
HUD_GLASSES,
DARK_SUNGLASSES,
NIGHT_VISION_GOGGLES,
BIONIC,
HIVE_GOGGLES,
MATRIX_GLASSES,
GREEN_GLOW,
ORANGE_GLOW,
RED_GLOW,
PURPLE_GLOW,
BLUE_GLOW,
SKY_GLOW,
RED_LASER,
BLUE_LASER,
GOLDEN_SHADES,
HIPSTER_GLASSES,
PINCENEZ,
BLUE_SHADES,
BLIT_GLASSES,
NOUNS_GLASSES
}
enumFur {
MAGENTA,
BLUE,
GREEN,
RED,
BLACK,
BROWN,
SILVER,
PURPLE,
PINK,
SEANCE,
TURQUOISE,
CRIMSON,
GREENYELLOW,
GOLD,
DIAMOND,
METALLIC
}
enumHead {
HALO,
ENERGY_FIELD,
BLUE_TOP_HAT,
RED_TOP_HAT,
ENERGY_CRYSTAL,
CROWN,
BANDANA,
BUCKET_HAT,
HOMBURG_HAT,
PROPELLER_HAT,
HEADBAND,
DORAG,
PURPLE_COWBOY_HAT,
SPACESUIT_HELMET,
PARTY_HAT,
CAP,
LEATHER_COWBOY_HAT,
CYBER_HELMET__BLUE,
CYBER_HELMET__RED,
SAMURAI_HAT,
NONE
}
enumMouth {
SMIRK,
SURPRISED,
SMILE,
PIPE,
OPEN_SMILE,
NEUTRAL,
MASK,
TONGUE_OUT,
GOLD_GRILL,
DIAMOND_GRILL,
NAVY_RESPIRATOR,
RED_RESPIRATOR,
MAGENTA_RESPIRATOR,
GREEN_RESPIRATOR,
MEMPO,
VAPE,
PILOT_OXYGEN_MASK,
CIGAR,
BANANA,
CHROME_RESPIRATOR,
STOIC
}
libraryEnums{
functiontoString(Accessory v) externalpurereturns (stringmemory) {
if (v == Accessory.GOLD_EARRINGS) {
return"Gold Earrings";
}
if (v == Accessory.SCARS) {
return"Scars";
}
if (v == Accessory.GOLDEN_CHAIN) {
return"Golden Chain";
}
if (v == Accessory.AMULET) {
return"Amulet";
}
if (v == Accessory.CUBAN_LINK_GOLD_CHAIN) {
return"Cuban Link Gold Chain";
}
if (v == Accessory.FANNY_PACK) {
return"Fanny Pack";
}
if (v == Accessory.NONE) {
return"None";
}
revert("invalid accessory");
}
functiontoString(BackAccessory v) externalpurereturns (stringmemory) {
if (v == BackAccessory.NETRUNNER) {
return"Netrunner";
}
if (v == BackAccessory.MERCENARY) {
return"Mercenary";
}
if (v == BackAccessory.RONIN) {
return"Ronin";
}
if (v == BackAccessory.ENCHANTER) {
return"Enchanter";
}
if (v == BackAccessory.VANGUARD) {
return"Vanguard";
}
if (v == BackAccessory.MINER) {
return"Miner";
}
if (v == BackAccessory.PATHFINDER) {
return"Pathfinder";
}
if (v == BackAccessory.SCOUT) {
return"Scout";
}
revert("invalid back accessory");
}
functiontoString(Background v) externalpurereturns (stringmemory) {
if (v == Background.STARRY_PINK) {
return"Starry Pink";
}
if (v == Background.STARRY_YELLOW) {
return"Starry Yellow";
}
if (v == Background.STARRY_PURPLE) {
return"Starry Purple";
}
if (v == Background.STARRY_GREEN) {
return"Starry Green";
}
if (v == Background.NEBULA) {
return"Nebula";
}
if (v == Background.STARRY_RED) {
return"Starry Red";
}
if (v == Background.STARRY_BLUE) {
return"Starry Blue";
}
if (v == Background.SUNSET) {
return"Sunset";
}
if (v == Background.MORNING) {
return"Morning";
}
if (v == Background.INDIGO) {
return"Indigo";
}
if (v == Background.CITY__PURPLE) {
return"City - Purple";
}
if (v == Background.CONTROL_ROOM) {
return"Control Room";
}
if (v == Background.LAB) {
return"Lab";
}
if (v == Background.GREEN) {
return"Green";
}
if (v == Background.ORANGE) {
return"Orange";
}
if (v == Background.PURPLE) {
return"Purple";
}
if (v == Background.CITY__GREEN) {
return"City - Green";
}
if (v == Background.CITY__RED) {
return"City - Red";
}
if (v == Background.STATION) {
return"Station";
}
if (v == Background.BOUNTY) {
return"Bounty";
}
if (v == Background.BLUE_SKY) {
return"Blue Sky";
}
if (v == Background.RED_SKY) {
return"Red Sky";
}
if (v == Background.GREEN_SKY) {
return"Green Sky";
}
revert("invalid background");
}
functiontoString(Clothing v) externalpurereturns (stringmemory) {
if (v == Clothing.MARTIAL_SUIT) {
return"Martial Suit";
}
if (v == Clothing.AMETHYST_ARMOR) {
return"Amethyst Armor";
}
if (v == Clothing.SHIRT_AND_TIE) {
return"Shirt and Tie";
}
if (v == Clothing.THUNDERDOME_ARMOR) {
return"Thunderdome Armor";
}
if (v == Clothing.FLEET_UNIFORM__BLUE) {
return"Fleet Uniform - Blue";
}
if (v == Clothing.BANANITE_SHIRT) {
return"Bananite Shirt";
}
if (v == Clothing.EXPLORER) {
return"Explorer";
}
if (v == Clothing.COSMIC_GHILLIE_SUIT__BLUE) {
return"Cosmic Ghillie Suit - Blue";
}
if (v == Clothing.COSMIC_GHILLIE_SUIT__GOLD) {
return"Cosmic Ghillie Suit - Gold";
}
if (v == Clothing.CYBER_JUMPSUIT) {
return"Cyber Jumpsuit";
}
if (v == Clothing.ENCHANTER_ROBES) {
return"Enchanter Robes";
}
if (v == Clothing.HOODIE) {
return"Hoodie";
}
if (v == Clothing.SPACESUIT) {
return"Spacesuit";
}
if (v == Clothing.MECHA_ARMOR) {
return"Mecha Armor";
}
if (v == Clothing.LAB_COAT) {
return"Lab Coat";
}
if (v == Clothing.FLEET_UNIFORM__RED) {
return"Fleet Uniform - Red";
}
if (v == Clothing.GOLD_ARMOR) {
return"Gold Armor";
}
if (v == Clothing.ENERGY_ARMOR__BLUE) {
return"Energy Armor - Blue";
}
if (v == Clothing.ENERGY_ARMOR__RED) {
return"Energy Armor - Red";
}
if (v == Clothing.MISSION_SUIT__BLACK) {
return"Mission Suit - Black";
}
if (v == Clothing.MISSION_SUIT__PURPLE) {
return"Mission Suit - Purple";
}
if (v == Clothing.COWBOY) {
return"Cowboy";
}
if (v == Clothing.GLITCH_ARMOR) {
return"Glitch Armor";
}
if (v == Clothing.NONE) {
return"None";
}
revert("invalid clothing");
}
functiontoString(Eyes v) externalpurereturns (stringmemory) {
if (v == Eyes.SPACE_VISOR) {
return"Space Visor";
}
if (v == Eyes.ADORABLE) {
return"Adorable";
}
if (v == Eyes.VETERAN) {
return"Veteran";
}
if (v == Eyes.SUNGLASSES) {
return"Sunglasses";
}
if (v == Eyes.WHITE_SUNGLASSES) {
return"White Sunglasses";
}
if (v == Eyes.RED_EYES) {
return"Red Eyes";
}
if (v == Eyes.WINK) {
return"Wink";
}
if (v == Eyes.CASUAL) {
return"Casual";
}
if (v == Eyes.CLOSED) {
return"Closed";
}
if (v == Eyes.DOWNCAST) {
return"Downcast";
}
if (v == Eyes.HAPPY) {
return"Happy";
}
if (v == Eyes.BLUE_EYES) {
return"Blue Eyes";
}
if (v == Eyes.HUD_GLASSES) {
return"HUD Glasses";
}
if (v == Eyes.DARK_SUNGLASSES) {
return"Dark Sunglasses";
}
if (v == Eyes.NIGHT_VISION_GOGGLES) {
return"Night Vision Goggles";
}
if (v == Eyes.BIONIC) {
return"Bionic";
}
if (v == Eyes.HIVE_GOGGLES) {
return"Hive Goggles";
}
if (v == Eyes.MATRIX_GLASSES) {
return"Matrix Glasses";
}
if (v == Eyes.GREEN_GLOW) {
return"Green Glow";
}
if (v == Eyes.ORANGE_GLOW) {
return"Orange Glow";
}
if (v == Eyes.RED_GLOW) {
return"Red Glow";
}
if (v == Eyes.PURPLE_GLOW) {
return"Purple Glow";
}
if (v == Eyes.BLUE_GLOW) {
return"Blue Glow";
}
if (v == Eyes.SKY_GLOW) {
return"Sky Glow";
}
if (v == Eyes.RED_LASER) {
return"Red Laser";
}
if (v == Eyes.BLUE_LASER) {
return"Blue Laser";
}
if (v == Eyes.GOLDEN_SHADES) {
return"Golden Shades";
}
if (v == Eyes.HIPSTER_GLASSES) {
return"Hipster Glasses";
}
if (v == Eyes.PINCENEZ) {
return"Pince-nez";
}
if (v == Eyes.BLUE_SHADES) {
return"Blue Shades";
}
if (v == Eyes.BLIT_GLASSES) {
return"Blit GLasses";
}
if (v == Eyes.NOUNS_GLASSES) {
return"Nouns Glasses";
}
revert("invalid eyes");
}
functiontoString(Fur v) externalpurereturns (stringmemory) {
if (v == Fur.MAGENTA) {
return"Magenta";
}
if (v == Fur.BLUE) {
return"Blue";
}
if (v == Fur.GREEN) {
return"Green";
}
if (v == Fur.RED) {
return"Red";
}
if (v == Fur.BLACK) {
return"Black";
}
if (v == Fur.BROWN) {
return"Brown";
}
if (v == Fur.SILVER) {
return"Silver";
}
if (v == Fur.PURPLE) {
return"Purple";
}
if (v == Fur.PINK) {
return"Pink";
}
if (v == Fur.SEANCE) {
return"Seance";
}
if (v == Fur.TURQUOISE) {
return"Turquoise";
}
if (v == Fur.CRIMSON) {
return"Crimson";
}
if (v == Fur.GREENYELLOW) {
return"Green-Yellow";
}
if (v == Fur.GOLD) {
return"Gold";
}
if (v == Fur.DIAMOND) {
return"Diamond";
}
if (v == Fur.METALLIC) {
return"Metallic";
}
revert("invalid fur");
}
functiontoString(Head v) externalpurereturns (stringmemory) {
if (v == Head.HALO) {
return"Halo";
}
if (v == Head.ENERGY_FIELD) {
return"Energy Field";
}
if (v == Head.BLUE_TOP_HAT) {
return"Blue Top Hat";
}
if (v == Head.RED_TOP_HAT) {
return"Red Top Hat";
}
if (v == Head.ENERGY_CRYSTAL) {
return"Energy Crystal";
}
if (v == Head.CROWN) {
return"Crown";
}
if (v == Head.BANDANA) {
return"Bandana";
}
if (v == Head.BUCKET_HAT) {
return"Bucket Hat";
}
if (v == Head.HOMBURG_HAT) {
return"Homburg Hat";
}
if (v == Head.PROPELLER_HAT) {
return"Propeller Hat";
}
if (v == Head.HEADBAND) {
return"Headband";
}
if (v == Head.DORAG) {
return"Do-rag";
}
if (v == Head.PURPLE_COWBOY_HAT) {
return"Purple Cowboy Hat";
}
if (v == Head.SPACESUIT_HELMET) {
return"Spacesuit Helmet";
}
if (v == Head.PARTY_HAT) {
return"Party Hat";
}
if (v == Head.CAP) {
return"Cap";
}
if (v == Head.LEATHER_COWBOY_HAT) {
return"Leather Cowboy Hat";
}
if (v == Head.CYBER_HELMET__BLUE) {
return"Cyber Helmet - Blue";
}
if (v == Head.CYBER_HELMET__RED) {
return"Cyber Helmet - Red";
}
if (v == Head.SAMURAI_HAT) {
return"Samurai Hat";
}
if (v == Head.NONE) {
return"None";
}
revert("invalid head");
}
functiontoString(Mouth v) externalpurereturns (stringmemory) {
if (v == Mouth.SMIRK) {
return"Smirk";
}
if (v == Mouth.SURPRISED) {
return"Surprised";
}
if (v == Mouth.SMILE) {
return"Smile";
}
if (v == Mouth.PIPE) {
return"Pipe";
}
if (v == Mouth.OPEN_SMILE) {
return"Open Smile";
}
if (v == Mouth.NEUTRAL) {
return"Neutral";
}
if (v == Mouth.MASK) {
return"Mask";
}
if (v == Mouth.TONGUE_OUT) {
return"Tongue Out";
}
if (v == Mouth.GOLD_GRILL) {
return"Gold Grill";
}
if (v == Mouth.DIAMOND_GRILL) {
return"Diamond Grill";
}
if (v == Mouth.NAVY_RESPIRATOR) {
return"Navy Respirator";
}
if (v == Mouth.RED_RESPIRATOR) {
return"Red Respirator";
}
if (v == Mouth.MAGENTA_RESPIRATOR) {
return"Magenta Respirator";
}
if (v == Mouth.GREEN_RESPIRATOR) {
return"Green Respirator";
}
if (v == Mouth.MEMPO) {
return"Mempo";
}
if (v == Mouth.VAPE) {
return"Vape";
}
if (v == Mouth.PILOT_OXYGEN_MASK) {
return"Pilot Oxygen Mask";
}
if (v == Mouth.CIGAR) {
return"Cigar";
}
if (v == Mouth.BANANA) {
return"Banana";
}
if (v == Mouth.CHROME_RESPIRATOR) {
return"Chrome Respirator";
}
if (v == Mouth.STOIC) {
return"Stoic";
}
revert("invalid mouth");
}
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/interfaceIERC165{
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/functionsupportsInterface(bytes4 interfaceId) externalviewreturns (bool);
}
Código Fuente del Contrato
Archivo 15 de 30: IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address recipient, uint256 amount) externalreturns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(address sender,
address recipient,
uint256 amount
) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
Código Fuente del Contrato
Archivo 16 de 30: IERC721.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)pragmasolidity ^0.8.0;import"../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/interfaceIERC721isIERC165{
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/eventTransfer(addressindexedfrom, addressindexed to, uint256indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/eventApproval(addressindexed owner, addressindexed approved, uint256indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/eventApprovalForAll(addressindexed owner, addressindexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/functionbalanceOf(address owner) externalviewreturns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/functionownerOf(uint256 tokenId) externalviewreturns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/functiontransferFrom(addressfrom,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/functionapprove(address to, uint256 tokenId) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/functiongetApproved(uint256 tokenId) externalviewreturns (address operator);
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/functionsetApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/functionisApprovedForAll(address owner, address operator) externalviewreturns (bool);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 tokenId,
bytescalldata data
) external;
}
Código Fuente del Contrato
Archivo 17 de 30: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)pragmasolidity ^0.8.0;import"../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/interfaceIERC721EnumerableisIERC721{
/**
* @dev Returns the total amount of tokens stored by the contract.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/functiontokenOfOwnerByIndex(address owner, uint256 index) externalviewreturns (uint256 tokenId);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/functiontokenByIndex(uint256 index) externalviewreturns (uint256);
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)pragmasolidity ^0.8.0;/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/interfaceIERC721Receiver{
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
*/functiononERC721Received(address operator,
addressfrom,
uint256 tokenId,
bytescalldata data
) externalreturns (bytes4);
}
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;libraryInteger{
/**
* @dev Gets the bit at the given position in the given integer.
* 255 is the leftmost bit, 0 is the rightmost bit.
*
* For example: bitAt(2, 0) == 0, because the rightmost bit of 10 is 0
* bitAt(2, 1) == 1, because the second to last bit of 10 is 1
*/functionbitAt(uint integer, uint pos) internalpurereturns (uint) {
require(pos <=255, "pos > 255");
return (integer & (1<< pos)) >> pos;
}
functionsetBitAt(uint integer, uint pos) internalpurereturns (uint) {
return integer | (1<< pos);
}
/**
* @dev Gets the value of the bits between left and right, both inclusive, in the given integer.
* 255 is the leftmost bit, 0 is the rightmost bit.
*
* For example: bitsFrom(10, 3, 1) == 7 (101 in binary), because 10 is *101*0 in binary
* bitsFrom(10, 2, 0) == 2 (010 in binary), because 10 is 1*010* in binary
*/functionbitsFrom(uint integer, uint left, uint right) internalpurereturns (uint) {
require(left >= right, "left > right");
require(left <=255, "left > 255");
uint delta = left - right +1;
return (integer & (((1<< delta) -1) << right)) >> right;
}
}
Código Fuente del Contrato
Archivo 24 de 30: MerkleProof.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)pragmasolidity ^0.8.0;/**
* @dev These functions deal with verification of Merkle Trees proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*/libraryMerkleProof{
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/functionverify(bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internalpurereturns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*
* _Available since v4.4._
*/functionprocessProof(bytes32[] memory proof, bytes32 leaf) internalpurereturns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i =0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash =keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash =keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash;
}
}
Código Fuente del Contrato
Archivo 25 de 30: MerkleWhitelistERC721Enumerable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)pragmasolidity ^0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/function_transferOwnership(address newOwner) internalvirtual{
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
//SPDX-License-Identifier: MITpragmasolidity ^0.8.0;/**
* @title A pseudo random number generator
*
* @dev This is not a true random number generator because smart contracts must be deterministic (every node a transaction goes to must produce the same result).
* True randomness requires an oracle which is both expensive in terms of gas and would take a critical part of the project off the chain.
*/structRng {
bytes32 state;
}
/**
* @title A library for working with the Rng struct.
*
* @dev Rng cannot be a contract because then anyone could manipulate it by generating random numbers.
*/libraryRngLibrary{
/**
* Creates a new Rng.
*/functionnewRng() internalviewreturns (Rng memory) {
return Rng(getEntropy());
}
/**
* Creates a pseudo-random value from the current block miner's address and sender.
*/functiongetEntropy() internalviewreturns (bytes32) {
returnkeccak256(abi.encodePacked(block.coinbase, msg.sender));
}
/**
* Generates a random uint256.
*/functiongenerate(Rng memoryself) internalviewreturns (uint256) {
self.state =keccak256(abi.encodePacked(getEntropy(), self.state));
returnuint256(self.state);
}
/**
* Generates a random uint256 from min to max inclusive.
*
* @dev This function is not subject to modulo bias.
* The chance that this function has to reroll is astronomically unlikely, but it can theoretically reroll forever.
*/functiongenerate(Rng memoryself, uint min, uint max) internalviewreturns (uint256) {
require(min <= max, "min > max");
uint delta = max - min;
if (delta ==0) {
return min;
}
return generate(self) % (delta +1) + min;
}
}
Código Fuente del Contrato
Archivo 30 de 30: Strings.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)pragmasolidity ^0.8.0;/**
* @dev String operations.
*/libraryStrings{
bytes16privateconstant _HEX_SYMBOLS ="0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/functiontoString(uint256 value) internalpurereturns (stringmemory) {
// Inspired by OraclizeAPI's implementation - MIT licence// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.solif (value ==0) {
return"0";
}
uint256 temp = value;
uint256 digits;
while (temp !=0) {
digits++;
temp /=10;
}
bytesmemory buffer =newbytes(digits);
while (value !=0) {
digits -=1;
buffer[digits] =bytes1(uint8(48+uint256(value %10)));
value /=10;
}
returnstring(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/functiontoHexString(uint256 value) internalpurereturns (stringmemory) {
if (value ==0) {
return"0x00";
}
uint256 temp = value;
uint256 length =0;
while (temp !=0) {
length++;
temp >>=8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/functiontoHexString(uint256 value, uint256 length) internalpurereturns (stringmemory) {
bytesmemory buffer =newbytes(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");
returnstring(buffer);
}
}