What is the hype about NFTs & How to mint your own NFT without OpenSea

Priyal Saxena
Nybles
Published in
14 min readFeb 21, 2022

NFTs, these three simple letters are dominating the world right now. Unless you have been living under a rock, you certainly must have heard of them. The fact that a Nyan cat gif was sold as an NFT for about $587,000 sounds nuts, doesn’t it?

But, what is a NFT? It’s the latest trend that is sweeping the internet. Is it hype? Yes. Could it change our world? Yes.

NFTs might be a new hype, but the basic concept behind it, isn’t new at all. It’s how we value things. Ancient humans valued food, then we started valuing land, and then currency. If you think about it, currency is just a piece of paper, which we all collectively as a society decide to associate with a certain value.

The full form of NFT is Non-Fungible Token. So, there are two keywords here, “Non-Fungible”, and “Token”.

Non-Fungible

Fungible means replaceable. For example, a dollar is the exact same as another dollar and hence, is replaceable by any other dollar. A dollar is Fungible. So are bitcoins, or mass-produced Ikea furniture. But the ring your partner proposed you with is unique, and isn’t replaceable by any other ring in the world, so it’s Non-Fungible. It’s valuable because it’s one of its kind.

Token

Token is defined as “a voucher that can be exchanged for goods or services, typically one given as a gift or forming part of a promotional offer”. Now, to understand NFT, we first need to first understand Blockchain.

Blockchain

Imagine that you are craving ice cream. So you walk to the ice-cream parlor down the street, you choose a flavor, pull out your wallet while our guy Jimmy scoops your ice cream, and pay him with your debit card. You swipe your card, enter the details, and Boom! you just paid for your ice cream. Without even touching money. Simple, right? But there is a lot that happens in the background, first your bank checks if you have enough money in your wallet to pay for your ice-cream or not. After receiving confirmation that you indeed have enough money, your bank approves your transaction and deducts the amount from your account, and then Jimmy’s bank adds it to his account.

A smart guy wanted to decentralize this process. To handle such transactions without banks. He invented Blockchain.

Instead of Jimmy’s and your bank coordinating to handle your transaction, we can now record all the transactions publicly on the internet. Your account balance is now, in a way, publicly known. Now, let’s say Jimmy asks for 4 crypto coins in exchange for the ice cream. And you decide to pay him by swiping your new flashy crypto-currency-card. Now, instead of a bank checking, if you have the required balance, and approving the transaction, millions of other computers do that. For example, if you don’t have 4 crypto coins in your wallet, then all the other computers will know that you don’t and won’t allow your transaction. But if you do have 4 crypto coins, all computers will allow your transaction, and it will be recorded in the public ledger. That is the basic idea of blockchain.

How does all this combine to form NFTs?

Until now, digital media could not be owned the way people own fine art or rare coins, because it could be easily copied, shared, or stolen. But what if we could have a public record of certificates certifying that a specific digital media is owned by a specific person? What then? People would start collecting digital media the same way people have been collecting stamps or coins.

Now, let’s say 0x7eb2…3f6b, a nameless Foundation account without a profile description, decides to pay $587,000 for a certificate that says that a cat gif, the “Nyan cat gif” is now owned by him. The only thing all the other computers care about is if this 0x7eb2…3f6b guy has enough money to pay the required amount? If he does have that amount (which he did), then all the computers approve the transaction, and now that NFT belongs to him.

This transaction is now recorded on a permanent public ledger (blockchain), which will now serve as a sort of certification of authenticity that cannot be altered or erased.

So recording transactions on blockchain basically gives rise to certify owners of “original” digital media, and this makes digital media non-fungible. This allows for artists, musicians, influencers, and sports franchises to make money selling digital goods that would otherwise be cheap or free.

Ethereum

Ethereum is a decentralized, open-source blockchain with smart contract functionality. These smart contracts are packet of codes which are attached to all NFTs. They allow the NFT to be individually unique, verifiable, and traceable. These contracts are very secure against hacking and copying. This allows for NFTs to be bought with crypto currency, typically Ethereum.

Uses of NFTs

Major companies like Twitter, Nike and Facebook are already evolving to integrate NFTs in their work system. Possibilities in regards to NFTs are endless, and we are just scratching the surface. There is a huge possibility for new innovations in near future, that will completely change the way world operates.

