NFT Minting vs Lazy Minting. Minting explained.

Szymon Kolber
Rarible Protocol
Published in
10 min readNov 29, 2021

You’ve made your first NFT. You’ve carefully drafted every pixel in a 64x64 image, and now it’s ready 🤩! You then open Rarible and mint it, making it officially available to the world. But do you know what happens on the background? Keep reading to find out what’s the secret ingredient and how you can recreate it in your code.

Minting

Minting an NFT is how your digital art becomes a part of the blockchain–a public ledger that is unchangeable and tamper-proof. Similar to the way that metal coins are minted and brought into circulation, NFTs are tokens that get “minted” once they are created. Your digital artwork is represented as an NFT, and can be purchased and traded in the market, as well as digitally tracked as it is resold in the future. (source)

This definition is somehow satisfying, but if you’re a technical guy like me, it’s not really enough. Let’s dive into it.

OpenZeppelin

If you’ve ever touched smart contracts and solidity, there’s a really big chance that you know OpenZeppelin already. OpenZeppelin allows us to develop a really secure, highly tested, production ready smart contract blueprint. Smart contracts are always a risky business, because once it is deployed, no changes are allowed. You really have to test it in and out. That’s what OpenZeppelin does (and a few other things). Here you can find their GitHub if you’re curious.

GitHub — OpenZeppelin/openzeppelin-contracts: OpenZeppelin Contracts is a library for secure smart…

A library for secure smart contract development. Build on a solid foundation of community-vetted code. 🧙 Not sure how… GitHub.com

The best way to learn is to learn from the pros, so let’s take a look at how they’ve implemented the mint function.

Mint function | OpenZeppelin

I’m sorry to disappoint all of you who thought that there was some sort of magic involved here 😂. It is actually pretty simple! We first check if we’re not minting to 0x0 address, because the 0x0 address is the one to which no one has a private key for. Fun fact: if we want to burn a token, we just transfer it to address 0x0, since nobody will be able to retrieve it. After that, we check if tokenId isn’t already used. BeforeTokenTransfer is just a hook, and it doesn’t do anything special (if you want to read the docs, check out their GitHub). The next two lines are where the minting happens.

Minting in its essence…

Two lines, from which one could basically be omitted. In solidity, instead of an array, we have a mapping function which basically behaves like an array. Balances and owners are respectively uint256 & address arrays.

_owners & _balances initialization

The act of minting is similar to assigning a value of minter address to the tokenId property in the owners’ array (we can also think of it as a dictionary).

If you think that it’s all too easy, don’t underestimate it. Remember that it’s all on the blockchain, so even if it’s that simple it’s still super secure, fast, etc. Thanks to its security, we don’t need any additional logic.

Minting drawbacks

So far, so good. Now we know how the minting process works, and we know that it’s secure. What are the drawbacks? Since we’re making a write operation on the blockchain, unfortunately it will have a cost, in Ether specifically. At the time of writing, to mint one NFT, you’d have to pay around $20. It’s not a small amount, considering that you might want to mint multiple NFTs.

Lazy Minting

What if I told you that you can create an NFT, and list it for sale FOR FREE? You heard it right. Free minting… for you at least 😁. Buyers will have to cover the cost when they buy it. But hey, it’s cutting the risk down to almost 0. Interested? I will now uncover how it works.

Okay, so in minting, you basically have a 3-step process:

  1. You need to have a smart contract which is capable of minting (marketplaces such as Rarible or OpenSea offers them, they have their own smart contracts)
  2. You need to pay a gas fee, in order to mint your NFT (gas costs $)
  3. Somebody can then buy your NFT

In lazy minting, it does look a little different:

  1. You need to have an even smarter contract which is capable of lazy-minting (e.g. Rarible)
  2. You create a signature for the NFT, signed with your private key.
  3. Someone then buys it and pays the minting fee, as well as the listed price.

Isn’t it amazing? We’ve reduce risk posed by an upfront investment. Everything’s looks good, until we encounter…

Vulnerabilities

If we create a signature without any context, on whichever chain it should be created in the moment of purchase, someone would be able to market the NFT that was lazy minted on Ropsten, as the one lazy minted on Mainnet. Not nice. In order to prevent that, we need a little more information. But hey, we’re in the crypto space, and there are lots of smart people here 🧠. To address this problem, the Ethereum community came up with EIP712.

Soldiers! To the code!

Now that we know how minting looks under the hood, let’s use Rarible to create a lazy minting form. In this article we’ll focus strictly on lazy minting, but if you’re interested in the overall app setup, with Ethereum context creation, I strongly encourage you to take a look into my last article, where I’ve covered it. In today’s article, we’re going to build an app similar to the one you see below.

NFT Creation Form

But first things first. Let’s take a look at the app HTML, which we render.

JSX

We strictly divide our app into a few elegantly packed components. We have NFTDetailsForm, which is responsible for all inputs, and we have MetaMaskButton which handles the web3 stuff for us. Metamask button creation is also covered in my last article.

Moving forward, we’ll take a closer look at NFTDetailsForm, because that’s where we actually create an NFT.

NFTDetailsForm component creation

Imports and form schema validator

