> 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.md).

# ARC-721

## 1 ARC-721 Protocol Standard

ARC-721 is a set of standard interfaces, for issuing non-fungible tokens(NFT) on the AIXChain network. ARC-721 is fully compatible with ERC-721.

### 1.1 ARC-721 Smart Contract Interface Implementation

Every ARC-721 compliant contract must implement the ARC721 and ARC165 interfaces. Other extension interfaces can be implemented according to specific business requirements.

#### 1.1.1 ARC-721 & ARC-165 Interfaces

```javascript
pragma solidity ^0.4.20;

  interface ARC721 {
    // Returns the number of NFTs owned by the given account
    function balanceOf(address _owner) external view returns (uint256);

    //Returns the owner of the given NFT
    function ownerOf(uint256 _tokenId) external view returns (address);

    //Transfer ownership of NFT
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;

    //Transfer ownership of NFT
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;

    //Transfer ownership of NFT
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

    //Grants address ‘_approved’ the authorization of the NFT ‘_tokenId’
    function approve(address _approved, uint256 _tokenId) external payable;

    //Grant/recover all NFTs’ authorization of the ‘_operator’
    function setApprovalForAll(address _operator, bool _approved) external;

    //Query the authorized address of NFT
    function getApproved(uint256 _tokenId) external view returns (address);

    //Query whether the ‘_operator’ is the authorized address of the ‘_owner’
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);

    //The successful ‘transferFrom’ and ‘safeTransferFrom’ will trigger the ‘Transfer’ Event
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    //The successful ‘Approval’ will trigger the ‘Approval’ event
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

    //The successful ‘setApprovalForAll’ will trigger the ‘ApprovalForAll’ event
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

  }

  interface ARC165 {
      //Query whether the interface ‘interfaceID’  is supported
      function supportsInterface(bytes4 interfaceID) external view returns (bool);
  }
```

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

Solidity

```javascript
interface ARC721TokenReceiver {
     //This method will be triggered when the ‘_to’ is the contract address during the ‘safeTransferFrom’ execution, and the return value must be checked, If the return value is not bytes4(keccak256("onTRC721Received(address,address,uint256,bytes)")) throws an exception. The smart contract which can receive NFT must implement the TRC721TokenReceiver interface.
       function onARC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external                returns(bytes4);
   }
```

> The hash of `bytes4(keccak256("onWRC721Received(address,address,uint256,bytes)))` is different from the Ethereum version `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)))`. Please use `0x5175f878` instead of `0x150b7a02`.

#### 1.1.2 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 {
     //Return the token name
     function name() external view returns (string _name);

      //Return the token symbol
     function symbol() external view returns (string _symbol);

       //Returns the URI of the external file corresponding to ‘_tokenId’. External resource files need to include names, descriptions and pictures. 
     function tokenURI(uint256 _tokenId) external view returns (string);
  }
```

URI is a URI link describing the \_tokenId asset, pointing to a JSON file that conforms to the ARC721 metadata description structure. When tokens are minted, each token needs to be assigned a unique URI:

JSON

```json
{
    "title": "Asset Metadata",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "Identifies the asset to which this NFT represents"
        },
        "description": {
            "type": "string",
            "description": "Describes the asset to which this NFT represents"
        },
        "image": {
            "type": "string",
            "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive."
        }
    }
}
```

#### 1.1.3 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  {
    //Return the total supply of NFT
    function totalSupply() external view returns (uint256);

    //Return the corresponding ‘tokenId’ through ‘_index’
    function tokenByIndex(uint256 _index) external view returns (uint256);

     //Return the ‘tokenId’ corresponding to the index in the NFT list owned by the ‘_owner'
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
  }
```