Gaming- Recent Innovations allow gamers to earn NFT digital assets through their game-play. This creates a symbiotic relationship between the game developers and gamers, which distributes power between the two. These assets can then be sold for actual money. These NFTs are compatible and usable in other virtual environments as well, so even if a particular game shuts down, earned NFTs are still useful.

Real estate- All details that typically goes in the lengthy paperwork of a real estate transaction, like contracts, certifications, ownership and claim history will now be stored in the blockchain and will be publicly accessible. This will automate paperwork and eliminate several layers of middlemen. Because Smart Contracts are nearly impossible to alter, it will also mitigate real estate fraud.

Metaverse- Metaverses are virtual worlds where essentially the internet is brought to life. There is an abundant possibility within metaverse worlds, where you get to design your life, design your avatar, and interact with real people in virtual communities, by using virtual reality headsets. Metaverses will be more of a “place” where you and your friends can visit. NFTs will be an essential part of metaverses and will serve as the building blocks for assets that can be utilized across all these worlds. There will be NFT art on the walls of your virtual home, and your NFT music playing in the background. You will be able to gift your friends NFT goods like clothes, or watches. NFTs will also help blend metaverse with real world. For example, physical events like music concerts will have digital counterparts in virtual worlds.

Why do people buy NFTs?

So, finally, why in the world would someone pay $587,000 for a cat gif, or for any NFT for that matter? There are two reasons; two kinds of buyers. One has a taste for finer things in life, and they want to “collect” these NFTs, they are basically buying a feeling, rather than a gif. There’s this whole new culture of owning digitally native assets. Others are just trying to make quick money.

Other Examples

Nyan cat gif is only one of the many NFTs that are being auctioned for 6 digit figures. Jack Dorsey’s first-ever tweet, Sports Collectibles: NBA shots, William Shatner’s personal memorabilia, and many other NFTs have all proved to be titled as most expensive NFTs.

Minting your own NFT (without OpenSea)

Now, let’s get to the technical nitty-gritty details of minting a NFT.

Step 1: Setting up the local Environment

First, we’re going to write a smart contract. That contract will have all the logic around our NFTs. And then we will deploy our smart contract to the blockchain.

We’re going to be using Hardhat, which is a tool that lets us quickly compile smart contracts and test them locally. First, you’ll need to get node/npm.

Next, let’s head to the terminal. Go ahead and cd to the directory you want to work in. Once you’re there, run these commands:

npm init -ynpm install — save-dev hardhatnpx hardhat

Create a basic sample project. Say yes to everything. Install hardhat-waffle and hardhat-ethers.

We also want to install OpenZeppelin, which is a library that’s used to develop secure smart contracts.

npm install @openzeppelin/contractsnpx hardhat run scripts/sample-script.js

Our local environment is now set up and we also ran/deployed a smart contract to a local blockchain. Basically what’s happening here step-by-step is:

  1. Hardhat helps compile our smart contract from solidity to bytecode.
  2. Hardhat will create a “local blockchain” on the computer. It’s a test version of Ethereum running on the computer to help us quickly test our NFT and smart contract.
  3. Hardhat will then “deploy” our compiled contract to the local blockchain. The address at the end of the message popped in the terminal is our deployed contract, on our test version of Ethereum.

If you’re curious, check out Greeter.sol which is the smart contract, and sample-script.js which actually runs the contract.

Step 2: Writing our starter contract.

Go ahead and delete the file sample-test.js under test, sample-script.js under scripts, and Greeter.sol under contracts. We’ll write these ourselves!

Open the project up in VSCode create a file named MyNFT.sol under the contracts directory.

Note: Downloading the Solidity extension for VSCode is recommended. It gives nice syntax highlighting.

Copy-paste the following code to create a basic contract

// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.0;import “hardhat/console.sol”;contract MyNFT {constructor() {console.log(“This is my NFT contract!”);}}

Basically, we specify that we want to use version 0.8.0 of the Solidity compiler. Be sure your compiler is set to 0.8.0 in hardhat.config.js. The third line of our code allows us to do some console logs in our contract. It allows for easier debugging of smart contracts. The last few lines of our code make up our smart contract, and it kinda looks like a class. On initializing this contract for the first time, that constructor will run and print out “This is my NFT contract!”.

Step 3: Running our smart contract.

Congrats, we’ve got a smart contract! Now, we need to-

  1. Compile it.
  2. Deploy it to our local blockchain.
  3. Once it’s there, it’ll console.log a message so that we know it worked.