The fact that we’re writing crypto, doesn’t mean we don’t want our Next JS app to look pretty ✨✨. When it comes to forms, I like them sharp and clean. That’s why we use the react-hook-form library along with yupResolvers. It allows us to create auto error checking inputs in accordance to the constraints we set. As you can see, we need 5 inputs: price, title, description, royalties and, of course, the file we want to transform into an NFT (although it’s not really necessary, you can create an NFT without an image file).

NFTDetailsForm Initialization

To properly initialize react-hook-form, we destructure the useForm hook and formState. It will remove any need for validations. I know it looks a little demanding at the beginning, but trust me, it’s totally worth it! Breaking it down even further, on NFTDetailsForm, all the text inputs are created as follows:

Input creation with react-hook-form

When we use react-hook-form instead of creating a useState hook for each input, we are just registering it (remember: register is a special function which we get from useForm hook) and boom, all the validation is here already! 🔥

File Input

With a file input (the one where we add a file) the situation is slightly different. We create an onChange event listener and assign e.target.files to that when changed. Since the files we selected are in the form of an array, we set it to the first one. The reason for the check is that, when we cancel the form (i.e. you press cancel after clicking “Add File”), we set it to null.

Right now we have all the frontend files validated, which is a really huge bonus, since we don’t need any backend server. What’s left is the form data values submission.

Sending data back to create page

Create Page

After we gather all the data we need, we need to actually create an NFT. The Process of Lazy Minting on Rarible is as follows:

  1. Upload data to IPFS, which is like a decentralized database.
  2. Generate tokenId. Since a lazy minted NFT isn’t actually, well… minted yet, in order to see it we need to store it somewhere. In this case, Rarible is doing that, that’s why we need to get a tokenId from them.
  3. Creating lazy mint form. In this step we create a lazy mint form including royalties, creator, token type (ERC721 | ERC1155) etc., and we sign it using metamask and our private key.
  4. Post lazy mint form to Rarible API.

That’s all, when it comes to theory. Let’s get down to business 🦾

Step 1. Upload File To IPFS

The data argument comes from inputs which we’ve created earlier. First, we have to transform the file data into an array buffer. We do a safety check before moving on, check if there is a wallet connected and if the file exists. Now it’s time for programmers to think creatively! I’ve noticed that, when we insert a normal IPFS Image hash (on IPFS all data are stored under some hash), it doesn’t show properly on Rarible, because IPFS actually redirects you to that image. That’s why, before I create a full object hash, I extract the correct Image URL, by making a usual get request. If you’re not familiar with how NFTs are stored on IPFS, this is the process:

  1. Upload image to IPFS -> get back its hash
  2. Upload object to IPFS where image property is pointing to it’s hash

We do it this way, because storing full images in bytes on the blockchain would be crazy expensive! 💸

After uploading a full object and getting its hash, we’re done with IPFS.

Step 2. Generate Token ID

We’re making a request to Rarible API, passing the contract address and minter address. Minter address is the currently connected and active wallet, and contract address is the address from the chain that we want to use (e.g. ROPSTEN, MAINNET, RINKEBY).

Step 3. Creating Lazy Mint

We’re creating it in a different file to keep our files separate. You see, there are two steps here:

1. We create a lazy mint form

It’s basically json with all of the data we need to create an NFT: we have a token type, which can be either ERC721 or ERC1155, we have a contract address, we have a tokenId, we have an IPFS hash which we’ve created earlier, and we have the creators’ array, which allows us to split NFT income into a few different artists (in case more than one is involved). 10000 represents 100%, so if you want to make it 50/50, it would look like this:

And royalties, which is also an array, allows the creator to receive a percentage-based value out of every sale of this NFT. A pretty nice option for artists! 🎨

2. We sign the created form, along with EIP712 usage, to avoid the vulnerabilities we talked about earlier

Abstracted functions
Inner logic

In order to create type data, and sign this data, we have to create a JSON object for ERC721Types & DOMAIN_TYPE. As you can see, it’s strictly for solidity purposes, because it’s basically a variable name and a variable type (solidity is a typed language). Afterwards, we create a JSON type to which we insert all the values we’ve collected. The last step is signing the data. We use metamask for that. We can do it with the provider.send function. We get a signature out of it, and we’re ready for the last step.

4. Post lazy mint form to Rarible API.

POSTing lazy mint form to Rarible

After we’ve created the NFT signature with metamask, signed it and created a lazy mint form, now it’s time to POST it to Rarible. We do that by using the Axios library, where we just POST the form to the appropriate endpoint. That’s it! If we get a response with 200 status, we’ve successfully lazy minted an NFT!

Congratulations!

Summing it up

In today’s article we went through what minting is overall, what are the differences between minting and lazy minting and how we can perform lazy minting on Rarible.

Here you can find the GitHub project for this (it’s on rarible branch):

https://github.com/kolberszymon/jawz-art/tree/rarible

Here you can find live examples:

https://cocky-hopper-ee594a.netlify.app/create

If you have any further questions, we are always ready to help you! Join our discord, and we will provide the support you need!

Rarible DAO discord: https://discord.com/invite/zqsZsEWBbN

Consider subscribing to our weekly newsletter: https://www.getrevue.co/profile/raribleprotocol

My personal contact information:

Discord: Szymon From Poland#6093

Github: kolberszymon

Linkedin: koblerszymon

Happy coding, amigos!

--

--

Szymon Kolber
Rarible Protocol

Blockchain, crypto, full-stack. Make the world decentralised again 🌎