Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Muhammad-waqar-uit/656e173a590e87e7f859eb13fb8f5a24 to your computer and use it in GitHub Desktop.

Select an option

Save Muhammad-waqar-uit/656e173a590e87e7f859eb13fb8f5a24 to your computer and use it in GitHub Desktop.

Revisions

  1. Muhammad-waqar-uit created this gist Aug 29, 2022.
    454 changes: 454 additions & 0 deletions [email protected]@4.7.3...token...ERC721...ERC721.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,454 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

    pragma solidity ^0.8.0;

    import "./IERC721.sol";
    import "./IERC721Receiver.sol";
    import "./extensions/IERC721Metadata.sol";
    import "../../utils/Address.sol";
    import "../../utils/Context.sol";
    import "../../utils/Strings.sol";
    import "../../utils/introspection/ERC165.sol";

    /**
    * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
    * the Metadata extension, but not including the Enumerable extension, which is available separately as
    * {ERC721Enumerable}.
    */
    contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
    * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
    */
    constructor(string memory name_, string memory symbol_) {
    _name = name_;
    _symbol = symbol_;
    }

    /**
    * @dev See {IERC165-supportsInterface}.
    */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
    return
    interfaceId == type(IERC721).interfaceId ||
    interfaceId == type(IERC721Metadata).interfaceId ||
    super.supportsInterface(interfaceId);
    }

    /**
    * @dev See {IERC721-balanceOf}.
    */
    function balanceOf(address owner) public view virtual override returns (uint256) {
    require(owner != address(0), "ERC721: address zero is not a valid owner");
    return _balances[owner];
    }

    /**
    * @dev See {IERC721-ownerOf}.
    */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
    address owner = _owners[tokenId];
    require(owner != address(0), "ERC721: invalid token ID");
    return owner;
    }

    /**
    * @dev See {IERC721Metadata-name}.
    */
    function name() public view virtual override returns (string memory) {
    return _name;
    }

    /**
    * @dev See {IERC721Metadata-symbol}.
    */
    function symbol() public view virtual override returns (string memory) {
    return _symbol;
    }

    /**
    * @dev See {IERC721Metadata-tokenURI}.
    */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
    _requireMinted(tokenId);

    string memory baseURI = _baseURI();
    return bytes(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 overridden in child contracts.
    */
    function _baseURI() internal view virtual returns (string memory) {
    return "";
    }

    /**
    * @dev See {IERC721-approve}.
    */
    function approve(address to, uint256 tokenId) public virtual override {
    address owner = ERC721.ownerOf(tokenId);
    require(to != owner, "ERC721: approval to current owner");

    require(
    _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
    "ERC721: approve caller is not token owner nor approved for all"
    );

    _approve(to, tokenId);
    }

    /**
    * @dev See {IERC721-getApproved}.
    */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
    _requireMinted(tokenId);

    return _tokenApprovals[tokenId];
    }

    /**
    * @dev See {IERC721-setApprovalForAll}.
    */
    function setApprovalForAll(address operator, bool approved) public virtual override {
    _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
    * @dev See {IERC721-isApprovedForAll}.
    */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
    return _operatorApprovals[owner][operator];
    }

    /**
    * @dev See {IERC721-transferFrom}.
    */
    function transferFrom(
    address from,
    address to,
    uint256 tokenId
    ) public virtual override {
    //solhint-disable-next-line max-line-length
    require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");

    _transfer(from, to, tokenId);
    }

    /**
    * @dev See {IERC721-safeTransferFrom}.
    */
    function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
    ) public virtual override {
    safeTransferFrom(from, to, tokenId, "");
    }

    /**
    * @dev See {IERC721-safeTransferFrom}.
    */
    function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
    ) public virtual override {
    require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
    _safeTransfer(from, to, tokenId, data);
    }

    /**
    * @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.
    *
    * `data` is additional data, it has no specified format and it is sent in call to `to`.
    *
    * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
    * implement alternative mechanisms to perform token transfer, such as signature-based.
    *
    * Requirements:
    *
    * - `from` cannot be the zero address.
    * - `to` cannot be the zero address.
    * - `tokenId` token must exist and be owned by `from`.
    * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    *
    * Emits a {Transfer} event.
    */
    function _safeTransfer(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
    ) internal virtual {
    _transfer(from, to, tokenId);
    require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
    * @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`),
    * and stop existing when they are burned (`_burn`).
    */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
    return _owners[tokenId] != address(0);
    }

    /**
    * @dev Returns whether `spender` is allowed to manage `tokenId`.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
    address owner = ERC721.ownerOf(tokenId);
    return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
    * @dev Safely mints `tokenId` and transfers it to `to`.
    *
    * Requirements:
    *
    * - `tokenId` must not exist.
    * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
    *
    * Emits a {Transfer} event.
    */
    function _safeMint(address to, uint256 tokenId) internal virtual {
    _safeMint(to, tokenId, "");
    }

    /**
    * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
    * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
    */
    function _safeMint(
    address to,
    uint256 tokenId,
    bytes memory data
    ) internal virtual {
    _mint(to, tokenId);
    require(
    _checkOnERC721Received(address(0), to, tokenId, data),
    "ERC721: transfer to non ERC721Receiver implementer"
    );
    }

    /**
    * @dev Mints `tokenId` and transfers it to `to`.
    *
    * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
    *
    * Requirements:
    *
    * - `tokenId` must not exist.
    * - `to` cannot be the zero address.
    *
    * Emits a {Transfer} event.
    */
    function _mint(address to, uint256 tokenId) internal virtual {
    require(to != address(0), "ERC721: mint to the zero address");
    require(!_exists(tokenId), "ERC721: token already minted");

    _beforeTokenTransfer(address(0), to, tokenId);

    _balances[to] += 1;
    _owners[tokenId] = to;

    emit Transfer(address(0), to, tokenId);

    _afterTokenTransfer(address(0), to, tokenId);
    }

    /**
    * @dev Destroys `tokenId`.
    * The approval is cleared when the token is burned.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    *
    * Emits a {Transfer} event.
    */
    function _burn(uint256 tokenId) internal virtual {
    address owner = ERC721.ownerOf(tokenId);

    _beforeTokenTransfer(owner, address(0), tokenId);

    // Clear approvals
    _approve(address(0), tokenId);

    _balances[owner] -= 1;
    delete _owners[tokenId];

    emit Transfer(owner, address(0), tokenId);

    _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
    * @dev Transfers `tokenId` from `from` to `to`.
    * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
    *
    * Requirements:
    *
    * - `to` cannot be the zero address.
    * - `tokenId` token must be owned by `from`.
    *
    * Emits a {Transfer} event.
    */
    function _transfer(
    address from,
    address to,
    uint256 tokenId
    ) internal virtual {
    require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
    require(to != address(0), "ERC721: transfer to the zero address");

    _beforeTokenTransfer(from, to, tokenId);

    // Clear approvals from the previous owner
    _approve(address(0), tokenId);

    _balances[from] -= 1;
    _balances[to] += 1;
    _owners[tokenId] = to;

    emit Transfer(from, to, tokenId);

    _afterTokenTransfer(from, to, tokenId);
    }

    /**
    * @dev Approve `to` to operate on `tokenId`
    *
    * Emits an {Approval} event.
    */
    function _approve(address to, uint256 tokenId) internal virtual {
    _tokenApprovals[tokenId] = to;
    emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
    * @dev Approve `operator` to operate on all of `owner` tokens
    *
    * Emits an {ApprovalForAll} event.
    */
    function _setApprovalForAll(
    address owner,
    address operator,
    bool approved
    ) internal virtual {
    require(owner != operator, "ERC721: approve to caller");
    _operatorApprovals[owner][operator] = approved;
    emit ApprovalForAll(owner, operator, approved);
    }

    /**
    * @dev Reverts if the `tokenId` has not been minted yet.
    */
    function _requireMinted(uint256 tokenId) internal view virtual {
    require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
    * @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(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
    ) private returns (bool) {
    if (to.isContract()) {
    try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
    return retval == IERC721Receiver.onERC721Received.selector;
    } catch (bytes memory reason) {
    if (reason.length == 0) {
    revert("ERC721: transfer to non ERC721Receiver implementer");
    } else {
    /// @solidity memory-safe-assembly
    assembly {
    revert(add(32, reason), mload(reason))
    }
    }
    }
    } else {
    return true;
    }
    }

    /**
    * @dev Hook that is called before any token transfer. This includes minting
    * and burning.
    *
    * 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, ``from``'s `tokenId` will be burned.
    * - `from` and `to` are never both zero.
    *
    * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
    */
    function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
    ) internal virtual {}

    /**
    * @dev Hook that is called after any transfer of tokens. This includes
    * minting and burning.
    *
    * Calling conditions:
    *
    * - when `from` and `to` are both non-zero.
    * - `from` and `to` are never both zero.
    *
    * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
    */
    function _afterTokenTransfer(
    address from,
    address to,
    uint256 tokenId
    ) internal virtual {}
    }
    143 changes: 143 additions & 0 deletions [email protected]@4.7.3...token...ERC721...IERC721.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,143 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

    pragma solidity ^0.8.0;

    import "../../utils/introspection/IERC165.sol";

    /**
    * @dev Required interface of an ERC721 compliant contract.
    */
    interface IERC721 is IERC165 {
    /**
    * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
    */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
    * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
    */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
    * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
    */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
    * @dev Returns the number of tokens in ``owner``'s account.
    */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
    * @dev Returns the owner of the `tokenId` token.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
    * @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.
    */
    function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes calldata data
    ) external;

    /**
    * @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 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.
    */
    function safeTransferFrom(
    address from,
    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.
    */
    function transferFrom(
    address from,
    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.
    */
    function approve(address to, uint256 tokenId) external;

    /**
    * @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.
    */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
    * @dev Returns the account approved for `tokenId` token.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
    * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
    *
    * See {setApprovalForAll}
    */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    }
    27 changes: 27 additions & 0 deletions [email protected]@4.7.3...token...ERC721...IERC721Receiver.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

    pragma solidity ^0.8.0;

    /**
    * @title ERC721 token receiver interface
    * @dev Interface for any contract that wants to support safeTransfers
    * from ERC721 asset contracts.
    */
    interface IERC721Receiver {
    /**
    * @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 `IERC721Receiver.onERC721Received.selector`.
    */
    function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes calldata data
    ) external returns (bytes4);
    }
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,163 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

    pragma solidity ^0.8.0;

    import "../ERC721.sol";
    import "./IERC721Enumerable.sol";

    /**
    * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
    * enumerability of all the token ids in the contract as well as all token ids owned by each
    * account.
    */
    abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
    * @dev See {IERC165-supportsInterface}.
    */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
    return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
    * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
    */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
    require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
    return _ownedTokens[owner][index];
    }

    /**
    * @dev See {IERC721Enumerable-totalSupply}.
    */
    function totalSupply() public view virtual override returns (uint256) {
    return _allTokens.length;
    }

    /**
    * @dev See {IERC721Enumerable-tokenByIndex}.
    */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
    require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
    return _allTokens[index];
    }

    /**
    * @dev Hook that is called before any token transfer. This includes minting
    * and burning.
    *
    * 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, ``from``'s `tokenId` will be burned.
    * - `from` cannot be the zero address.
    * - `to` cannot be the zero address.
    *
    * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
    */
    function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
    ) internal virtual override {
    super._beforeTokenTransfer(from, to, tokenId);

    if (from == address(0)) {
    _addTokenToAllTokensEnumeration(tokenId);
    } else if (from != to) {
    _removeTokenFromOwnerEnumeration(from, tokenId);
    }
    if (to == address(0)) {
    _removeTokenFromAllTokensEnumeration(tokenId);
    } else if (to != from) {
    _addTokenToOwnerEnumeration(to, tokenId);
    }
    }

    /**
    * @dev Private function to add a token to this extension's ownership-tracking data structures.
    * @param to address representing the new owner of the given token ID
    * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
    */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
    uint256 length = ERC721.balanceOf(to);
    _ownedTokens[to][length] = tokenId;
    _ownedTokensIndex[tokenId] = length;
    }

    /**
    * @dev Private function to add a token to this extension's token tracking data structures.
    * @param tokenId uint256 ID of the token to be added to the tokens list
    */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
    _allTokensIndex[tokenId] = _allTokens.length;
    _allTokens.push(tokenId);
    }

    /**
    * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
    * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
    * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
    * This has O(1) time complexity, but alters the order of the _ownedTokens array.
    * @param from address representing the previous owner of the given token ID
    * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
    */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
    // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
    // then delete the last slot (swap and pop).

    uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
    uint256 tokenIndex = _ownedTokensIndex[tokenId];

    // When the token to delete is the last token, the swap operation is unnecessary
    if (tokenIndex != lastTokenIndex) {
    uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

    _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
    _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
    }

    // This also deletes the contents at the last position of the array
    delete _ownedTokensIndex[tokenId];
    delete _ownedTokens[from][lastTokenIndex];
    }

    /**
    * @dev Private function to remove a token from this extension's token tracking data structures.
    * This has O(1) time complexity, but alters the order of the _allTokens array.
    * @param tokenId uint256 ID of the token to be removed from the tokens list
    */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
    // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
    // then delete the last slot (swap and pop).

    uint256 lastTokenIndex = _allTokens.length - 1;
    uint256 tokenIndex = _allTokensIndex[tokenId];

    // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
    // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
    // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
    uint256 lastTokenId = _allTokens[lastTokenIndex];

    _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
    _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

    // This also deletes the contents at the last position of the array
    delete _allTokensIndex[tokenId];
    _allTokens.pop();
    }
    }
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)

    pragma solidity ^0.8.0;

    import "../ERC721.sol";

    /**
    * @dev ERC721 token with storage based token URI management.
    */
    abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
    * @dev See {IERC721Metadata-tokenURI}.
    */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
    _requireMinted(tokenId);

    string memory _tokenURI = _tokenURIs[tokenId];
    string memory base = _baseURI();

    // If there is no base URI, return the token URI.
    if (bytes(base).length == 0) {
    return _tokenURI;
    }
    // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
    if (bytes(_tokenURI).length > 0) {
    return string(abi.encodePacked(base, _tokenURI));
    }

    return super.tokenURI(tokenId);
    }

    /**
    * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
    *
    * Requirements:
    *
    * - `tokenId` must exist.
    */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
    require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
    _tokenURIs[tokenId] = _tokenURI;
    }

    /**
    * @dev See {ERC721-_burn}. This override additionally checks to see if a
    * token-specific URI was set for the token, and if so, it deletes the token URI from
    * the storage mapping.
    */
    function _burn(uint256 tokenId) internal virtual override {
    super._burn(tokenId);

    if (bytes(_tokenURIs[tokenId]).length != 0) {
    delete _tokenURIs[tokenId];
    }
    }
    }
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

    pragma solidity ^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
    */
    interface IERC721Enumerable is IERC721 {
    /**
    * @dev Returns the total amount of tokens stored by the contract.
    */
    function totalSupply() external view returns (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.
    */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
    * @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.
    */
    function tokenByIndex(uint256 index) external view returns (uint256);
    }
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

    pragma solidity ^0.8.0;

    import "../IERC721.sol";

    /**
    * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
    * @dev See https://eips.ethereum.org/EIPS/eip-721
    */
    interface IERC721Metadata is IERC721 {
    /**
    * @dev Returns the token collection name.
    */
    function name() external view returns (string memory);

    /**
    * @dev Returns the token collection symbol.
    */
    function symbol() external view returns (string memory);

    /**
    * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
    */
    function tokenURI(uint256 tokenId) external view returns (string memory);
    }
    222 changes: 222 additions & 0 deletions [email protected]@4.7.3...utils...Address.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,222 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

    pragma solidity ^0.8.1;

    /**
    * @dev Collection of functions related to the address type
    */
    library Address {
    /**
    * @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
    * ====
    *
    * [IMPORTANT]
    * ====
    * You shouldn't rely on `isContract` to protect against flash loan attacks!
    *
    * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
    * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
    * constructor.
    * ====
    */
    function isContract(address account) internal view returns (bool) {
    // This method relies on extcodesize/address.code.length, which returns 0
    // for contracts in construction, since the code is only stored at the end
    // of the constructor execution.

    return account.code.length > 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].
    */
    function sendValue(address payable 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._
    */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
    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._
    */
    function functionCall(
    address target,
    bytes memory data,
    string memory errorMessage
    ) internal returns (bytes memory) {
    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._
    */
    function functionCallWithValue(
    address target,
    bytes memory data,
    uint256 value
    ) internal returns (bytes memory) {
    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._
    */
    function functionCallWithValue(
    address target,
    bytes memory data,
    uint256 value,
    string memory errorMessage
    ) internal returns (bytes memory) {
    require(address(this).balance >= value, "Address: insufficient balance for call");
    require(isContract(target), "Address: call to non-contract");

    (bool success, bytes memory 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._
    */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
    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._
    */
    function functionStaticCall(
    address target,
    bytes memory data,
    string memory errorMessage
    ) internal view returns (bytes memory) {
    require(isContract(target), "Address: static call to non-contract");

    (bool success, bytes memory 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._
    */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
    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._
    */
    function functionDelegateCall(
    address target,
    bytes memory data,
    string memory errorMessage
    ) internal returns (bytes memory) {
    require(isContract(target), "Address: delegate call to non-contract");

    (bool success, bytes memory 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._
    */
    function verifyCallResult(
    bool success,
    bytes memory returndata,
    string memory errorMessage
    ) internal pure returns (bytes memory) {
    if (success) {
    return returndata;
    } else {
    // Look for revert reason and bubble it up if present
    if (returndata.length > 0) {
    // The easiest way to bubble the revert reason is using memory via assembly
    /// @solidity memory-safe-assembly
    assembly {
    let returndata_size := mload(returndata)
    revert(add(32, returndata), returndata_size)
    }
    } else {
    revert(errorMessage);
    }
    }
    }
    }
    24 changes: 24 additions & 0 deletions [email protected]@4.7.3...utils...Context.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

    pragma solidity ^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.
    */
    abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
    return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
    return msg.data;
    }
    }
    43 changes: 43 additions & 0 deletions [email protected]@4.7.3...utils...Counters.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

    pragma solidity ^0.8.0;

    /**
    * @title Counters
    * @author Matt Condon (@shrugs)
    * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
    * of elements in a mapping, issuing ERC721 ids, or counting request ids.
    *
    * Include with `using Counters for Counters.Counter;`
    */
    library Counters {
    struct Counter {
    // This variable should never be directly accessed by users of the library: interactions must be restricted to
    // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
    // this feature: see https://github.com/ethereum/solidity/issues/4637
    uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
    return counter._value;
    }

    function increment(Counter storage counter) internal {
    unchecked {
    counter._value += 1;
    }
    }

    function decrement(Counter storage counter) internal {
    uint256 value = counter._value;
    require(value > 0, "Counter: decrement overflow");
    unchecked {
    counter._value = value - 1;
    }
    }

    function reset(Counter storage counter) internal {
    counter._value = 0;
    }
    }
    75 changes: 75 additions & 0 deletions [email protected]@4.7.3...utils...Strings.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

    pragma solidity ^0.8.0;

    /**
    * @dev String operations.
    */
    library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
    * @dev Converts a `uint256` to its ASCII `string` decimal representation.
    */
    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT licence
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

    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);
    }

    /**
    * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
    */
    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);
    }

    /**
    * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed 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);
    }

    /**
    * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
    */
    function toHexString(address addr) internal pure returns (string memory) {
    return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
    }
    29 changes: 29 additions & 0 deletions [email protected]@4.7.3...utils...introspection...ERC165.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

    pragma solidity ^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.
    */
    abstract contract ERC165 is IERC165 {
    /**
    * @dev See {IERC165-supportsInterface}.
    */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
    return interfaceId == type(IERC165).interfaceId;
    }
    }
    25 changes: 25 additions & 0 deletions [email protected]@4.7.3...utils...introspection...IERC165.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

    pragma solidity ^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}.
    */
    interface IERC165 {
    /**
    * @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.
    */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    }
    16,461 changes: 16,461 additions & 0 deletions artifacts...Muwaqar.json
    16,461 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    602 changes: 602 additions & 0 deletions artifacts...Muwaqar_metadata.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,602 @@
    {
    "compiler": {
    "version": "0.8.7+commit.e28d00a7"
    },
    "language": "Solidity",
    "output": {
    "abi": [
    {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "owner",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "address",
    "name": "approved",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "Approval",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "owner",
    "type": "address"
    },
    {
    "indexed": true,
    "internalType": "address",
    "name": "operator",
    "type": "address"
    },
    {
    "indexed": false,
    "internalType": "bool",
    "name": "approved",
    "type": "bool"
    }
    ],
    "name": "ApprovalForAll",
    "type": "event"
    },
    {
    "anonymous": false,
    "inputs": [
    {
    "indexed": true,
    "internalType": "address",
    "name": "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": [
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "getApproved",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "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": "name",
    "outputs": [
    {
    "internalType": "string",
    "name": "",
    "type": "string"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "ownerOf",
    "outputs": [
    {
    "internalType": "address",
    "name": "",
    "type": "address"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "string",
    "name": "uri",
    "type": "string"
    }
    ],
    "name": "safeMint",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "from",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "from",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    },
    {
    "internalType": "bytes",
    "name": "data",
    "type": "bytes"
    }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "operator",
    "type": "address"
    },
    {
    "internalType": "bool",
    "name": "approved",
    "type": "bool"
    }
    ],
    "name": "setApprovalForAll",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "bytes4",
    "name": "interfaceId",
    "type": "bytes4"
    }
    ],
    "name": "supportsInterface",
    "outputs": [
    {
    "internalType": "bool",
    "name": "",
    "type": "bool"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "symbol",
    "outputs": [
    {
    "internalType": "string",
    "name": "",
    "type": "string"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "uint256",
    "name": "index",
    "type": "uint256"
    }
    ],
    "name": "tokenByIndex",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "owner",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "index",
    "type": "uint256"
    }
    ],
    "name": "tokenOfOwnerByIndex",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "tokenURI",
    "outputs": [
    {
    "internalType": "string",
    "name": "",
    "type": "string"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
    {
    "internalType": "uint256",
    "name": "",
    "type": "uint256"
    }
    ],
    "stateMutability": "view",
    "type": "function"
    },
    {
    "inputs": [
    {
    "internalType": "address",
    "name": "from",
    "type": "address"
    },
    {
    "internalType": "address",
    "name": "to",
    "type": "address"
    },
    {
    "internalType": "uint256",
    "name": "tokenId",
    "type": "uint256"
    }
    ],
    "name": "transferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
    }
    ],
    "devdoc": {
    "kind": "dev",
    "methods": {
    "approve(address,uint256)": {
    "details": "See {IERC721-approve}."
    },
    "balanceOf(address)": {
    "details": "See {IERC721-balanceOf}."
    },
    "getApproved(uint256)": {
    "details": "See {IERC721-getApproved}."
    },
    "isApprovedForAll(address,address)": {
    "details": "See {IERC721-isApprovedForAll}."
    },
    "name()": {
    "details": "See {IERC721Metadata-name}."
    },
    "ownerOf(uint256)": {
    "details": "See {IERC721-ownerOf}."
    },
    "safeTransferFrom(address,address,uint256)": {
    "details": "See {IERC721-safeTransferFrom}."
    },
    "safeTransferFrom(address,address,uint256,bytes)": {
    "details": "See {IERC721-safeTransferFrom}."
    },
    "setApprovalForAll(address,bool)": {
    "details": "See {IERC721-setApprovalForAll}."
    },
    "symbol()": {
    "details": "See {IERC721Metadata-symbol}."
    },
    "tokenByIndex(uint256)": {
    "details": "See {IERC721Enumerable-tokenByIndex}."
    },
    "tokenOfOwnerByIndex(address,uint256)": {
    "details": "See {IERC721Enumerable-tokenOfOwnerByIndex}."
    },
    "totalSupply()": {
    "details": "See {IERC721Enumerable-totalSupply}."
    },
    "transferFrom(address,address,uint256)": {
    "details": "See {IERC721-transferFrom}."
    }
    },
    "version": 1
    },
    "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
    }
    },
    "settings": {
    "compilationTarget": {
    "contract-c27f250b5f.sol": "Muwaqar"
    },
    "evmVersion": "london",
    "libraries": {},
    "metadata": {
    "bytecodeHash": "ipfs"
    },
    "optimizer": {
    "enabled": false,
    "runs": 200
    },
    "remappings": []
    },
    "sources": {
    "@openzeppelin/[email protected]/token/ERC721/ERC721.sol": {
    "keccak256": "0x0b606994df12f0ce35f6d2f6dcdde7e55e6899cdef7e00f180980caa81e3844e",
    "license": "MIT",
    "urls": [
    "bzz-raw://4c827c981a552d1c76c96060e92f56b52bc20c6f9b4dbf911fe99ddbfb41f2ea",
    "dweb:/ipfs/QmW8xvJdzHrr8Ry34C7viBsgG2b8T1mL4BQWJ5CdfD9JLB"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/IERC721.sol": {
    "keccak256": "0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f",
    "license": "MIT",
    "urls": [
    "bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f",
    "dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/IERC721Receiver.sol": {
    "keccak256": "0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da",
    "license": "MIT",
    "urls": [
    "bzz-raw://6e75cf83beb757b8855791088546b8337e9d4684e169400c20d44a515353b708",
    "dweb:/ipfs/QmYvPafLfoquiDMEj7CKHtvbgHu7TJNPSVPSCjrtjV8HjV"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Enumerable.sol": {
    "keccak256": "0x0a79511df8151b10b0a0004d6a76ad956582d32824af4c0f4886bdbdfe5746e5",
    "license": "MIT",
    "urls": [
    "bzz-raw://afbedcf17f31db719e6fdc56caa8f458799c5fa2eb94cb1e94ef18f89af85768",
    "dweb:/ipfs/QmVmqRdBfbgYThpZSoAJ5o9mnAMjx8mCHHjv3Rh8cQAAg3"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol": {
    "keccak256": "0x5c3501c1b70fcfc64417e9da5cc6a3597191baa354781e508e1e14cc0e50a038",
    "license": "MIT",
    "urls": [
    "bzz-raw://899c87a849a94c848818d0afede6961d2c87665af1dd23a5c983e78981a65691",
    "dweb:/ipfs/QmUeFDffQRDmX87FX3MRxN3bmpUxDTWpWLwPJzeAJ3yF6H"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/extensions/IERC721Enumerable.sol": {
    "keccak256": "0xd1556954440b31c97a142c6ba07d5cade45f96fafd52091d33a14ebe365aecbf",
    "license": "MIT",
    "urls": [
    "bzz-raw://26fef835622b46a5ba08b3ef6b46a22e94b5f285d0f0fb66b703bd30217d2c34",
    "dweb:/ipfs/QmZ548qdwfL1qF7aXz3xh1GCdTiST81kGGuKRqVUfYmPZR"
    ]
    },
    "@openzeppelin/[email protected]/token/ERC721/extensions/IERC721Metadata.sol": {
    "keccak256": "0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9",
    "license": "MIT",
    "urls": [
    "bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146",
    "dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf"
    ]
    },
    "@openzeppelin/[email protected]/utils/Address.sol": {
    "keccak256": "0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10",
    "license": "MIT",
    "urls": [
    "bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487",
    "dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG"
    ]
    },
    "@openzeppelin/[email protected]/utils/Context.sol": {
    "keccak256": "0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7",
    "license": "MIT",
    "urls": [
    "bzz-raw://6df0ddf21ce9f58271bdfaa85cde98b200ef242a05a3f85c2bc10a8294800a92",
    "dweb:/ipfs/QmRK2Y5Yc6BK7tGKkgsgn3aJEQGi5aakeSPZvS65PV8Xp3"
    ]
    },
    "@openzeppelin/[email protected]/utils/Counters.sol": {
    "keccak256": "0xf0018c2440fbe238dd3a8732fa8e17a0f9dce84d31451dc8a32f6d62b349c9f1",
    "license": "MIT",
    "urls": [
    "bzz-raw://59e1c62884d55b70f3ae5432b44bb3166ad71ae3acd19c57ab6ddc3c87c325ee",
    "dweb:/ipfs/QmezuXg5GK5oeA4F91EZhozBFekhq5TD966bHPH18cCqhu"
    ]
    },
    "@openzeppelin/[email protected]/utils/Strings.sol": {
    "keccak256": "0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3",
    "license": "MIT",
    "urls": [
    "bzz-raw://6f2cf1c531122bc7ca96b8c8db6a60deae60441e5223065e792553d4849b5638",
    "dweb:/ipfs/QmPBdJmBBABMDCfyDjCbdxgiqRavgiSL88SYPGibgbPas9"
    ]
    },
    "@openzeppelin/[email protected]/utils/introspection/ERC165.sol": {
    "keccak256": "0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b",
    "license": "MIT",
    "urls": [
    "bzz-raw://fb0048dee081f6fffa5f74afc3fb328483c2a30504e94a0ddd2a5114d731ec4d",
    "dweb:/ipfs/QmZptt1nmYoA5SgjwnSgWqgUSDgm4q52Yos3xhnMv3MV43"
    ]
    },
    "@openzeppelin/[email protected]/utils/introspection/IERC165.sol": {
    "keccak256": "0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1",
    "license": "MIT",
    "urls": [
    "bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f",
    "dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy"
    ]
    },
    "contract-c27f250b5f.sol": {
    "keccak256": "0x9f6b099732366189f74cc8791cd47bbdeaaefc6bf5e17781c0b11fb7c922e455",
    "license": "MIT",
    "urls": [
    "bzz-raw://a57bcf356ba606251727a425c7e0598a73362fb31d837aaae9a08eb6f07f301e",
    "dweb:/ipfs/QmfPQkk7DxrcyKBTXPjzLHX26Nyg8xRhpwmBpb2kdB8rRk"
    ]
    }
    },
    "version": 1
    }
    145,183 changes: 145,183 additions & 0 deletions artifacts...build-info...1d094eb9ca2476a261a72677ea179c1d.json
    145,183 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    144,075 changes: 144,075 additions & 0 deletions artifacts...build-info...33bbaefd57c784171bdb714757912add.json
    144,075 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    54 changes: 54 additions & 0 deletions contract-c27f250b5f.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.4;

    import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
    import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Enumerable.sol";
    import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol";
    import "@openzeppelin/[email protected]/utils/Counters.sol";

    contract Muwaqar is ERC721, ERC721Enumerable, ERC721URIStorage {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;
    uint256 MAX_SUPPLY = 100000;
    constructor() ERC721("muwaqar", "mw") {}

    function safeMint(address to, string memory uri) public {
    uint256 tokenId = _tokenIdCounter.current();
    require(_tokenIdCounter.current() <= MAX_SUPPLY, "I'm sorry we reached the cap");
    _tokenIdCounter.increment();
    _safeMint(to, tokenId);
    _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
    internal
    override(ERC721, ERC721Enumerable)
    {
    super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
    super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
    public
    view
    override(ERC721, ERC721URIStorage)
    returns (string memory)
    {
    return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC721, ERC721Enumerable)
    returns (bool)
    {
    return super.supportsInterface(interfaceId);
    }
    }