# ERC-721: The Standard for Non-Fungible Tokens (NFTs)

### **Introduction**

ERC-721 is the standard for **non-fungible tokens (NFTs)**, meaning **each token is unique** and cannot be replaced (e.g., CryptoKitties, Bored Apes).

### **Architecture**

An ERC-721 token smart contract includes:

* **Token Ownership Mapping:** Each token has a unique `tokenId` linked to an address.
* **Metadata Storage:** Stores information like name, image, and description.
* **Transfer Functions:** Allows ownership to be transferred.

### **Key Functions of ERC-721**

| Function                                    | Description                                    |
| ------------------------------------------- | ---------------------------------------------- |
| balanceOf(address)                          | Returns the number of NFTs owned by an address |
| ownerOf(uint256 tokenId)                    | Returns the owner of a specific NFT            |
| transferFrom(address, address, uint256)     | Transfers ownership of an NFT                  |
| approve(address, uint256)                   | Approves another address to manage an NFT      |
| safeTransferFrom(address, address, uint256) | Ensures safe NFT transfer                      |

### **Workflow of ERC-721 Transactions**

1. **Minting:** A unique `tokenId` is created and assigned to an owner.
2. **Transfer:** The NFT can be transferred using `transferFrom()`.
3. **Approval & Marketplace Integration:**
   * The owner approves a marketplace contract to manage their NFT using `approve()`.
   * The marketplace can then transfer the NFT on behalf of the owner.

### Example: ERC-721 Smart Contract

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    uint256 private _nextTokenId;

    constructor() ERC721("MyNFT", "MNFT") {}

    function mintNFT(address recipient, string memory tokenURI) public onlyOwner {
        uint256 tokenId = _nextTokenId;
        _nextTokenId++;
        _mint(recipient, tokenId);
        _setTokenURI(tokenId, tokenURI);
    }
}

```

### ERC-721 NFT Flow

```scss
[ User A ]  ---> (mint tokenId #1) --->  [ NFT Contract ]
[ User A ]  ---> (transfer tokenId #1) --->  [ User B ]
[ Marketplace ] ---> (approve & transfer NFT) ---> [ Buyer ]

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.anandisheladiya.com/protocols/ercs-and-eips/erc-721-the-standard-for-non-fungible-tokens-nfts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
