Comment on page
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
OpenZeppelin is an open-source library to build secure smart contracts, provides many audited contracts, and is a good point to start and 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.
- Set up OpenZeppelin
- Create a simple non-fungible token contract
- Compile
- Deploy the contract
- Verifying and interacting with
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.
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.
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
👨💻

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);
}
}
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". - Functions:
- Before the mint, to make sure each Joe's client can only have one voucher, we check if the balance of the address for this token is 0;
- Also, increment the tokenId.
-
_beforeTokenTransfer(address from, address to, uint256 tokenId)
: Hook that is called before any token transfer. This includes minting and burning.
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
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
🥳
🥳
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
🚀
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
🚀
🚀