The topic of Non–fungible tokens (NFTs)  is capturing broad interest from people outside of Web3:  popular media, celebrities, traditional business, social media influencers, and more. With all of the hype around multi-million dollar trading prices and “insert your favorite celebrity” shilling NFTs, it’s easy to get lost in the headlines. With this post, I hope to provide background on NFTs, some of their lesser known use cases, and some of the developer pains around NFTs. We will use Replit to create an NFT collection and give you practice minting your own NFTs.

Generally speaking, one of the least understood parts of NFTs is the word non-fungible. If you already have a firm understanding of this, well done! To get all of us on the same page, let’s define it here. I’ll first start with the definition of “fungible”. A defines it as:

“being of such nature or kind as to be freely exchangeable or replaceable, in whole or in part, for another of like nature or kind.”

In other words, fiat currency, ERC-20 tokens, and M&M’s are fungible. Any one of a like-kind can serve as an equivalent replacement for the other. Non-fungible describes a uniqueness both in form and value in which they cannot replace each other. Baseball cards, real estate property like your home, and cats are non-fungible. It is logical that digital collectibles are an obvious use case for NFTs. The uniqueness and rarity of a particular NFT can drive value amongst a group of collectors.


According to the dates on the EIP list, the proposal around NFTs came around 2018 with ERC-721. With a lot of the focus on fungible tokens in years previous, this proposal started discussion around use cases for non-fungible tokens. The idea of a digital token representing uniqueness has a broad number of use cases that extend well beyond the current trend of digital collectibles.

  • Physical world value representation (deeds)
  • Negative value assets (debt paper)
  • Unique representation of ownership (rights from ownership)

As developers started exploring the NFT world, a number of extensions have been proposed ERC-1155 (MultiToken), EIP-2981 (Royalty Standards), EIP-3569 (Sealed MetadataURI standard)  EIP-3754 (Generalized NFT Standards),  EIP-3589 (Fungible Asset Collections).

With projects such as BAYC, CryptoPunks, and EulerBeats exemplifying the most popular projects, it’s hard to separate the idea of NFT from digital collectibles. Although digital collectibles is the dominant use case, it should be noted that NFTs can be used in much more broad applications.

One example of a non-digital collectible NFT is ENS domains. As of 2019 ENS became ERC-721 compliant. That means that domains can be transferred exactly the same as other NFTs. You can even trade them on OpenSea! While there are some differences between how an ENS domain is implemented compared to your favorite Bored Ape, you can trade them on open NFT marketplaces the same way.

As many of the projects today focus NFTs on digital art, that will be the use case we explore in this post. On with the show.

Developer Concerns

When starting an NFT project from scratch, there are a number of decisions and risks you have to consider. I’ve outlined a few here.

Let’s start with the contract. ERC-721 and ERC-1155 (and some of the extension standards) define a standardized interface you need to implement to be compliant; they say nothing about the implementation details. This means that if you develop a contract from scratch you should have it reviewed before deploying it and sending real value through it. To complete this part you need to learn Solidity, learn how to do a security audit on it (or hire a professional group like Consensys Diligence), and then deploy and hope for the best. If you have a bank roll, maybe you would want to offer a bounty for post-launch auditing.

Another set of decisions has to do with the collection itself. Are you going to do generative art (art produced by a renderer based on the metadata)? Is it going to be a collection of original art like Damian Hirst’s The Currency? Is it pregenerated? Dynamically generated? Either way, you have decisions to make as to what you want to represent and how you want to compile the metadata. This metadata is eventually going to be referenced by your contract’s tokenUri and be permanently immortalized on the blockchain. No pressure.

So, you got your assets together? Great! Now you need to decide on a place to store it. Will it be centralized, decentralized, or on-chain?

There’s a number of ways you can store your metadata. The ERC-721 spec calls for metadata to be stored in a tokenUri field in the contract. Anything that qualifies as a URI could technically work: https://, ipfs://, data-uri;, etc. There is some debate as to which is the best method. Storing on a centralized hosting provider (S3, web hosting, etc) is best, said no one ever, so we can cross that off the list straight off. Seriously speaking, centralized hosting runs the risk of going offline if the hosting provider is censored, a self hosted web server crashes, or someone forgets to pay the bill. It’s best not to risk that.

Some say that encoding it to a data-uri is best because it keeps all of the data on-chain and not reliant on additional storage technologies. While it does simplify the technology stack and has the benefit of getting the data in a single call, it comes with a higher gas cost and some inflexibility.

Some say IPFS is best because it gives you a content addressable URI (guaranteeing the content won’t change) and it’s off chain, so it saves on gas costs. We will be using IPFS in this blog post through Infura’s IPFS API. Whichever you pick is up to you and will be great. Except for the central storage idea. That one is not ok.

Now that you have all of that together, you have to send all of the transactions to mint. This is fine to put together manually if you are only minting a handful of NFTs. But what if you are dropping 10,000? How do you manage all of those transactions? While that is beyond the scope of this post, it is something you need to consider with larger NFT projects.

Get to the Minting Part, Already

