Search
⌃K

Create and Deploy Your First Smart Contract on the XDC Network Using OpenZepplin and Remix

Use OpenZeppelin's Smart Contracts to create your tokens.
OpenZeppelin

Overview

OpenZeppelin is an open-source library to build secure smart contracts, provides many audited contracts, and is a good point to start and learn.

What you will learn

In this tutorial, you will learn how to create and deploy a Solidity smart contract using OpenZeppelin and deploy it to the Apothem test network.

What you will do

  • Set up OpenZeppelin
  • Create a simple non-fungible token contract
  • Compile
  • Deploy the contract
  • Verifying and interacting with

About OpenZeppelin library

OpenZeppelin is a “battle-tested” open-source framework comprised of reusable Ethereum smart contracts. The framework helps smart contract developers reduce the risk of vulnerabilities in their distributed applications by using standard, tested, community-reviewed code. It provides flexibility regarding how contracts are combined, along with custom useful extensions.

Using Contracts Wizard

OpenZeppelin's Contracts Wizard as an interactive smart contract generator is the easiest way to get started building smart contracts based on OpenZeppelin's components.
OpenZeppelin Contracts Wizard
Select the kind of contract that you want, set your parameters and desired features, and the Wizard will generate all of the code necessary. The resulting code is ready to be compiled and deployed, or it can serve as a starting point and be customized further.
​

Writing our first Non-Fungible Token (NFT)

ERC721 is a standard for non-fungible tokens and is defined in the EIP-721 Token Standard by Ethereum. With this standard, you can represent ownership of non-fungible tokens, where each token is unique. Let's build
👨💻
​

Create the contract

Joe's Free Voucher image
Joe has a Pizza shop and for the opening day, he wants to create a one-time free voucher for each client that show with her Web3 wallet.
To make a simple non-fungible token contract that can be paused and minted only by the owner, you'll use OpenZeppelin's ERC721 contract. Open Remix IDE, and create a new Solidity file named PizzaFreeVoucher.sol in the contracts folder:
How to create a new file in Remix IDE
How to create a new file in Remix IDE
How to create a new file in Remix IDE
Most of the OpenZeppelin contracts are expected to be used via inheritance, meaning you will inherit from them when writing your contracts. Here is a possible code for the contract. Copy the code below for your PizzaFreeVoucher.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
​
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
​
contract PizzaFreeVoucher is ERC721, Pausable, Ownable, ERC721Burnable {
​
using Counters for Counters.Counter;
​
Counters.Counter private _tokenIdCounter;
​
constructor() ERC721("Pizza Free Voucher", "JOE_FVOUCH") {}
​
function _baseURI() internal pure override returns (string memory) {
return "ipfs://QmUWy3zCsLLAu4jMpypUZkiEs9Nktnm3qNgKPzZVkrdpeo/#";
}
​
function pause() public onlyOwner {
_pause();
}
​
function unpause() public onlyOwner {
_unpause();
}
​
function safeMint(address to) public onlyOwner {
uint256 bal = balanceOf(to);
require(bal == 0, 'Already request your voucher');
​
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
​
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, tokenId);
}
}

Contract explained

The token behind the contract is an ERC721 token, which can be Pausable, is Ownable by someone, and can be also Burnable by someone. In this basic example, the owner has all this control, "Joe".
With contract PizzaFreeVoucher is ERC721, Pausable, Ownable, ERC721Burnable we define multiple inheritances, voucher contract is inherited from many contracts. By doing this, we can use some external properties from other contracts:
  • At our constructor, we call the OpenZeppelin's ERC721(name, symbol) constructor, where the token name is "Pizza Free Voucher" and the symbol is "JOE_FVOUCH".
  • As variables, we uniquely use a Counter to automatically store and increment the tokenId.
  • Functions:

Compiling

You only need to compile the Solidity file by changing the Remix tab to Solidity Compiler or by just hitting Ctrl + S in the editor.
Compile contract

Deploy the contract

Using this tutorial, you'll deploy the contract using a Web3 wallet compatible with XDC Network, the XDCPay. Install the wallet and create a new account. Next, you'll need to make sure you have network gas for interacting with the blockchain.
​
⚠
Because we are just testing, check if you are connected to the XDC Apothem testnet network.
Visit the XDC Apothem network faucet, enter the public address of your account, and Request 1000 XDC. After the success message from the faucet, you can confirm if you have 1000 XDC tokens transferred to your wallet.
Apothem Network Faucet
Apothem Network Faucet
Apothem Network Faucet
Now that you have gas, deploy the contract you previously created. Go to the deploy tab on your Remix IDE, set the environment to Injected Provider, and connect Remix with your XDCPay account. Select the PizzaFreeVoucher contract and click on Deploy.
Deploy
Deploy
Deploy
Next, you should see a pop-up notification to accept/deny the deployment transaction. Accept by clicking on Submit.
Verify
Verify
Wait for the blockchain confirmation in the Transactions tab of your wallet. You can now copy the transaction hash 0xe487f01b027172ce171f5980e465307da5bdb66a0425904ff8f48f25f797b15d
🥳
​
🥳
​

Verifying and interacting with your contract

Open the XDC Apothem Network Explorer and search for the previously copied hash. Here, at explorer, we can check all the transactions that occur on the network, including the deployment of our contract. Check the To address, should be your contract address (starting with xdc...).
Verify
In searching for the contract address on the explorer, you will see that the contract isn't verified. Click on Verify and Publish that will open the verification page.
Verify
You'll now have to submit the source code, name, address, and compiler version of the contract. With this, the final user can confirm if the contract was been verified or not, but also interact with it directly on the explorer.
​
ℹ
When using external dependencies in your code (for example OpenZeppelin imports or other imports), we need to flat all the code before verifying.
On the bottom-left corner in Remix, open Plugin Manager and install the Flattener plugin. Change to Flattener tab on the left navigation bar and click on contracts/Flattern PizzaFreeVoucher.sol (this will copy the flat code to your clipboard).
Flat the source code
Flat the source code
Back to the verification page, paste this code, and fill in the rest of the information. Finally, click Submit.
Verify
Once the contract is verified, simply navigate to Contract > Read Contract tab, and here you can perform reading actions, such as getting the balance of an account, getting the contract owner, etc.
Interact
Mint your first non-fungible token by going to the Write Contract tab. First, connect your web3 wallet by clicking on the Connect to Web3 button and then call the SafeMint method with the address that will receive the NFT.
Interact
Interact
Accept the action by submitting the transaction
🚀
​

Confirm the balance

If the mint transaction was confirmed, congratulations! The target address now has one free pizza voucher.
Interact
You can pick the voucher contract address (xdcF26E1ac69D9e173C96848FbD1bBE8759f5C71106) and add it to the list of XDCPay's tokens.
Confirm wallet
Confirm wallet
Confirm wallet
Now you can see the voucher NFT in your wallet
🚀
​
🚀
​