Our custom script will handle those 3 steps for us.

Go into the scripts directory and make a file named run.js. Copy-paste the following code inside it.

const main = async () => {
const nftContractFactory = await hre.ethers.getContractFactory('MyNFT');
const nftContract = await nftContractFactory.deploy();
await nftContract.deployed();
console.log("Contract deployed to:", nftContract.address);
};
const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.log(error);
process.exit(1);
}
};
runMain();

Understanding code line by line here,

const nftContractFactory = await hre.ethers.getContractFactory("MyNFT");

This will compile our contract and generate the necessary files we need to work with our contract under the artifacts directory.

const nftContract = await nftContractFactory.deploy();

This instructs Hardhat to create a local Ethereum network, just to test this contract. And after the script completes it’ll destroy that local network.

await nftContract.deployed();

This will make us wait until our contract is officially mined and deployed to our local blockchain. Hardhat actually creates fake “miners” on your machine to try its best to imitate the actual blockchain.

Our constructor runs when we actually are fully deployed!

console.log("Contract deployed to:", nftContract.address);

Once our contract is finally deployed, nftContract.address will basically give us the address of the deployed contract. This address will help us find our contract on the blockchain.

Now, we actually get to run it! Open up your terminal and write following code:

npx hardhat run scripts/run.js

You should see your console.log run from within the contract and the contract address print out!

Step 4: Locally Minting our NFTs.

Now that we got the basics down, we’re ready to mint some NFTs! Update your MyNFT.sol to the following code:

pragma solidity ^0.8.0;// import some OpenZeppelin Contracts.
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "hardhat/console.sol";
// inherit the contract we imported. So that we'll have access
// to the inherited contract's methods.
contract MyNFT is ERC721URIStorage {
// this helps us keep track of tokenIds.
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// We need to pass the name of our NFTs token and its symbol.
constructor() ERC721 ("SquareNFT", "SQUARE") {
console.log("This is my NFT contract!");
}
// A function our user will hit to get their NFT.
function makeAnNFT() public {
// Get the current tokenId, this starts at 0.
uint256 newItemId = _tokenIds.current();
// Actually mint the NFT to the sender using msg.sender.
_safeMint(msg.sender, newItemId);
// Set the NFTs data.
_setTokenURI(newItemId, "hello");
// Increment the counter for when the next NFT is minted.
_tokenIds.increment();
}
}

First we “inherit” an OpenZeppelin contract using is ERC721URIStorage. Basically, it means we can call other contracts from ours. It's almost like importing functions for us to use!

ERC721 is the NFT standard. OpenZeppelin has implemented the NFT standard for us and then lets us write our own logic on top of it to customize it. So we don’t need to write our NFT contract from complete scratch!

Let’s take it step-by-step through the makeAnNFT function.

uint256 newItemId = _tokenIds.current();

_tokenIds is a number, which is used to keep track of the NFTs unique identifier. When we first call makeAnEpicNFT, newItemId it is automatically initialized to 0. When we run it again, it increments to 1, and so on!

_tokenIds is state variable hence whenever we change it, the value is stored on the contract directly.

_safeMint(msg.sender, newItemId);

_safeMint(msg.sender, newItemId) basically instructs to mint the NFT with id newItemId to the user with address msg.sender. Here, msg.sender is a variable that easily gives us access to the public address of the person calling the contract. This is a super-secure way to get the user’s public address because by using msg.sender you can't "fake" someone else's public address unless you had their wallet credentials and called the contract on their behalf!

Also, one can not call a contract anonymously, they need to have their wallet credentials connected which is almost like “signing in” and being authenticated.

_setTokenURI(newItemId, "hello");

We then do, _setTokenURI(newItemId, "hello") which will set the NFTs unique identifier along with the data associated with that unique identifier. Here, we're setting it as "hello" for now.

_tokenIds.increment();

After the NFT is minted, we increment tokenIds using _tokenIds.increment(). This makes sure that next time an NFT is minted, it'll have a different tokenIds identifier.

The tokenURI is where the actual NFT data lives. And it usually links to a JSON file called the metadata that looks something like this:

{
"name": "Christmas Tree Portal",
"description": "The best way I could put up a Christmas tree with a Fox in the house",
"image": "https://i.imgur.com/v7U019j.png"
}

