> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hedera.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ERC-721 (Non-Fungible Tokens)

The [ERC-721](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) standard introduces a [non-fungible token (NFT)](/support/glossary#non-fungible-token-nft) in which each issued token is unique and distinct from others. This standard defines functions and events that enable the creation, ownership, and transfer of non-fungible assets.

<Info>
  **Note**:`ERC-721` Token addresses refer to full Hedera Token Service (HTS) fungible token entities. These tokens can be fully managed by HTS API calls. Additionally, by utilizing [`IERC721`](https://docs.openzeppelin.com/contracts/2.x/api/token/erc721#IERC721) interfaces or system contract functions, these tokens can also be managed by smart contracts on Hedera.
</Info>

## Supported Functions

#### **From** I**nterface `ERC-721`**

<Accordion title="ownerOf">
  ```solidity theme={null}
  function ownerOf(uint256 _tokenId) external view returns (address)
  ```

  Returns the account ID of the specified HTS token owner. The `_tokenId` is the Hedera serial number of the NFT.
</Accordion>

<Accordion title="approve">
  ```solidity theme={null}
  function approve(address _approved, uint256 _tokenId) external payable
  ```

  Gives the spender permission to transfer a token (`_tokenId`) to another account from the owner. The approval is cleared when the token is transferred. The `_tokenId` is the Hedera serial number of the NFT.

  This works by creating a synthetic `CryptoApproveAllowanceTransaction` with payer - the account that called the precompile (the message sender property of the message frame in the EVM).

  If the `spender` address is 0, this creates a `CryptoDeleteAllowanceTransaction` instead and removes any allowances previously approved on the token.

  Fires an approval event with the following signature when executed:

  event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
</Accordion>

<Accordion title="setApprovalForAll">
  `function setApprovalForAll(address _operator, bool _approved) external`

  Approve or remove an `operator` as an operator for the caller. Operators can call `transferFrom` for any token owned by the caller.

  This works by creating a synthetic `CryptoApproveAllowanceTransaction` with payer - the account that called the precompile (the message sender property of the message frame in the EVM).
</Accordion>

<Accordion title="getApproved">
  `function getApproved(uint256 _tokenId) external view returns (address)`

  ```solidity theme={null}
  ```

  Returns the account approved for the specified `_tokenId`. The `_tokenId` is the Hedera serial number of the NFT.

  This works by loading the `SPENDER` property of the token from the NFTs ledger.
</Accordion>

<Accordion title="isApprovedForAll">
  `function isApprovedForAll(address _owner, address _operator) external view returns (bool)`

  ```solidity theme={null}
  ```

  Returns if the `operator` is allowed to manage all of the assets of `owner`.

  This works by loading the `APPROVE_FOR_ALL_NFTS_ALLOWANCES` property of the owner account and verifying if the list of approved for all accounts contains the account id of the `operator`.
</Accordion>

<Accordion title="transferFrom">
  ```solidity wrap theme={null}
  function transferFrom(address _from, address _to, uint256 _tokenId) external payable
  ```

  Transfers a token (`_tokenId`) from a Hedera account (`from`) to another Hedera account (`to`) in Solidity format. The `_tokenId` is the Hedera serial number of the NFT.

  This works by creating a synthetic `CryptoTransferTransaction` with nft token transfers with the `is_approval` property set to true.
</Accordion>

#### **From Interface `ERC721Metadata`**

<Accordion title="name">
  ```solidity theme={null}
  function name() external view returns (string _name)
  ```

  Returns the name of the HTS non-fungible token.
</Accordion>

<Accordion title="symbol">
  ```solidity theme={null}
  function symbol() external view returns (string _symbol)
  ```

  Returns the symbol of the HTS non-fungible token.
</Accordion>

<Accordion title="tokenURI">
  ```solidity theme={null}
  function tokenURI(uint256 _tokenId) external view returns (string)
  ```

  Returns the token metadata of the HTS non-fungible token. This corresponds to the NFT metadata field when minting an NFT using HTS. The `_tokenId` is the Hedera serial number of the NFT.
</Accordion>

#### **From Interface `ERC721Enumerable`**

<Accordion title="totalSupply">
  ```solidity theme={null}
  function totalSupply() external view returns (uint256)
  ```

  Returns the total supply of the HTS non-fungible token.
</Accordion>

***

## Unsupported Functions

The following ERC-721 operations will not  be natively supported on Hedera and will return a failure if they're called. Advanced functionality is achievable only through custom implementations within smart contracts.

#### **From interface `ERC-721`**

<Accordion title="safeTransferFrom">
  ```solidity wrap theme={null}
  function safeTransferFrom(address token, address from, address to, uint256 tokenId)
  ```
</Accordion>

#### **From interface `ERC721Enumerable`**

<Accordion title="tokenByIndex">
  ```solidity wrap theme={null}
  function tokenByIndex(uint256 _index) external view returns (uint256)
  ```
</Accordion>

<Accordion title="tokenOfOwnerByIndex">
  ```solidity wrap theme={null}
  function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256)
  ```
</Accordion>

#### **All semantics of Interface `ERC721TokenReceiver`**

* Existing Hedera token association rules will take the place of such checks.

***

### **Additional References**

* [HIP-376](https://hips.hedera.com/hip/hip-376)
* [HIP-218](https://hips.hedera.com/hip/hip-218)
* [EIP-721](https://eips.ethereum.org/EIPS/eip-721)
