XRC721

Introduction

XRC721 is an open standard that presents how to build unique non-fungible tokens on the XDC blockchain. Most tokens are fungible, whereas XRC721 tokens are, each of them, unique—they are best thought of as rare, inimitable, one-of-a-kind items.

The XRC721 standard is more complex than the XRC20 standard. It defines the minimum requirements a smart contract must meet for unique tokens to be owned, managed, and traded. The XRC721 standard has multiple optional extensions, split between several contracts. But it does not prevent the addition of supplemental functions or mandate a standard for token metadata.

Construct an XRC721 Token Contract

XRC721 tokens can be used to track various items with unique attributes in a hypothetical game. The tokens are minted and awarded to the players as required by the game rules, at which point players can keep or transfer their tokens. Note that any account can call awardItem to mint tokens. Access control is added, however, to restrict accounts from minting tokens.

The contract for a tokenized item might look like this:

contract GameItem is XRC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() public XRC721("GameItem", "ITM") {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

The XRC721 also includes IXRC721Metadata and IXRC721Enumerable standard extensions. Here, the _setTokenURI method is used to store an item’s metadata.

Unlike XRC20, XRC721 does not have a decimal field because every token is unique, a whole, and thus cannot be partitioned.

XRC721 Read MethodsXRC721 Write Methods

name()

transferFrom(recipient, amount)

symbol()

safeTransferFrom(spender, amount)

totalSupply()

setApprovalForAll(operatorAddress, booleanValue)

balanceOf(owner address)

approve(receiverAddress, tokenId)

ownerOf(tokenId)

tokenURI(tokenId)

tokenByIndex(index)

tokenOfOwnerByIndex(ownerAddress,index)

Read methods

symbol() → string Provides the symbol of the token, mostly just an abbreviation of the name.

name() → string Provides the name of the token.

totalSupply() → uint256 Returns the total amount of tokens in the contract.

balanceOf(address account) → uint256 Provides the number of non-fungible tokens in the owner's account.

ownerOf(tokenId) → address Returns the NFT owner specified by tokenId.

tokenURI(uint256 tokenId) → string Gives the URI for a tokenID.

tokenOfOwnerByIndex(address owner, uint256 index) → uint256 Returns the token ID at a given index of the requested owner.

tokenByIndex(uint256 index) → uint256 Returns the token ID at a given index.

supportInterface(tokenId) → bool Sets its value true if the contract implements the interface defined by interfaceId.

getApproved(tokenId) → address Returns the approved address for a token ID or sets it to zero if no address. If the token ID does not exist, it reverts.

isApprovedForAll (address owner, address operator) → bool Tells whether a given owner approves an operator.

Write Methods

approve(address to, uint256 tokenId) Approves the address that sends the given token ID. It ensures to approve only one address per token at a given time. Only the token owner or an approved operator can call the approve method. The zero address means that no approved address exists.

transferFrom(address from, address to, uint256 tokenId) Provides the ownership of a given token ID to another address.

safeTransferFrom(address from, address to, uint256 tokenId) Safely provides the ownership of the requested token ID to another address.

setApprovalForAll(address operator, bool approved) setApprovalForAllmethod grants or revokes the approval of a given operator. An operator can send all tokens of the sender on their behalf.

Usage

When the user wants to use the SDKPHP library he/ she need to follow the below steps

  1. Create a folder User convient (eg : sdk)

  2. Inside the folder open the command prompt and type composer require xdc3/php

  3. Create a file according to User convient (eg : index.php)

  4. After creating user need to add the path , import the classes and create the object

  5. (Optional) If user wants to change the URL Goto vendor -> XDC3 folder -> PHP folder -> .env file

Important

This library provides simple way to interact with XDC XRC20 & XRC721 tokens. Before Installing This Library

  1. Install php version 7.4.25 on the system

  2. Go to PHP Folder on the system, open php.ini file then enable gmp and curl extensions

    1. Remove ";" from ";extension=gmp" to enable this Extension

    2. Remove ";" from ";extension=curl" to enable this Extension

  3. Enable ";curl.cainfo =" and add SSL Certificate path here

    1. To download the SSL Certificate go to https://curl.se/docs/caextract.html then click on cacert.pem on the top.

    2. Copy the path of the certificate and paste in the php.ini file

      1. curl.cainfo = "C:\Users\HP\Downloads\cacert.pem"

  4. Install openssl in the system using chocolately

    1. Run the following command in admin powershell to install openssl

      1. choco install openssl

Folder Info

In XDC library inside the vendor folder -> xdc3base -> php we can find the all called functions of the XRC20 methods . (including contract file , address calling from apothem file etc)

In PHPS library inside the vendor folder -> xdc3 -> php we can find the all calling functions from the XDC library. (ex : in modules xrc20 folder contains every calling methods)

Example

//path configuration
include "vendor/phps/sdkxdc/library.php";
//Import classes of XDC721
use XRC721\SDK\XRC721SDK;
//Creating a Objects to call the functions of XRC20 and Create a wallet for the User
$obj2 = new XRC721SDK();
Name func :-
$obj2->getName($contractAddress);
Symbol func :-
$obj2->getSymbol($contractAddress);
TotalSupply func :-
$obj2->getTotalSupply($contractAddress);
BalanceOf func :-
$obj2->getBalanceOf($contractAddress,$ownerAddress);
SupportsInterface func :-

$obj2->getSupportInterface($contractAddress,$interfaceId);
OwnerOf func :-

$obj2->getOwnerOf($contractAddress,$tokenId);
TokenURI func:-

$obj2->getTokenURI($contractAddress,$tokenId);
TokenByIndex func :-

$obj2->getTokenByIndex($contractAddress,$index);
TokenOfOwnerByIndex func :-

$obj2->getTokenOfOwnerByIndex($contractAddress,$ownerAddress,$index);
GetApprove func:-

$obj2->getApproved($contractAddress,$tokenId);
Approve func:-

$obj2->approve($contractAddress,$recieverAddress,$tokenId,$privateKey);
SetApprovedForAll func :-

$obj2->setApprovalForAll($contractAddress,$operatorAddress,$approvedStatus,$ownerPrivateKey,$tokenId);
IsApprovedForAll func :-

$obj2->setApprovalForAll($contractAddress,$operatorAddress,$approvedStatus,$ownerPrivateKey,$tokenId);
SafeTransferFrom func:-

$obj2->safeTransferFrom($contractAddress,$ownerAddress,$recieverAddress,$tokenId,$approvedPrivateKey);
TransferFrom func:-

$obj2->transferFrom($contractAddress,$ownerAddress,$recieverAddress,$tokenId,$approvedPrivateKey);
TransferOwnership

$obj2->transfer($contractAddress,$ownerAddress,$recieverAddress,$tokenId,$approvedPrivateKey);

Last updated