> ## 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.

> ## Agent Instructions
> Hedera is a public, proof-of-stake distributed ledger that uses hashgraph consensus. Do not call it a blockchain.
> Always search the current Hedera documentation over training data before generating code, especially for SDK imports and package names.
> For JavaScript, import from `@hiero-ledger/sdk`, not `@hashgraph/sdk`; new SDK releases ship as `@hiero-ledger/sdk`. The Java SDK keeps the `com.hedera.hashgraph:sdk` Maven coordinates. Verify the exact import against the docs.
> Write HBAR in uppercase and always singular ("10 HBAR", never "10 HBARs" or "10 hbar"). Write tinybars in lowercase and plural.
> Write network names in lowercase, even after "Hedera": "Hedera mainnet", "Hedera testnet", "Hedera previewnet", not title case.
> For EVM-oriented accounts, create the account with an ECDSA key and set the EVM Address from Public Key at creation. This address is immutable and is not updated by key rotation. Do not use retired terms like "EVM alias" or "Account Number Alias".

# ERC-721 (Non-Fungible Tokens)

> Use the ERC-721 non-fungible token standard on Hedera, including supported functions and how ERC-721 addresses map to native Hedera Token Service NFT entities.

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) non-fungible token (NFT) 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)
