Skip to main content
Version: v1.3

Create ERC721 NFTs

EVM-only NFT

Please keep in mind that this is an EVM-only NFT. It's not tied to L1 native assets. Also, these are different from L1 NFTs.

Required Prior Knowledge

This guide assumes you are familiar with the concept of tokens in blockchain, Ethereum Request for Comments (ERCs)(also known as Ethereum Improvement Proposals ( EIP)) , NFTs, Smart Contracts and have already tinkered with Solidity.

You should also have basic knowledge on how to create and deploy a smart contract.

About ERC721

Non-fungible tokens or NFTs are a type of token that can represent any unique object, including a real-world asset on a decentralized network. NFTs are commonly represented by the (ERC721 standard). You can use the openzepplin lib @openzeppelin/contracts/token/ERC721/ERC721.sol to streamline your development experience.

You can also use the (OpenZepplin Contracts Wizard) to generate and customize your smart contracts.


This guide will use the Remix IDE, but you can use this contract with any IDE you are familiar with.

Create the Smart Contract

The following is an example NFT Smart Contract called "IotaEVMSampleNFT".

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";

contract IotaEVMSampleNFT is ERC721, Ownable {
uint256 private _nextTokenId;

constructor(address initialOwner)
ERC721("IotaEVMSampleNFT", "SSNFT")

function _baseURI() internal pure override returns (string memory) {
return "";

function safeMint(address to) public onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);

As you can see above, the contract uses standard methods for the most part. You should pay attention to the following:

  • pragma solidity ^0.8.20;: This line means the contract uses solidity compiler version 0.8.20 or above.
  • contract IotaEVMSampleNFT is ERC721, ERC721URIStorage, Ownable: This line defines the contract's name, and what other contracts it implements.
  • ERC721("IotaEVMSampleNFT", "SNFT") {}: This line defines the token name and symbol. You can name it whatever you want. We recommend using the same name for the token and the contract.
  • return "";: You should define the base URI of your NFTs. That means the URL you provide here will be used for all your tokens. Since this contract uses auto-incremental token IDs, your token URI will look something like,,, and so on.
  • function safeMint(address to, string memory uri) public onlyOwner {: The safeMint function will require that you manually input a token's to address and a uri every time you want to mint. This should work for regular use cases.

Customize on OpenZeppelin

You can customize your contract depending on how you want it to behave. You should consider the following topics and questions:

  1. Ownership — Who owns it? How is it stored?
  2. Creation — Method or Type of Creation.
  3. Transfer & Allowance — How will tokens be transferred? How will they be available to other addresses and accounts?
  4. Burn — Do you want to destroy it? If yes, how?

You can click on Copy to Clipboard and paste it into the IDE of your choice, download it, or click on Open in Remix directly.

Set the Initial Owner

Before you can deploy this contract, you will need to set the Initial Owner address; this can be your own IOTA EVM address.

"Set the initial owner" img.png

Deploy a Smart Contract

Deploy a Solidity Smart Contract following our how to Deploy a Smart Contract guide.

Mint Your Custom NFTs

So far, you have created and deployed the contract. But, you probably want to mint some NFTs. To do, you should:

  1. Open the contract (listed under Deployed Contracts).

  2. Insert your target IOTA EVM in beside the safeMint button and then click the button.

    Safe mint

  3. Confirm the transaction on Metamask.

    Confirm in metamask

If you visit your address in the visit the IOTA EVM Explorer, ShimmerEVM Explorer or EVM Testnet Explorer you should see your NFTs listed under Tokens.