Working with Replit

Replit is a browser based working environment. It allows for real time collaboration on a project and can be used for exploring ideas. All you need is an internet connection and a web browser to start collaborating on a project.

Replit makes it easy to start with a template and start jamming on code. Even better, you can share a link and mob program the project all in real time! Let’s get started by forking  this REPL.

Once we fork it into our account, we can dig in. The REPL we are working with is based on the public Solidity template with some extra tools geared toward the NFT use case. The template provides an easy way to connect a wallet, write and deploy contracts, and includes some CLI tools to help manage the creation process.

Starting With the Contracts

Writing contracts can have a steep learning curve: learning solidity, avoiding security risks, and understanding how to call and build on top of them. For standard contracts like ERC-721 / ERC-1155, there are open source libraries like OpenZepplin.  If the out of the box contracts don’t fit your project, you can still write your own contracts and get a security audit from Consensys Diligence and be assured that your contracts are secure. The REPL comes with 2 OpenZepplin contracts as a starting point: one for ERC-721 and one for ERC-1155.

Let’s customize this contract, then deploy it. Going for simplicity (and a no cost testnet), let’s implement an ERC-721 token on the Goerli testnet. There are 2 fields that are part of the contract that need to be filled out on creation. We have to give our token collection a name and a symbol. Since I have a small collection of badly made memes for this blog, I’ll use the name “Bad Meme Token”, and symbol “BM”. Seems like a good name for this token. With that out of the way, let’s deploy.

Now that we have the contract deployed we can get on prepping our tokens. It’s super easy in the REPL. The REPL gives us simple and easy access to make contract calls and send transactions to the network. All you have to do is customize your contract, connect your wallet, connect to Infura IPFS, and start deploying!

Create the assets on IPFS

As stated before, we will use the Infura IPFS API. All of the minting we are going to do in this blog post fits within the Free Plan, so you don’t need to be on a paid tier in order to experiment with minting NFTS.

The REPL gives us an easy way to manage the IPFS assets. In the template there is an assets folder. For all of the images we want to manage as an NFT, we first need to upload them to IPFS.

  1. Create an Infura account (if you don’t already have one)
  2. From your dashboard, hit “Create a New Project”
  3. Select IPFS and fill out the project info
  4. Take note of your project ID and Secret
  5. Enter the Project ID and Project Secret into the REPL’s secrets manager as PROJECT_ID and PROJECT_SECRET
  6. Open the REPL Shell
  7. Enter the command npm run ipfs -d ./assets -g *.jpg
  8. Take note of all of the CID URLs (you will need this for the metadata generation)
  9. Using the CID URLs, generate and upload all of the metadata URLs.
  10. For each of those URIs generate the NFT!

There are some variations on how to do this and manage NFT assets on IPFS, but this is the simplest version. For the next level, look into managing a directory of assets in IPFS!

Gather the metadata

Ok, now that we’ve finished the initial asset storage it’s time to create the NFT metadata. NFTs need to have a metadata url associated with it. This needs to be a web compatible URL and can take one of 2 basic forms: An http url pointing to a storage solution (like IPFS) or a data-uri that is encoded and stored directly on-chain. While there are a lot of benefits with the data-uri direction, it is less flexible and more expensive than managing it with external storage. We’ll focus on the former for this tutorial.

Since we are doing a digital collectible, we assume that we want to have it appear on OpenSea so we can sell it for 100 ETH! OpenSea has metadata standards it recommends so we can easily display it in the marketplace. The metadata part is simply a json file that represents some descriptive data as well as the attributes (that help make the NFT unique). Using the image url’s we generated in the last step, we can create a json file like the following:

Once we have all of the JSON files created and on the filesystem, we can use the same ipfs utility to upload them to IPFS.

npm run ipfs -d ./assets -g *.json

We make note of all of the new URLs from the JSON upload process. That’s it! We’ve prepared everything that we need to mint our NFTs!

Mint all the things

Back to the REPL! The UI allows us to easily call contract methods and fill in all of the metadata without having to code it up. In the UI, locate your contract and click to expand the methods.  Locate the “mint” method. Enter the address of the recipient (put in your own address, unless you have a collection of addresses you want to mint to). Copy and paste the IPFS URL in the tokenURI field. And then:

BAM! You have achieved NFT. Congratulations.

Final Thoughts

We’ve stepped through some basics on how to mint some fresh NFTs using OpenZepplin, Replit, and IPFS on Infura. We’ve even created an entire BM collection! Now that you have the basics of minting an NFT, there are a number of topics you can explore further. Some examples include exploring novel use cases for NFTs, fractionalizable NFTs, how to manage a token drop, and using NFTs as a proof of ownership for other on-chain adventures. And because we've explored creating an NFT project from a beginner's perspective, there's still a lot of scope for you to play with. If you're interested in something more out-of-the-box, with quick-start features like a white-label storefront, support for fiat payments and email-based redemption flows, check out ConsenSys NFT. I hope this post can serve as an inspiration and a bit of hands on experience for your next world changing project. If you end up launching something, tweet us @infura_io!!!