This can be customized, though, almost all NFTs have a name, description, and a link to something like a video, image, etc. Be careful about the structure though, because if it does not match the OpenSea Requirements your NFT will appear broken on the website.

We can copy-paste the Christmas Tree Portal JSON metadata above into this website, which is an easy place for people to host JSON data. Once you click "Save" you'll get a link to the JSON file. (For example, mines is https://jsonkeeper.com/b/CHWV).

Now, lets head to our smart contract and change some lines. We’ll replace the URI in _setTokenURI(newItemId, “hello”) with the link to our JSON file. Like this : _setTokenURI(newItemId, “INSERT_YOUR_JSON_URL_HERE”);

Under that line, we can also add a console.log to help us see when the NFT is minted.

console.log("An NFT w/ ID %s has been minted", newItemId);

Now, to finally locally mint our NFT, we’ll need to change our run.js file to actually call our makeAnNFT() function. This is what the final run.js code looks like:

const main = async () => {
const nftContractFactory = await hre.ethers.getContractFactory('MyNFT');
const nftContract = await nftContractFactory.deploy();
await nftContract.deployed();
console.log("Contract deployed to:", nftContract.address);

// Call the function.
let txn = await nftContract.makeAnNFT()
// Wait for it to be mined.
await txn.wait()

};

const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.log(error);
process.exit(1);
}
};

runMain();

Now run the following in terminal:

npx hardhat run scripts/run.js 

We’ll see a message saying This is my NFT contract!, then another message with the address of the deployed contract, and another message saying a NFT with 0 ID has been minted, in our terminal.

Boom! We just locally minted our very first NFT.

Step 5: Deploying our NFTs.

We will now deploy our NFT to a testnet so that we’ll actually be able to to view our NFT online.

A transaction is an action that changes the blockchain. Sending someone ETH, doing something that updates a variable in our contract, minting an NFT, deploying a smart contract are all considered transactions.

As the blockchain has no owner, but it’s just a bunch of computers around the world run by miners that have a copy of the blockchain when we deploy our contract, we need to inform all those miners about our new smart contract, and ask them to add it to the blockchain.

Alchemy helps us here by essentially broadcasting our contract creation transaction so that it can be picked up by miners. Once the transaction is mined, it is then broadcasted to the blockchain as a legit transaction. From there, everyone updates their copy of the blockchain.

So, now we need make an account with Alchemy here.

We are going to mint the NFT on a testnet (so that we’re not dealing with real money). Testnets are run by actual miners and mimic real-world scenarios, but uses fake $.

We have to ask the network for some fake ETH. This fake ETH will only work on this specific testnet, Rinkeby for this case. You can grab some fake Ethereum for Rinkeby through a faucet like MyCrypto. There, you’ll need to connect your wallet, make an account, and then click that same link again to request funds.

We’ll now separate our deploy script from the run.js script. We want to keep run.js separate because there a lot of changes in that file. Create a file named deploy.js under the scripts folder and copy-paste all of run.js into deploy.js. It's going to be exactly the same code right now.

Find hardhat.config.js file in the root directory of your smart contract project, and copy-paste the following code:

require('@nomiclabs/hardhat-waffle');

module.exports = {
solidity: '0.8.0',
networks: {
rinkeby: {
url: 'YOUR_ALCHEMY_API_URL',
accounts: ['YOUR_PRIVATE_RINKEBY_ACCOUNT_KEY'],
},
},
};

Grab your API URL from the Alchemy dashboard and your private rinkeby key from metamask and paste those in.

Now open your .gitignore file and add following line:

hardhat.config.js

Now we’re to deploy. Run the following command from the root directory of epic-nfts.

npx hardhat run scripts/deploy.js --network rinkeby

It’ll take about 30–40 sec to mint, deploy, transaction to mined + picked up by miners. After the NFT is deployed we will see a console.log in the terminal.

Step 6: View it on OpenSea.

Now head to testnets.opensea.io. Search for your contract address which is the address we deployed to. You can find it in your terminal. Don’t click enter, click the collection itself when it comes up in the search. Click on the collection name you used, and boom! you can see they NFTs we just minted.

Note: If you can not seem to find your NFTs on OpenSea, use Rarible.

About me

I am Priyal Saxena, a second-year B.Tech student at IIIT Allahabad, and a
member of
GeekHaven WebD wing.

You can contact me through Github and Linkedin.

--

--