How to create and deploy an XRC-721 (NFT) on XinFin Hybrid Blockchain
What is a Non-Fungible Token?
Fungible means to be the same or interchangeable. For example, XinFin tokens, all the members of a particular token class, have the same value. The same can be said of XinFin tokens. Fungible tokens are interchangeable 1:1.
With this in mind, NFTs are unique; each one is different. Every single token has unique characteristics and values. The types of things that can be NFTs are collectible cards, artworks, airplane tickets, etc. They are all clearly distinguishable from one another and are not interchangeable. Think of Non-Fungible Tokens (NFTs) as rare collectibles; each has unique characteristics, unusual attributes, and most times, its metadata
What is XRC-721?
XRC stands for XinFin Request for Comment, and 721 is the proposal identifier number. XRCs are application-level standards in the XinFin ecosystem, they can be a smart contract standard for tokens such as XRC-20, the author of an XRC is responsible for building consensus with the XinFin community and once the proposal is reviewed and approved by the community it becomes a standard. You can track the recent XRC proposal here. XRC-721 was created to propose the functionality to track and transfer NFTs within smart contracts.
XRC-721 is an open standard that describes how to build Non-Fungible tokens on EVM compatible blockchains; it is a standard interface for Non-Fungible tokens; it has a set of rules which make it easy to work with NFTs. NFTs are not only of XRC-721 type; they can also be XRC-1155 tokens.
The following are the set of functions and events defined in the XRC-721 standard:
XRC-721 defines some functions with compliance to XRC-20. This makes it easier for existing wallets to display simple token information.
XRC20-like Functions:
- name: Used to define the token’s name, which other contracts and applications can identify.
- symbol: Used to define a token’s shorthand name or symbol.
- totalSupply: This function is used to define the total number of tokens on the blockchain; the supply doesn’t have to be constant.
- balanceOf: Returns number of NFTs owned by an address.
Ownership Functions
- ownerOf: This function returns the address of the owner of a token. As each XRC-721 token is unique and non-fungible, they are represented on the blockchain by an ID. Other users, contracts, apps can use this ID to determine the owner of the token.
- approve: This function grants or approves another entity the permission to transfer tokens on the owner’s behalf.
- takeOwnership: This is an optional function that acts like a withdraw function since an outside party can call it to take tokens out of another user’s account. Therefore, takeOwnership can be used when a user has been approved to own a certain amount of tokens and wishes to withdraw said tokens from another user’s balance.
- transfer: This is another type of transfer function; it allows the owner to transfer the token to another user, just like other digital tokens/coins.
- tokenOfOwnerByIndex: This is an optional but recommended function. Each owner can own more than one NFT at the same time. Its unique ID identifies every NFT, and eventually, it can become difficult to keep track of IDs. So the contract stores these IDs in an array and the tokenOfOwnerByIndex function lets us retrieve this information from the array.
Metadata Function
- tokenMetadata: This optional feature is an interface that lets us discover a token’s metadata or a link to its data.
Events
- Transfer: This event is fired when the ownership of the token changes from one individual to another. It emits the information on which account transferred the token, which account received the token, and which token (by ID) was transferred.
- Approve: This event is fired when a user approves another user to take ownership of the token, i.e., it is fired whenever the approve function is executed. It emits the information on which account currently owns the token, which account is approved to take ownership of the token in the future, and which token (by ID) is approved to have its ownership transferred.
Use cases of Non-Fungible Tokens (NFTs):
- Digital art (or physical art): Art pieces are the most popular use cases of NFTs. Digital art auctions were the first application of NFTs and continue to grow.
- Gaming: Providing in-game purchases and collectibles of games.
- Real estate: Tokenizing properties and smart contracts and carry buying and selling.
- Finance: Financial instruments like loans, futures, and other responsibilities.
- Software titles: Software licenses to ensure anti-piracy and privacy.
- Concert tickets/Sports match tickets: To ensure that no fraud happens in ticket selling and fans can have a single place to view past experiences.
- KYC compliance: Creating a token for a specific user’s KYC.
Getting test XDC
Now that we know what XRC-721 tokens are and how they work, let’s see how we can build and deploy our own tokens.
We’ll deploy our contract on the Apothem testnet. To get started, you will need the XDCPay browser extension to create an XDC wallet and some test XDC, which you can get by going to the Apothem faucet. You’ll need to select Apothem Network on your XDCPay wallet and copy-paste the wallet address into the text field in the faucet, then click get 1000 XDC.
Adding Files to IPFS
Before writing our NFT contract, we need to host our art for NFT and create a metadata file; for this, we’ll use IPFS — a peer-to-peer file storing and sharing distributed system. Download and install IPFS CLI based on your Operating system by following the installation guide in IPFS docs.
Following are the steps for hosting the image and metadata file.
Step 1: Creating IPFS repo.
Start the IPFS repo by typing the following in a terminal/cmd window.
Step 2: Starting the IPFS daemon.
Start IPFS daemon, open a separate terminal/cmd window and type the following.
Step 3: Adding an image to IPFS
Go to the first terminal window and add the image to IPFS (Duabi.png here).
Copy the hash starting from Qm and add the “https://ipfs.io/ipfs/” prefix to it; it must look something like this
https://ipfs.io/ipfs/QmNQ7pbUY11tRWDQCjcGYd3YLPw9kdRsHLp5q6NQbyMEM6?filename=nft.jpeg
Step 4: Adding JSON file to IPFS
Create a JSON file nft.json and save it in the same directory as the image.
JSON file format:
{“name”: “Dubai Art”,“description”: “This image shows the true nature of NFT.”,“image”: “https://ipfs.io/ipfs/QmNQ7pbUY11tRWDQCjcGYd3YLPw9kdRsHLp5q6NQbyMEM6",}
Now add the JSON file.
Copy the hash starting from Qm and add the “https://ipfs.io/ipfs/” prefix to it; it must look something like this https://ipfs.io/ipfs/QmNQ7pbUY11tRWDQCjcGYd3YLPw9kdRsHLp5q6NQbyMEM6
Save this URL. We’ll need this to mint our NFT.
Creating our own token.
For ease and security, we’ll use a simple XRC-721 contract to create our NFT. With 0xcert/ethereum-erc721, we don’t need to write the whole XRC-721 interface. Instead, we can import the library contract and use its functions.
Head over to the XinFin Remix IDE and make a new Solidity file, for example — nft.sol
Paste the following code from GitHub https://github.com/RuslanWing/Smartcontracts/blob/main/XRC-721.sol to your new Solidity script:
Explanation of the code of GitHub:
Line 1: Specifying SPDX license type, which is an addition after Solidity ^0.6.8. Whenever the source code of a smart contract is made available to the public, these licenses can help resolve/avoid copyright issues. If you do not wish to specify any license type, you can use a special value UNLICENSED or simply skip the whole comment (it won’t result in an error, just a warning).
Line 2: Declaring the solidity version.
Line 4–5: Importing 0xcert/ethereum-erc721 contracts.
Line 7: Starting our Contract named newNFT and mentioning it’s extending NFTokenMetadata and Ownable contracts.
Line 9–12: Initializing the constructor and setting name, a symbol of our token.
Line 14: Declaring function mint with three arguments, variable _to of type address which will store the address of the receiver of NFT token, variable _tokenId of uint256 type which will hold the token id, variable _uri of type string which will store the URI of the JSON file. Declaring mint as external means, it can be accessed from other smart contracts and outside the self scope.
Line 15: Minting token using the address of the receiver and token id.
Line 16: Setting token URI using token id and URI of JSON file.
Compile the smart contract and deploy it using injected Web3 (make sure to select Apothem network on XDCPay before compiling the contract). Approve the transaction from XDCPay.
If you receive an error message before deployment, “This contract may be abstract,” make sure to select the appropriate contract under the Contract tab.
Confirm the transaction in XDCPay
Now go to the “Deployed Contracts” section in Remix and expand the deployed contract. You’ll see a bunch of functions/methods. Expand the mint function and add the following details:
- Add your XDCPay address in the _to the field.
- Enter any Big number value in the _tokenid field (we suggest 1 since it’s the first).
- Add the URI of the JSON file in the _uri field, which we obtained in the previous section.
Click on transact and confirm the transaction from XDCPay. Now you have the token on the Apothem network.
You can check other details like name, symbol, owner, or tokenuri by entering the token id we mentioned earlier.
Conclusion
Congratulations on creating your very own NFT. Become an artist yourself, and help your artist friends put their artistic work on the XinFin blockchain which is a green blockchain that charges near-zero gas fees at a speed of 2000+ TPS.