> For the complete documentation index, see [llms.txt](https://developers.aixchain.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.aixchain.com/aixc-and-arc-token/arc-721/protocol-interface.md).

# Protocol Interface

## ARC-721 Standard

A standard interface allows applications to track and transfer NFTs on Tron. Simple ARC-721 smart contracts list as below to track a large number of NFTs. ARC-20 token standard is insufficient for handling NFTs due to each token in ARC-721 being unique. The standard of ARC-721 is inspiring on Tron. It plays an important role as well as ARC-20.

## MUST Implemented Interfaces

Every ARC-721 compliant contract must implement the ARC721 and ARC165 interfaces

solidity

```javascript
pragma solidity ^0.4.20;

  interface ARC721 {
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    function balanceOf(address _owner) external view returns (uint256);
    function ownerOf(uint256 _tokenId) external view returns (address);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function approve(address _approved, uint256 _tokenId) external payable;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address);
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
  }
  interface ARC165 {
      function supportsInterface(bytes4 interfaceID) external view returns (bool);
  }
```

**balanceOf(address \_owner)**\
Returns the number of NFTs owned by the specified account

**ownerOf(uint256 \_tokenId)**\
Returns the owner of the specified NFT

**safeTransferFrom(address \_from, address \_to, uint256 \_tokenId, bytes data)**\
Transfer ownership of an NFT

**safeTransferFrom(address \_from, address \_to, uint256 \_tokenId)**\
Transfer ownership of an NFT

**transferFrom(address \_from, address \_to, uint256 \_tokenId)**\
Transfer the ownership of an NFT (the caller must confirm whether the \_to address can receive the NFT normally, otherwise the NFT will be lost)

**approve(address \_approved, uint256 \_tokenId)**\
Grant other people control of an NFT

**setApprovalForAll(address \_operator, bool \_approved)**\
Grant/recover control of all NFTs by a third party (\_operator)

**getApproved(uint256 \_tokenId)**\
Query the authorization of a certain NFT

**isApprovedForAll(address \_owner, address \_operator)**\
Query whether the operator is the authorized address of the owner

**supportsInterface(bytes4 interfaceID)**\
Query whether a certain interface is supported (interfaceID)

**event Approval(address indexed \_owner, address indexed \_approved, uint256 indexed \_tokenId)**\
Approval event will be triggered after Approval is successful

**event Transfer(address indexed \_from, address indexed \_to, uint256 indexed \_tokenId)**\
Successful transferFrom and safeTransferFrom will trigger the Transfer event

**event ApprovalForAll(address indexed \_owner, address indexed \_operator, bool \_approved)**\
ApprovalForAll event will be triggered after setApprovalForAll succeeds

A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.

solidity

```javascript
interface ARC721TokenReceiver {
       function onARC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external       returns(bytes4);
   }
```

**onARC721Received(address \_operator, address \_from, uint256 \_tokenId, bytes \_data)**

Works with the `safeTransferFrom` method, when \_to is the contract address, you need to call this method and check the return value. If the return value is not bytes4(keccak256("onARC721Received(address,address,uint256,bytes)")) an exception will be thrown. A smart contract that can receive NFT must implement the ARC721TokenReceiver interface.

> #### 📘
>
> The hash of bytes4(keccak256("onARC721Received(address,address,uint256,bytes))) is different from the Ethereum version bytes4(keccak256("onERC721Received(address,address,uint256,bytes))). With the return value of function `onARC721Received`, please use 0x5175f878 instead of 0x150b7a02.

## OPTIONAL Metadata Extension Interface

The metadata extension is OPTIONAL for ARC-721 smart contracts. This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.

solidity

```javascript
interface ARC721Metadata {
     function name() external view returns (string _name);
     function symbol() external view returns (string _symbol);
     function tokenURI(uint256 _tokenId) external view returns (string);
  }
```

**name()**\
Returns the contract name

**symbol()**\
Returns the contract symbol

**tokenURI(uint256 \_tokenId)**\
Returns the URI of the external file corresponding to \_tokenId. External resource files need to include names, descriptions and pictures.

## OPTIONAL Enumeration Extension Interface

The enumeration extension is OPTIONAL for ARC-721 smart contracts. This allows your contract to publish its full list of NFTs and make them discoverable.

solidity

```javascript
interface ARC721Enumerable  {
    function totalSupply() external view returns (uint256);
    function tokenByIndex(uint256 _index) external view returns (uint256);
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
  }
```

**totalSupply()**\
Returns the total amount of NFT

**tokenByIndex(uint256 \_index)**\
Returns the corresponding tokenId through \_index

**tokenOfOwnerByIndex(address \_owner, uint256 \_index)**\
Returns the tokenId corresponding to the index in the NFT list owned by the owner


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://developers.aixchain.com/aixc-and-arc-token/arc-721/protocol-interface.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
