I built a web3 dapp that can mint an unlimited quantity of NFTs. Learn how to build decentralized web apps with JavaScript using tools like Hardhat, Solidity, OpenZeppelin, React, Alchemy, and more https://fireship.io/lessons/web3-solidity-hardhat-react-tutorial/

🤪 Invest in my NFT Collection https://opensea.io/collection/fireguys

#web3 #nft #tutorial

🔗 Resources

- Source Code https://fireship.io/lessons/web3-solidity-hardhat-react-tutorial/
- Pinata https://pinata.cloud/
- Hardhat https://hardhat.org/
- OpenZeppelin Wizard https://docs.openzeppelin.com/contracts/4.x/wizard
- Alchemy https://www.alchemy.com/
- Web3 Criticism https://moxie.org/2022/01/07/web3-first-impressions.html
- No-Code NFT tutorial by @codeSTACKr https://youtu.be/AaCgydeMu64

📚 Chapters

00:00 Web3 Introduction
01:11 What is an NFT?
02:27 Why Web3  is Dumb
03:00 1. How to Generate Random Art
06:14 2. Upload to IPFS with Pinata
07:33 3. Hardhat Toolchain Setup
08:51 4. Code an ERC-721 Smart Contract 
13:30 5. Testing Smart Contracts with Waffle
15:22 6. Web3 Frontend with Ethers.js and React
21:20 7. Deploy to a Testnet with Alchemy

🔥 Get More Content - Upgrade to PRO

Upgrade to Fireship PRO at https://fireship.io/pro
Use code lORhwXd2 for 25% off your first payment. 

🎨 My Editor Settings

- Atom One Dark 
- vscode-icons
- Fira Code Font

🔖 Topics Covered

- step-by-step web3 project
- full web3 tutorial
- NFTs explained
- How to use Hardhat and Solidity
- How to use ethers.js with react
- What is ERC-721
- How to deploy a web3 app
- Web3 with Ethereum and Polygon
2024-02-04T13:48:13.069Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
15de47a6-65a6-498b-9065-d0c5f146d3e0
9d7864acf526eaae4faf890b72896a065fdf515b20833aeb717635c5ab013297
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
In today's video, we'll build a complete web 3 application step by step from scratch and in the process, we'll talk about the good and bad aspects of developing decentralized web apps on the blockchain.
You may have seen the headlines of kids making 1,000,000 of dollars overnight by selling digital art in the form of NFTs.
If you're like me and not already an NFT millionaire.
You likely have some FOMO about this whole trend.
You could point out how NFTs are dumb, pointless, and bad for the environment, or you could try to get in on the trend yourself, and that's exactly what we'll do in this video.
I'll show you how I created a collection of 20,000 unique graphics with some crappy artwork I drew by hand in a few minutes.
We'll then take that artwork and upload it to the interplanetary file system.
At which point, we can write a smart contract with Solidity and OpenZeppelin that will mint a new NFT whenever somebody transfers Ethereum to the smart contract.
And finally, we'll use ethers.
Js with React to build a web 3 application that provides a front end interface where people can actually interact of a smart contract.
By the end of this tutorial, you'll understand the complete process of going from 0 to a web 3 point o NFT application.
This tutorial is longer than most on this channel and it's broken down into 7 phases.
If you're new here, like and subscribe and follow along with the full tutorial on Fireship biome.
And if you wanna see more web 3 content, let me know in the comments.
Before we get started, let's first answer the question of what is an NFT collection.
A nonfudgeable token is a unique digital asset.
Usually, it represents a piece of artwork like an image, but it can also represent things like domain names and physical items in the real world, but you'll often see NFTs packaged in a collection like CryptoPunks, Bored Ape Yacht Club, and doodles just to name a few.
These graphics are created with a few base layers, like hair, eyes, clothing, and so on.
The layers are then combined together randomly to create a bunch of unique graphics.
What's interesting though is that the various traits and attributes have different levels of rarity.
When a graphic is generated, it's less likely to have one of the rare traits.
This is actually really fun because you can think of a smart contract like a vending machine in the cloud.
When an NFT collection is first offered, you can send crypto to that wallet address.
It will mint a one of a in token and transfer it to your wallet.
If you're lucky, you'll get something with a really rare trait.
It's not much different than opening up a pack of Pokemon cards.
Most of the cards are very common, but there is a small chance you'll get something that's very rare and valuable.
Now after you purchase an NFT, there's a secondary market where you can resell it to someone else on a site like OpenSea.
Many people invest in NFTs hoping to flip them for a higher value later on.
If you're the original creator, you can also configure your smart on track to receive royalty payments whenever the NFT changes hands in the future.
That's pretty cool, but there are a lot of bad things I could say about web 3 as well.
The guy who created signal, an encrypted messaging app, created an NFT that actually changes its appearance based on where you view it.
On OpenSea, it looks really cool, but in your wallet, but it looks like a piece of poop.
Because the NFT image is hosted off chain, he just used a web server to display a different image based on the user agent that was requesting the image.
Everybody talks about web 3 being decentralized and trustless, but the reality is that much of it works thanks to centralized APIs.
Read his full blog post to learn more.
At the end of the day, we don't really care about that we're just here to have fun, get some exercise, and make a ton of money.
Now we're ready to kick off phase 1 of this project, where we create the layers or graphics that we'll use for the NFT collection.
I'm not much of an artist and everything I draw tends to look really creepy.
Not much I can do about that, so I'm just gonna own it.
Believe it or not, creating NFT artwork is an art form.
I I find it really satisfying because you can take a few basic images and use them to create thousands of different unique combinations.
For my NFT collection, I actually used a pen and paper to draw everything by hand.
I then digitized it and brought each individual layer into Figma.
As you can see here, I have different categories for the various traits, like hair, eyes, nose, mouth, beard, and so on.
From there, I created a little script in Node.
Js that randomly combines these layers together.
You can find the source code on GitHub, but there are many existing tools out there that can help you generate in NFT collection without needing to write any code.
If you're looking for a tutorial that doesn't require any code, this is not the video for you.
If your goal is to just create a bunch of images and sell them as NFTs.
I'd recommend checking out this recent tutorial from Code Stacker for a more simplified approach.
I'm not gonna go through every single line of code here, but I just wanna walk you through the process I used to create all my NFT graphics from scratch.
1st, you can see I have a directory called layers that contains a bunch of files like eyes 0, eyes 1, eyes 2, and so on.
This directory contains all the possible layers that we would use in an image.
From there, I have a file named index.js.
Inside of I have an SVG template.
I'm using scalable vector graphics here, but I've seen other implementations that just use PNGs.
Now each layer in our layers directory as an SVG, so all we have to do is grab the main content from that file and replace each one of these comments with the corresponding traffic like head, hair, eyes, nose, mouth, and beard.
In order to do that, I'm using Node.
Js to read one of our layer files and then use some regex to grab of the content inside the SVG tags.
Then I have a function called create image that will generate a bunch of random numbers and combine them together into an array.
I've made this a recursive function that checks to see if that combination has already been taken, in which case it will try running the randomization again.
If it is a valid combination, We'll go ahead and replace all the comments in the SVG template with the actual layers from our layers directory.
Now, in addition to creating in image.
We're also going to create a JSON file with some metadata about it.
This metadata is really important because it contains the name of the file as well as a link to its actual image on the interplanetary file system.
That represents a unique file upload that cannot be modified.
In addition, if the metadata contains attributes of the different traits in the image.
Generally, when making an NFT collection, each trait has a different level of rarity.
The more rare rates an NFT has, the more valuable it tends to be, thanks to the magic of artificial scarcity.
Now, I'll go ahead and write these files to my file system and as an added touch, I'm also burning the SVG to a PNG file as well.
I'm using a node package called Sharp to make that possible.
And finally, to run the script, I just have a while loop that calls the create image function for the number of images that I want to create.
And now when we run the script with node, we get this out directory with a bunch of files that contain both the raw images and JSON for each individual graphic.
That takes care of phase 1.
We can now generate 1,000 or even millions of individual graphics by simply adding more layers to the layers directory, but keep in mind that my implementation is very crude.
There's a lot of optimizations we could make or better yet, we could have used a pre built solution out there to get this job done much faster.
Now the next thing we need to think about is how to get these files on the Internet and connect them to a non fungible token.
The actual image data and JSON for the NFT t is too big to be efficiently stored on the blockchain.
So instead, we store it off chain on the interplanetary file system, which is a decentralized file system in the cloud very similar to BitTorrent.
One very important concern that IPFS handles is content addressability.
Anytime you upload a file, it creates a unique identifier for at upload, and that allows us to verify the authenticity of any graphics associated to an NFT.
Once a file has been uploaded, you can't modify it without changing its content identifier.
That means when minting an NFT, the only thing we actually need to store is a link to that file's content identifier.
Now the question becomes, How do we take our raw files and upload them to IPFS?
There are many ways to go about it, but an easy free solution that I've been using is of it.
It's very similar to something like Dropbox where you simply click a button to upload and choose a file from your file system, and you can even host an entire static website from Yotta.
It also has a node SDK to upload programmatically, but we're not going to worry about it in this video.
I'm just going to upload a few of our images here, and you'll notice when I that it creates a content identifier.
Conveniently, we can upload an entire directory all at once.
I'm gonna go ahead and upload a few of the graphics that I just generated.
For this tutorial, You can upload any random file.
It doesn't really matter.
And now, we're ready to build a full stack web 3 application using Solidity, Hardhat, and React.
The first thing I'm doing here is generating a new React app using Vite.
It really doesn't matter which front end framework you use here, but the vast majority of web 3 demos out there use React.
That Gives us a front end application.
Now we're going to run npx hardhat, which will add a variety of tools to our project to add a blockchain back end.
You'll notice it generates a directory for contracts, which contains files written in Solidity, which contains the smart contract code that will interact with the blockchain.
It also creates a directory named scripts that contains the code to deploy those contracts to the blockchain.
Now there's a couple of configuration things we'll need to do here.
In the hardhat config file, We'll update the paths option to create any artifacts in the source directory for the React application.
That allows React to access information about the smart contracts.
When you compile of smart contract.
It creates what's known as an application binary interface, which is basically a middleman that allows your front end JavaScript code to communicate with the smart contract compiled to machine code and all that information lives in the our contract compiled to machine code, and all that information lives in the artifacts directory.
From there, we're going to install a bunch of dependencies with npm, like Waffle for automated testing and ethers to interact with smart contracts in the browser and also a tool called OpenZeppelin, which provides templates for quickly building industry standard smart contracts.
At this point, I want to focus on writing a smart contract.
Its purpose is to accept a payment from a user, then mint a non fungible token and transfer it to that user's wallet.
It's important to point out that the code in the smart contract will not actually generate random rates for the NFT images.
It's actually extremely difficult to handle randomness in a smart contract.
Most NFT collections don't deal with it at all, and instead, they just generate all the images at once, upload them to IPFS, and then mint them after the fact.
At which point, they get sold on a secondary market, or you might code up another contract to create your own secondary market.
Now it is possible to implement randomness in a smart contract, and if that's what you wanna do, I would highly recommend looking into something like Chainlink.
We're going to take the easy approach in this video where the smart contract takes the IPFS URL for the metadata along with some Ethereum and mints a new token from it.
To handle that requirement, we'll need to learn a new programming language called Solidity.
In the contract x directory.
Let's go ahead and create a file ending in dot s o l.
Now, we could implement a smart contract from scratch, but that would be a pretty big undertaking on its own.
Luckily, there's a tool called in Zeppelin, and it has a wizard that we can use to automatically generate reliable code for us.
The Ethereum ecosystem already has a variety of standard interfaces to handle requirements commonly implemented in smart contracts.
Like ERC 20 is what you would use to create a fungible token, like if you wanted to create your own coin on the Ethereum network.
But to create a non fungible token, we want to use the ERC 721 standard.
Before we customize it, you'll notice that there is API documentation with a handful of methods built into the base contract, like balance of to check the owner's balance or owner of to to see who owns a token, as well as methods to transfer tokens from one user to another.
Now let's go over to the open Zeppelin wizard to customize our own ERC 721 contract.
Most importantly, we need to be able to mint our own tokens.
If we check the box for mint, it adds a new method to the contract that allows a privileged account to mint or create a new token.
Let's also auto increment IDs and then check the box for URI storage.
URI storage allows us to associate and upload on IPFS when this token is minted.
Remember, that's the reference to the metadata that we uploaded on pinata earlier.
We'll also wanna use a base URI here that points to of PFS to ensure that the URI is properly formatted.
That gives us a base contract to work with and you'll notice a button here to open up in the Remix IDE.
I'm not going to do it in this video, but Remix is a browser based IDE that makes it really easy to compile and test your smart on tracks.
What we're going to do is copy and paste this code and bring it directly into the solidity file that we created.
We could use this contract as is, but we want to extend it with some additional code that allows anybody to mint a token as long as they transfer the appropriate amount of Ethereum along with it.
Currently, you'll notice a safe mint method that allows the owner of the contract to mint a new token.
What we wanna do is create a new function called pay to mint that takes a recipient and metadata a content ID, then mint a new token with that data.
Now in order to implement this function, we'll wanna make sure that the same URI can't be minted twice.
And to validate that, I'm creating a mapping of Strings to integers to keep track of the existing URIs that have been minted.
We might also want to check if an existing URI is already owned, so I'm creating another function called is content owned that takes a URI as its argument and returns true if that URI already exists in the happening.
Now, we have everything in place to implement the paydement function.
You'll notice that it's marked as a payable function, which means that somebody can transfer money into the contract.
Tracked.
Now, we can use the require keyword to run some validation.
And, keep in mind that this is not a production ready contract.
My goal is just to show you how some of the basic mechanics in Solidity work.
With require, we first pass a condition.
In this case, we want to know if the URI has already been minted.
If it has not been minted, the function will continue executing.
Otherwise, it will throw an error saying the NFT has already been minted.
The next thing we wanna validate is that the user has paid enough ether.
There's a global variable of message, and its value property contains the amount of ether being sent into the contract.
We can make sure that the minimum value is greater than 0.05.
Otherwise, we'll throw an error saying the user needs to pay up.
From there, we'll want to create a new item ID.
With the counter implemented by OpenZeppelin, it will increment each new token by 1.
So it starts at 0 then goes to 1, 2, 3, and so on.
After incrementing the counter, we'll update our mapping of the existing URI's, then we call the built in mint method with the recipient's wallet address, and finally, we set the token URI on that ID.
That's how someone can pay to mint a new token.
And as one final touch, I'm also going to add A function here to get the current count, so we can know exactly how many tokens have been minted so far.
And that completes the Solidity code for our back end.
At this point, you may want to just jump straight into building a web 3 application, but I would highly recommend that you do some testing first.
Hardhat already has a sample test ready to go.
And the code you write in a test will be very similar, if not identical, to the code that you write in your front end React application.
It's much easier to detect bugs and issues in a test than it is in a front end application with all the UI stuff going on.
If you've never done test driven development before, I have an entire video on it.
In the test, we'll first use ethers to get our contract and then deploy it.
Once deployed, we'll then need a wallet address with some ether in it for testing.
Luckily, we can use a fake wallet with 10,000 ether in it already by going to the terminal and running npx hardhat node.
This creates a mock network on localhost and provides us with a bunch of fake accounts to used for testing.
Copy one of the public keys and use it in your test.
At this point, we can start calling the methods on the deployed smart contract.
First, I'll create a variable called balance that checks the current balance of the recipient's wallet address.
Balance of is a method built into the ERC 721 spec.
Now Now currently, the user hasn't purchased any NFTs, so we expect the balance to equal 0.
Now from there, we'll create another variable called newly minted token that calls the payment method that we defined on the smart contract.
It takes the recipient and metadata URI as arguments, and then we can also define the message value as 0.05 ether.
For fun, let's go ahead and set the ether value to 0.01.
Now go to the terminal and run npx hardhat test.
What you'll notice is that we get a failing test, and you'll see the error message here that the user needs to pay up.
Let's go ahead and fix that, and then we'll wait for the newly minted token to be mined by calling the wait method on it.
From there, we can query the balance again, and this time we expect it to equal 1.
In addition, we can test our is content owned method by making sure that that metadata URI is equal to true.
And there are all kinds of other things we could test here, but you get the general idea.
If you test all your smart contract logic first, It'll make the front end development much easier.
Now, we're ready to move on to the next phase, where we build a web 3 application that interacts with a smart contract from a website.
Let's 1st, go into the sample script provided by HardHat.
This script is used to compile the contract, which will populate the artifacts directory with all the information we need to interact with like the ABI I talked about earlier.
We'll want to update the default values with the name of the custom contract that we created.
You'll want to first make sure you have opened running the npx hardhat node command.
This should always be running in the background.
From there, we can open up a separate terminal and run npx hard at compile.
This runs the solidity compiler to convert your code into binary.
Once that's done, we can run npx hard hat run scripts, sample script, and specify the network as local host.
That will take the contract and deploy it to the actual network.
And now we have a smart contract running on our local Sheen.
Now when it comes to web 3, the way end users interact with a smart contract is typically with a browser plugin like Metamask.
For development, You'll want to set up MetaMask with one of the testing addresses provided by Hardhat.
If you don't have it yet, install MetaMask and then go to the local host network and import a new account.
It will ask you for a private key, which you can simply copy from the terminal output.
And now we're ready to start writing some React code.
In order for a user to mint an NFT on the website.
They'll need to have MetaMask installed.
We'll need to check that at runtime and have 2 different screens based on whether or not installed.
I'm creating 2 different components here, one called home and one called install.
And in the install component, we'll simply have a link to the MetaMask plug in.
Now in the main app component, we can check to see if the user has a plug in installed by checking the window ethereum object.
A plug in like Metamask will make this object available automatically when it's installed.
Now the next thing I'll do is create a new component called wallet balance.
And inside of it, We can start interacting with ethers.
Js, which is a JavaScript library that makes it easy to communicate between the smart contract and in end user's wallet.
In this component, what we wanna do is get the end user's current balance.
We'll first set up state with the use state hook and then define a function called GitBalance.
We can get the connected account on the window Ethereum object and then we use ethers.
Js to create a new web 3 provider.
The provider provides all kinds of or methods for interacting with the Blockchain.
One of which is getBalance, which then takes the account as its argument.
That will return the wallet balance of the connected account, which should be 10,000 ether, but it's in a big number format.
So ethers also provides a utility to format the ether value, which we can use when setting the balance on on the component.
And now we can call this function when a button is clicked and show the balance value in the UI.
Now let's go ahead and declare the wallet balance component in the main component and then we can serve the app locally by running npm run dev.
I've also added Bootstrap to my project to make things look a little nicer, but the end result should of a button that, when clicked, updates the balance in the UI.
That's how we can use Ethers to interact with the wallet, but now how do we interact with the smart contract?
We'll first need to import the contract ABI from the artifacts directory.
Now earlier, when you compiled your contract and ran the sample script, it should have said contract deployed to an address in the terminal.
Let's go ahead and take that contract address and set it up as a global variable here in our code.
We can then instantiate a web 3 provider again and use it to get the signer to execute transactions on the blockchain.
From there, we can use ethers to instantiate the contract using the address, the ABI and the signer.
What we wanna do next is loop over all of the NFT images in the collection.
Each one of those images will have a button to mint it.
Or if it's already been minted, the owner can view the token URI for the NFT.
We'll first need to know how many tokens have already been minted, and to do that, I'm setting up a function here called get count that calls the contract count method that we implemented in solidity earlier.
We'll then call this function when the component is first initialized with the useEffect hook.
In the JSX, I'm looping over every token that's been minted so far.
For each one of those items, I'm rendering a a component called nft image that takes the index as a prop, which conveniently matches the token ID.
Now, in the nft image component, I'm adding a property for the content ID.
This content ID comes from pinata.
Remember, I uploaded all my graphics to a folder in pinata.
We can combine the content ID with the token ID to reference that JSON metadata URI.
Now, when it comes to the actual image, I tried to use that pinata cloud gateway, but I didn't Find this to be very reliable.
I often had broken images, so currently, I'm referencing my images here locally.
Now, as we loop over these images, we need to figure out if each metadata URI I has been minted yet.
For that, I'm going to set up state on the component of isMinted and then define a function called getMintedStatus that will run the is content own method on the smart contract itself, and then we'll run that function with the useEffect hook.
And now we've reached the point where we can actually mint the token.
I'm creating another function to handle that, and inside the body, the first thing it will do is make a connection between the contract and the signer.
That will give us access to the recipient's to wallet address.
We then call the pay to mint method on the smart contract and pass the address as well as the metadata URI as arguments.
In addition, we need to set the value of ether that the user will pay.
For that, we pass an object with a value of the amount of ether, which in this case will be 0.05.
You may notice how this code is basically identical all to the code we wrote in our unit test earlier.
From there, we can wait for the result to be mined, after which point we can call that get minted status function again, and this time it should say that metadata URI has been minted.
Now, it's just a matter of using some conditional logic in the JSX to show the image URI if it's already been minted.
Otherwise, we'll just show a mystery placeholder and then we'll also show the option to mint the token if it's not already minted.
Otherwise, it will say that NFT is taken.
Now at this point, if all went well, you should be able to go to the application and When you click the mint button, it will bring up MetaMask confirming that you want to transfer 0.05 ether and will then complete the transaction after you confirm of it.
Congratulations, you just built a basic web 3 app.
Let's take a quick break to appreciate it.
It's Britney, bitch.
Now we can move on to phase 7, deployment.
This app is by no means production ready and would cost a lot of money to deploy it to the Ethereum mainnet.
But one thing we can do is deploy it to a testnet to see how it would work in the real world.
A free tool that can help us do that is Alchemy.
The majority of serious web 3 applications use tools like Alchemy and Infura, which are platforms that can help make decentralized apps more reliable.
What we're going to do is use Alchemy to deploy our contract to a test net.
When you create an account, it will give you the option to create a new application, and I'm going to use the Polygon chain with the Polygon Mumbai network.
Polygon, by the way, is a blockchain built on top of Ethereum that is faster unless expensive.
Its native token, MATIC, is very similar to ether.
For this tutorial, you can think of MATIC and ether as being the same basic thing.
Once the app is created, you'll notice it gives you a link to the network.
Go ahead and copy that.
Now go back to the hardhat config file in your source code.
You'll need a new entry under networks, which in this case will be Matic, and point it to the URL that you just copied.
The other thing you'll need is a private key for your account.
Go over to MetaMask and switch the network to Mumbai, then from the menu, click account details and export your private key, then paste it into the hardhat config.
The reason you need a private key here is because this account will be the one that deploys the contract, but deploying a contract isn't free and currently there is 0 MATIC in as wallet.
To get some free test money, we'll need to go to the Polygon faucet and add our public wallet address there, and after a few minutes of waiting, you should magically see some MATIC appear in your wallet.
And now we're ready for the moment of truth.
From the terminal, run the hardhat deploy script again, but this time make sure the network option is set to HANA.
That should deploy the contract to the Mumbai network, make sure to copy the address and update it in your front end code in the main dot JSX file.
You now have a web 3 application running out in the wild, and you could follow the same basic process to deploy to the main net.
I'm gonna go ahead and wrap things up there.
Hopefully, that gives you a general idea of all the steps involved in building a dApp.
The final thing I'll mention is that if you want to purchase these n f t's yourself, you can do so on OpenSea.
E.
I don't know why you ever would, but they're there if you want them.
Thanks for watching, and I will see you in the next one.

Speaker 0: In today's video, we'll build a complete web 3 application step by step from scratch and in the process, we'll talk about the good and bad aspects of developing decentralized web apps on the blockchain. You may have seen the headlines of kids making 1,000,000 of dollars overnight by selling digital art in the form of NFTs. If you're like me and not already an NFT millionaire. You likely have some FOMO about this whole trend. You could point out how NFTs are dumb, pointless, and bad for the environment, or you could try to get in on the trend yourself, and that's exactly what we'll do in this video.

I'll show you how I created a collection of 20,000 unique graphics with some crappy artwork I drew by hand in a few minutes. We'll then take that artwork and upload it to the interplanetary file system. At which point, we can write a smart contract with Solidity and OpenZeppelin that will mint a new NFT whenever somebody transfers Ethereum to the smart contract. And finally, we'll use ethers. Js with React to build a web 3 application that provides a front end interface where people can actually interact of a smart contract.

By the end of this tutorial, you'll understand the complete process of going from 0 to a web 3 point o NFT application. This tutorial is longer than most on this channel and it's broken down into 7 phases. If you're new here, like and subscribe and follow along with the full tutorial on Fireship biome. And if you wanna see more web 3 content, let me know in the comments. Before we get started, let's first answer the question of what is an NFT collection.

A nonfudgeable token is a unique digital asset. Usually, it represents a piece of artwork like an image, but it can also represent things like domain names and physical items in the real world, but you'll often see NFTs packaged in a collection like CryptoPunks, Bored Ape Yacht Club, and doodles just to name a few. These graphics are created with a few base layers, like hair, eyes, clothing, and so on. The layers are then combined together randomly to create a bunch of unique graphics. What's interesting though is that the various traits and attributes have different levels of rarity.

When a graphic is generated, it's less likely to have one of the rare traits. This is actually really fun because you can think of a smart contract like a vending machine in the cloud. When an NFT collection is first offered, you can send crypto to that wallet address. It will mint a one of a in token and transfer it to your wallet. If you're lucky, you'll get something with a really rare trait.

It's not much different than opening up a pack of Pokemon cards. Most of the cards are very common, but there is a small chance you'll get something that's very rare and valuable. Now after you purchase an NFT, there's a secondary market where you can resell it to someone else on a site like OpenSea. Many people invest in NFTs hoping to flip them for a higher value later on. If you're the original creator, you can also configure your smart on track to receive royalty payments whenever the NFT changes hands in the future.

That's pretty cool, but there are a lot of bad things I could say about web 3 as well. The guy who created signal, an encrypted messaging app, created an NFT that actually changes its appearance based on where you view it. On OpenSea, it looks really cool, but in your wallet, but it looks like a piece of poop. Because the NFT image is hosted off chain, he just used a web server to display a different image based on the user agent that was requesting the image. Everybody talks about web 3 being decentralized and trustless, but the reality is that much of it works thanks to centralized APIs.

Read his full blog post to learn more. At the end of the day, we don't really care about that we're just here to have fun, get some exercise, and make a ton of money. Now we're ready to kick off phase 1 of this project, where we create the layers or graphics that we'll use for the NFT collection. I'm not much of an artist and everything I draw tends to look really creepy. Not much I can do about that, so I'm just gonna own it.

Believe it or not, creating NFT artwork is an art form. I I find it really satisfying because you can take a few basic images and use them to create thousands of different unique combinations. For my NFT collection, I actually used a pen and paper to draw everything by hand. I then digitized it and brought each individual layer into Figma. As you can see here, I have different categories for the various traits, like hair, eyes, nose, mouth, beard, and so on.

From there, I created a little script in Node. Js that randomly combines these layers together. You can find the source code on GitHub, but there are many existing tools out there that can help you generate in NFT collection without needing to write any code. If you're looking for a tutorial that doesn't require any code, this is not the video for you. If your goal is to just create a bunch of images and sell them as NFTs.

I'd recommend checking out this recent tutorial from Code Stacker for a more simplified approach. I'm not gonna go through every single line of code here, but I just wanna walk you through the process I used to create all my NFT graphics from scratch. 1st, you can see I have a directory called layers that contains a bunch of files like eyes 0, eyes 1, eyes 2, and so on. This directory contains all the possible layers that we would use in an image. From there, I have a file named index.js.

Inside of I have an SVG template. I'm using scalable vector graphics here, but I've seen other implementations that just use PNGs. Now each layer in our layers directory as an SVG, so all we have to do is grab the main content from that file and replace each one of these comments with the corresponding traffic like head, hair, eyes, nose, mouth, and beard. In order to do that, I'm using Node. Js to read one of our layer files and then use some regex to grab of the content inside the SVG tags.

Then I have a function called create image that will generate a bunch of random numbers and combine them together into an array. I've made this a recursive function that checks to see if that combination has already been taken, in which case it will try running the randomization again. If it is a valid combination, We'll go ahead and replace all the comments in the SVG template with the actual layers from our layers directory. Now, in addition to creating in image. We're also going to create a JSON file with some metadata about it.

This metadata is really important because it contains the name of the file as well as a link to its actual image on the interplanetary file system. That represents a unique file upload that cannot be modified. In addition, if the metadata contains attributes of the different traits in the image. Generally, when making an NFT collection, each trait has a different level of rarity. The more rare rates an NFT has, the more valuable it tends to be, thanks to the magic of artificial scarcity.

Now, I'll go ahead and write these files to my file system and as an added touch, I'm also burning the SVG to a PNG file as well. I'm using a node package called Sharp to make that possible. And finally, to run the script, I just have a while loop that calls the create image function for the number of images that I want to create. And now when we run the script with node, we get this out directory with a bunch of files that contain both the raw images and JSON for each individual graphic. That takes care of phase 1.

We can now generate 1,000 or even millions of individual graphics by simply adding more layers to the layers directory, but keep in mind that my implementation is very crude. There's a lot of optimizations we could make or better yet, we could have used a pre built solution out there to get this job done much faster. Now the next thing we need to think about is how to get these files on the Internet and connect them to a non fungible token. The actual image data and JSON for the NFT t is too big to be efficiently stored on the blockchain. So instead, we store it off chain on the interplanetary file system, which is a decentralized file system in the cloud very similar to BitTorrent.

One very important concern that IPFS handles is content addressability. Anytime you upload a file, it creates a unique identifier for at upload, and that allows us to verify the authenticity of any graphics associated to an NFT. Once a file has been uploaded, you can't modify it without changing its content identifier. That means when minting an NFT, the only thing we actually need to store is a link to that file's content identifier. Now the question becomes, How do we take our raw files and upload them to IPFS?

There are many ways to go about it, but an easy free solution that I've been using is of it. It's very similar to something like Dropbox where you simply click a button to upload and choose a file from your file system, and you can even host an entire static website from Yotta. It also has a node SDK to upload programmatically, but we're not going to worry about it in this video. I'm just going to upload a few of our images here, and you'll notice when I that it creates a content identifier. Conveniently, we can upload an entire directory all at once.

I'm gonna go ahead and upload a few of the graphics that I just generated. For this tutorial, You can upload any random file. It doesn't really matter. And now, we're ready to build a full stack web 3 application using Solidity, Hardhat, and React. The first thing I'm doing here is generating a new React app using Vite.

It really doesn't matter which front end framework you use here, but the vast majority of web 3 demos out there use React. That Gives us a front end application. Now we're going to run npx hardhat, which will add a variety of tools to our project to add a blockchain back end. You'll notice it generates a directory for contracts, which contains files written in Solidity, which contains the smart contract code that will interact with the blockchain. It also creates a directory named scripts that contains the code to deploy those contracts to the blockchain.

Now there's a couple of configuration things we'll need to do here. In the hardhat config file, We'll update the paths option to create any artifacts in the source directory for the React application. That allows React to access information about the smart contracts. When you compile of smart contract. It creates what's known as an application binary interface, which is basically a middleman that allows your front end JavaScript code to communicate with the smart contract compiled to machine code and all that information lives in the our contract compiled to machine code, and all that information lives in the artifacts directory.

From there, we're going to install a bunch of dependencies with npm, like Waffle for automated testing and ethers to interact with smart contracts in the browser and also a tool called OpenZeppelin, which provides templates for quickly building industry standard smart contracts. At this point, I want to focus on writing a smart contract. Its purpose is to accept a payment from a user, then mint a non fungible token and transfer it to that user's wallet. It's important to point out that the code in the smart contract will not actually generate random rates for the NFT images. It's actually extremely difficult to handle randomness in a smart contract.

Most NFT collections don't deal with it at all, and instead, they just generate all the images at once, upload them to IPFS, and then mint them after the fact. At which point, they get sold on a secondary market, or you might code up another contract to create your own secondary market. Now it is possible to implement randomness in a smart contract, and if that's what you wanna do, I would highly recommend looking into something like Chainlink. We're going to take the easy approach in this video where the smart contract takes the IPFS URL for the metadata along with some Ethereum and mints a new token from it. To handle that requirement, we'll need to learn a new programming language called Solidity.

In the contract x directory. Let's go ahead and create a file ending in dot s o l. Now, we could implement a smart contract from scratch, but that would be a pretty big undertaking on its own. Luckily, there's a tool called in Zeppelin, and it has a wizard that we can use to automatically generate reliable code for us. The Ethereum ecosystem already has a variety of standard interfaces to handle requirements commonly implemented in smart contracts.

Like ERC 20 is what you would use to create a fungible token, like if you wanted to create your own coin on the Ethereum network. But to create a non fungible token, we want to use the ERC 721 standard. Before we customize it, you'll notice that there is API documentation with a handful of methods built into the base contract, like balance of to check the owner's balance or owner of to to see who owns a token, as well as methods to transfer tokens from one user to another. Now let's go over to the open Zeppelin wizard to customize our own ERC 721 contract. Most importantly, we need to be able to mint our own tokens.

If we check the box for mint, it adds a new method to the contract that allows a privileged account to mint or create a new token. Let's also auto increment IDs and then check the box for URI storage. URI storage allows us to associate and upload on IPFS when this token is minted. Remember, that's the reference to the metadata that we uploaded on pinata earlier. We'll also wanna use a base URI here that points to of PFS to ensure that the URI is properly formatted.

That gives us a base contract to work with and you'll notice a button here to open up in the Remix IDE. I'm not going to do it in this video, but Remix is a browser based IDE that makes it really easy to compile and test your smart on tracks. What we're going to do is copy and paste this code and bring it directly into the solidity file that we created. We could use this contract as is, but we want to extend it with some additional code that allows anybody to mint a token as long as they transfer the appropriate amount of Ethereum along with it. Currently, you'll notice a safe mint method that allows the owner of the contract to mint a new token.

What we wanna do is create a new function called pay to mint that takes a recipient and metadata a content ID, then mint a new token with that data. Now in order to implement this function, we'll wanna make sure that the same URI can't be minted twice. And to validate that, I'm creating a mapping of Strings to integers to keep track of the existing URIs that have been minted. We might also want to check if an existing URI is already owned, so I'm creating another function called is content owned that takes a URI as its argument and returns true if that URI already exists in the happening. Now, we have everything in place to implement the paydement function.

You'll notice that it's marked as a payable function, which means that somebody can transfer money into the contract. Tracked. Now, we can use the require keyword to run some validation. And, keep in mind that this is not a production ready contract. My goal is just to show you how some of the basic mechanics in Solidity work.

With require, we first pass a condition. In this case, we want to know if the URI has already been minted. If it has not been minted, the function will continue executing. Otherwise, it will throw an error saying the NFT has already been minted. The next thing we wanna validate is that the user has paid enough ether.

There's a global variable of message, and its value property contains the amount of ether being sent into the contract. We can make sure that the minimum value is greater than 0.05. Otherwise, we'll throw an error saying the user needs to pay up. From there, we'll want to create a new item ID. With the counter implemented by OpenZeppelin, it will increment each new token by 1.

So it starts at 0 then goes to 1, 2, 3, and so on. After incrementing the counter, we'll update our mapping of the existing URI's, then we call the built in mint method with the recipient's wallet address, and finally, we set the token URI on that ID. That's how someone can pay to mint a new token. And as one final touch, I'm also going to add A function here to get the current count, so we can know exactly how many tokens have been minted so far. And that completes the Solidity code for our back end.

At this point, you may want to just jump straight into building a web 3 application, but I would highly recommend that you do some testing first. Hardhat already has a sample test ready to go. And the code you write in a test will be very similar, if not identical, to the code that you write in your front end React application. It's much easier to detect bugs and issues in a test than it is in a front end application with all the UI stuff going on. If you've never done test driven development before, I have an entire video on it.

In the test, we'll first use ethers to get our contract and then deploy it. Once deployed, we'll then need a wallet address with some ether in it for testing. Luckily, we can use a fake wallet with 10,000 ether in it already by going to the terminal and running npx hardhat node. This creates a mock network on localhost and provides us with a bunch of fake accounts to used for testing. Copy one of the public keys and use it in your test.

At this point, we can start calling the methods on the deployed smart contract. First, I'll create a variable called balance that checks the current balance of the recipient's wallet address. Balance of is a method built into the ERC 721 spec. Now Now currently, the user hasn't purchased any NFTs, so we expect the balance to equal 0. Now from there, we'll create another variable called newly minted token that calls the payment method that we defined on the smart contract.

It takes the recipient and metadata URI as arguments, and then we can also define the message value as 0.05 ether. For fun, let's go ahead and set the ether value to 0.01. Now go to the terminal and run npx hardhat test. What you'll notice is that we get a failing test, and you'll see the error message here that the user needs to pay up. Let's go ahead and fix that, and then we'll wait for the newly minted token to be mined by calling the wait method on it.

From there, we can query the balance again, and this time we expect it to equal 1. In addition, we can test our is content owned method by making sure that that metadata URI is equal to true. And there are all kinds of other things we could test here, but you get the general idea. If you test all your smart contract logic first, It'll make the front end development much easier. Now, we're ready to move on to the next phase, where we build a web 3 application that interacts with a smart contract from a website.

Let's 1st, go into the sample script provided by HardHat. This script is used to compile the contract, which will populate the artifacts directory with all the information we need to interact with like the ABI I talked about earlier. We'll want to update the default values with the name of the custom contract that we created. You'll want to first make sure you have opened running the npx hardhat node command. This should always be running in the background.

From there, we can open up a separate terminal and run npx hard at compile. This runs the solidity compiler to convert your code into binary. Once that's done, we can run npx hard hat run scripts, sample script, and specify the network as local host. That will take the contract and deploy it to the actual network. And now we have a smart contract running on our local Sheen.

Now when it comes to web 3, the way end users interact with a smart contract is typically with a browser plugin like Metamask. For development, You'll want to set up MetaMask with one of the testing addresses provided by Hardhat. If you don't have it yet, install MetaMask and then go to the local host network and import a new account. It will ask you for a private key, which you can simply copy from the terminal output. And now we're ready to start writing some React code.

In order for a user to mint an NFT on the website. They'll need to have MetaMask installed. We'll need to check that at runtime and have 2 different screens based on whether or not installed. I'm creating 2 different components here, one called home and one called install. And in the install component, we'll simply have a link to the MetaMask plug in.

Now in the main app component, we can check to see if the user has a plug in installed by checking the window ethereum object. A plug in like Metamask will make this object available automatically when it's installed. Now the next thing I'll do is create a new component called wallet balance. And inside of it, We can start interacting with ethers. Js, which is a JavaScript library that makes it easy to communicate between the smart contract and in end user's wallet.

In this component, what we wanna do is get the end user's current balance. We'll first set up state with the use state hook and then define a function called GitBalance. We can get the connected account on the window Ethereum object and then we use ethers. Js to create a new web 3 provider. The provider provides all kinds of or methods for interacting with the Blockchain.

One of which is getBalance, which then takes the account as its argument. That will return the wallet balance of the connected account, which should be 10,000 ether, but it's in a big number format. So ethers also provides a utility to format the ether value, which we can use when setting the balance on on the component. And now we can call this function when a button is clicked and show the balance value in the UI. Now let's go ahead and declare the wallet balance component in the main component and then we can serve the app locally by running npm run dev.

I've also added Bootstrap to my project to make things look a little nicer, but the end result should of a button that, when clicked, updates the balance in the UI. That's how we can use Ethers to interact with the wallet, but now how do we interact with the smart contract? We'll first need to import the contract ABI from the artifacts directory. Now earlier, when you compiled your contract and ran the sample script, it should have said contract deployed to an address in the terminal. Let's go ahead and take that contract address and set it up as a global variable here in our code.

We can then instantiate a web 3 provider again and use it to get the signer to execute transactions on the blockchain. From there, we can use ethers to instantiate the contract using the address, the ABI and the signer. What we wanna do next is loop over all of the NFT images in the collection. Each one of those images will have a button to mint it. Or if it's already been minted, the owner can view the token URI for the NFT.

We'll first need to know how many tokens have already been minted, and to do that, I'm setting up a function here called get count that calls the contract count method that we implemented in solidity earlier. We'll then call this function when the component is first initialized with the useEffect hook. In the JSX, I'm looping over every token that's been minted so far. For each one of those items, I'm rendering a a component called nft image that takes the index as a prop, which conveniently matches the token ID. Now, in the nft image component, I'm adding a property for the content ID.

This content ID comes from pinata. Remember, I uploaded all my graphics to a folder in pinata. We can combine the content ID with the token ID to reference that JSON metadata URI. Now, when it comes to the actual image, I tried to use that pinata cloud gateway, but I didn't Find this to be very reliable. I often had broken images, so currently, I'm referencing my images here locally.

Now, as we loop over these images, we need to figure out if each metadata URI I has been minted yet. For that, I'm going to set up state on the component of isMinted and then define a function called getMintedStatus that will run the is content own method on the smart contract itself, and then we'll run that function with the useEffect hook. And now we've reached the point where we can actually mint the token. I'm creating another function to handle that, and inside the body, the first thing it will do is make a connection between the contract and the signer. That will give us access to the recipient's to wallet address.

We then call the pay to mint method on the smart contract and pass the address as well as the metadata URI as arguments. In addition, we need to set the value of ether that the user will pay. For that, we pass an object with a value of the amount of ether, which in this case will be 0.05. You may notice how this code is basically identical all to the code we wrote in our unit test earlier. From there, we can wait for the result to be mined, after which point we can call that get minted status function again, and this time it should say that metadata URI has been minted.

Now, it's just a matter of using some conditional logic in the JSX to show the image URI if it's already been minted. Otherwise, we'll just show a mystery placeholder and then we'll also show the option to mint the token if it's not already minted. Otherwise, it will say that NFT is taken. Now at this point, if all went well, you should be able to go to the application and When you click the mint button, it will bring up MetaMask confirming that you want to transfer 0.05 ether and will then complete the transaction after you confirm of it. Congratulations, you just built a basic web 3 app.

Let's take a quick break to appreciate it. It's Britney, bitch. Now we can move on to phase 7, deployment. This app is by no means production ready and would cost a lot of money to deploy it to the Ethereum mainnet. But one thing we can do is deploy it to a testnet to see how it would work in the real world.

A free tool that can help us do that is Alchemy. The majority of serious web 3 applications use tools like Alchemy and Infura, which are platforms that can help make decentralized apps more reliable. What we're going to do is use Alchemy to deploy our contract to a test net. When you create an account, it will give you the option to create a new application, and I'm going to use the Polygon chain with the Polygon Mumbai network. Polygon, by the way, is a blockchain built on top of Ethereum that is faster unless expensive.

Its native token, MATIC, is very similar to ether. For this tutorial, you can think of MATIC and ether as being the same basic thing. Once the app is created, you'll notice it gives you a link to the network. Go ahead and copy that. Now go back to the hardhat config file in your source code.

You'll need a new entry under networks, which in this case will be Matic, and point it to the URL that you just copied. The other thing you'll need is a private key for your account. Go over to MetaMask and switch the network to Mumbai, then from the menu, click account details and export your private key, then paste it into the hardhat config. The reason you need a private key here is because this account will be the one that deploys the contract, but deploying a contract isn't free and currently there is 0 MATIC in as wallet. To get some free test money, we'll need to go to the Polygon faucet and add our public wallet address there, and after a few minutes of waiting, you should magically see some MATIC appear in your wallet.

And now we're ready for the moment of truth. From the terminal, run the hardhat deploy script again, but this time make sure the network option is set to HANA. That should deploy the contract to the Mumbai network, make sure to copy the address and update it in your front end code in the main dot JSX file. You now have a web 3 application running out in the wild, and you could follow the same basic process to deploy to the main net. I'm gonna go ahead and wrap things up there.

Hopefully, that gives you a general idea of all the steps involved in building a dApp. The final thing I'll mention is that if you want to purchase these n f t's yourself, you can do so on OpenSea. E. I don't know why you ever would, but they're there if you want them. Thanks for watching, and I will see you in the next one.
In today's video, we'll build a complete web 3 application step by step from scratch and in the process, we'll talk about the good and bad aspects of developing decentralized web apps on the blockchain. You may have seen the headlines of kids making 1,000,000 of dollars overnight by selling digital art in the form of NFTs.
technology
intellectual property
If you're like me and not already an NFT millionaire.
You likely have some FOMO about this whole trend. You could point out how NFTs are dumb, pointless, and bad for the environment, or you could try to get in on the trend yourself, and that's exactly what we'll do in this video. I'll show you how I created a collection of 20,000 unique graphics with some crappy artwork I drew by hand in a few minutes. We'll then take that artwork and upload it to the interplanetary file system. At which point, we can write a smart contract with Solidity and OpenZeppelin that will mint a new NFT whenever somebody transfers Ethereum to the smart contract. And finally, we'll use ethers. Js with React to build a web 3 application that provides a front end interface where people can actually interact of a smart contract.
graphic design
art
copyright
patents
crafts
cryptocurrency
By the end of this tutorial, you'll understand the complete process of going from 0 to a web 3 point o NFT application. This tutorial is longer than most on this channel and it's broken down into 7 phases. If you're new here, like and subscribe and follow along with the full tutorial on Fireship biome. And if you wanna see more web 3 content, let me know in the comments.
Before we get started, let's first answer the question of what is an NFT collection. A nonfudgeable token is a unique digital asset. Usually, it represents a piece of artwork like an image, but it can also represent things like domain names and physical items in the real world, but you'll often see NFTs packaged in a collection like CryptoPunks, Bored Ape Yacht Club, and doodles just to name a few. These graphics are created with a few base layers, like hair, eyes, clothing, and so on. The layers are then combined together randomly to create a bunch of unique graphics. What's interesting though is that the various traits and attributes have different levels of rarity. When a graphic is generated, it's less likely to have one of the rare traits.
cryptocurrency
graphic design
This is actually really fun because you can think of a smart contract like a vending machine in the cloud. When an NFT collection is first offered, you can send crypto to that wallet address. It will mint a one of a in token and transfer it to your wallet. If you're lucky, you'll get something with a really rare trait. It's not much different than opening up a pack of Pokemon cards. Most of the cards are very common, but there is a small chance you'll get something that's very rare and valuable. Now after you purchase an NFT, there's a secondary market where you can resell it to someone else on a site like OpenSea.
cryptocurrency
gambling
purchasing
candy
Many people invest in NFTs hoping to flip them for a higher value later on.
If you're the original creator, you can also configure your smart on track to receive royalty payments whenever the NFT changes hands in the future. That's pretty cool, but there are a lot of bad things I could say about web 3 as well. The guy who created signal, an encrypted messaging app, created an NFT that actually changes its appearance based on where you view it. On OpenSea, it looks really cool, but in your wallet, but it looks like a piece of poop. Because the NFT image is hosted off chain, he just used a web server to display a different image based on the user agent that was requesting the image. Everybody talks about web 3 being decentralized and trustless, but the reality is that much of it works thanks to centralized APIs. Read his full blog post to learn more. At the end of the day, we don't really care about that we're just here to have fun, get some exercise, and make a ton of money.
internet
cryptocurrency
commerce
networking
Now we're ready to kick off phase 1 of this project, where we create the layers or graphics that we'll use for the NFT collection. I'm not much of an artist and everything I draw tends to look really creepy. Not much I can do about that, so I'm just gonna own it. Believe it or not, creating NFT artwork is an art form. I I find it really satisfying because you can take a few basic images and use them to create thousands of different unique combinations. For my NFT collection, I actually used a pen and paper to draw everything by hand. I then digitized it and brought each individual layer into Figma. As you can see here, I have different categories for the various traits, like hair, eyes, nose, mouth, beard, and so on. From there, I created a little script in Node.
graphic design
art
crafts
Js that randomly combines these layers together. You can find the source code on GitHub, but there are many existing tools out there that can help you generate in NFT collection without needing to write any code.
If you're looking for a tutorial that doesn't require any code, this is not the video for you. If your goal is to just create a bunch of images and sell them as NFTs. I'd recommend checking out this recent tutorial from Code Stacker for a more simplified approach. I'm not gonna go through every single line of code here, but I just wanna walk you through the process I used to create all my NFT graphics from scratch. 1st, you can see I have a directory called layers that contains a bunch of files like eyes 0, eyes 1, eyes 2, and so on.
graphic design
visualization
This directory contains all the possible layers that we would use in an image. From there, I have a file named index.js. Inside of I have an SVG template.
I'm using scalable vector graphics here, but I've seen other implementations that just use PNGs. Now each layer in our layers directory as an SVG, so all we have to do is grab the main content from that file and replace each one of these comments with the corresponding traffic like head, hair, eyes, nose, mouth, and beard.
visualization
In order to do that, I'm using Node. Js to read one of our layer files and then use some regex to grab of the content inside the SVG tags. Then I have a function called create image that will generate a bunch of random numbers and combine them together into an array. I've made this a recursive function that checks to see if that combination has already been taken, in which case it will try running the randomization again. If it is a valid combination, We'll go ahead and replace all the comments in the SVG template with the actual layers from our layers directory. Now, in addition to creating in image. We're also going to create a JSON file with some metadata about it. This metadata is really important because it contains the name of the file as well as a link to its actual image on the interplanetary file system. That represents a unique file upload that cannot be modified. In addition, if the metadata contains attributes of the different traits in the image. Generally, when making an NFT collection, each trait has a different level of rarity. The more rare rates an NFT has, the more valuable it tends to be, thanks to the magic of artificial scarcity. Now, I'll go ahead and write these files to my file system and as an added touch, I'm also burning the SVG to a PNG file as well. I'm using a node package called Sharp to make that possible. And finally, to run the script, I just have a while loop that calls the create image function for the number of images that I want to create.
And now when we run the script with node, we get this out directory with a bunch of files that contain both the raw images and JSON for each individual graphic. That takes care of phase 1. We can now generate 1,000 or even millions of individual graphics by simply adding more layers to the layers directory, but keep in mind that my implementation is very crude. There's a lot of optimizations we could make or better yet, we could have used a pre built solution out there to get this job done much faster.
graphic design
Now the next thing we need to think about is how to get these files on the Internet and connect them to a non fungible token.
The actual image data and JSON for the NFT t is too big to be efficiently stored on the blockchain. So instead, we store it off chain on the interplanetary file system, which is a decentralized file system in the cloud very similar to BitTorrent. One very important concern that IPFS handles is content addressability.
internet
Anytime you upload a file, it creates a unique identifier for at upload, and that allows us to verify the authenticity of any graphics associated to an NFT. Once a file has been uploaded, you can't modify it without changing its content identifier. That means when minting an NFT, the only thing we actually need to store is a link to that file's content identifier. Now the question becomes, How do we take our raw files and upload them to IPFS? There are many ways to go about it, but an easy free solution that I've been using is of it.
It's very similar to something like Dropbox where you simply click a button to upload and choose a file from your file system, and you can even host an entire static website from Yotta. It also has a node SDK to upload programmatically, but we're not going to worry about it in this video. I'm just going to upload a few of our images here, and you'll notice when I that it creates a content identifier. Conveniently, we can upload an entire directory all at once.
streaming
I'm gonna go ahead and upload a few of the graphics that I just generated. For this tutorial, You can upload any random file. It doesn't really matter. And now, we're ready to build a full stack web 3 application using Solidity, Hardhat, and React.
The first thing I'm doing here is generating a new React app using Vite. It really doesn't matter which front end framework you use here, but the vast majority of web 3 demos out there use React. That Gives us a front end application. Now we're going to run npx hardhat, which will add a variety of tools to our project to add a blockchain back end.
software development
You'll notice it generates a directory for contracts, which contains files written in Solidity, which contains the smart contract code that will interact with the blockchain. It also creates a directory named scripts that contains the code to deploy those contracts to the blockchain. Now there's a couple of configuration things we'll need to do here.
cryptocurrency
In the hardhat config file, We'll update the paths option to create any artifacts in the source directory for the React application. That allows React to access information about the smart contracts. When you compile of smart contract. It creates what's known as an application binary interface, which is basically a middleman that allows your front end JavaScript code to communicate with the smart contract compiled to machine code and all that information lives in the our contract compiled to machine code, and all that information lives in the artifacts directory. From there, we're going to install a bunch of dependencies with npm, like Waffle for automated testing and ethers to interact with smart contracts in the browser and also a tool called OpenZeppelin, which provides templates for quickly building industry standard smart contracts. At this point, I want to focus on writing a smart contract.
programming
software
software development
patents
logic
Its purpose is to accept a payment from a user, then mint a non fungible token and transfer it to that user's wallet. It's important to point out that the code in the smart contract will not actually generate random rates for the NFT images. It's actually extremely difficult to handle randomness in a smart contract. Most NFT collections don't deal with it at all, and instead, they just generate all the images at once, upload them to IPFS, and then mint them after the fact.
At which point, they get sold on a secondary market, or you might code up another contract to create your own secondary market. Now it is possible to implement randomness in a smart contract, and if that's what you wanna do, I would highly recommend looking into something like Chainlink.
marketing
patents
intellectual property
copyright licenses
commerce
We're going to take the easy approach in this video where the smart contract takes the IPFS URL for the metadata along with some Ethereum and mints a new token from it.
To handle that requirement, we'll need to learn a new programming language called Solidity. In the contract x directory. Let's go ahead and create a file ending in dot s o l. Now, we could implement a smart contract from scratch, but that would be a pretty big undertaking on its own.
programming
software development
Luckily, there's a tool called in Zeppelin, and it has a wizard that we can use to automatically generate reliable code for us.
The Ethereum ecosystem already has a variety of standard interfaces to handle requirements commonly implemented in smart contracts. Like ERC 20 is what you would use to create a fungible token, like if you wanted to create your own coin on the Ethereum network. But to create a non fungible token, we want to use the ERC 721 standard. Before we customize it, you'll notice that there is API documentation with a handful of methods built into the base contract, like balance of to check the owner's balance or owner of to to see who owns a token, as well as methods to transfer tokens from one user to another.
documentation
cryptocurrency
Now let's go over to the open Zeppelin wizard to customize our own ERC 721 contract. Most importantly, we need to be able to mint our own tokens. If we check the box for mint, it adds a new method to the contract that allows a privileged account to mint or create a new token. Let's also auto increment IDs and then check the box for URI storage. URI storage allows us to associate and upload on IPFS when this token is minted. Remember, that's the reference to the metadata that we uploaded on pinata earlier. We'll also wanna use a base URI here that points to of PFS to ensure that the URI is properly formatted.
That gives us a base contract to work with and you'll notice a button here to open up in the Remix IDE. I'm not going to do it in this video, but Remix is a browser based IDE that makes it really easy to compile and test your smart on tracks.
youtube
What we're going to do is copy and paste this code and bring it directly into the solidity file that we created. We could use this contract as is, but we want to extend it with some additional code that allows anybody to mint a token as long as they transfer the appropriate amount of Ethereum along with it. Currently, you'll notice a safe mint method that allows the owner of the contract to mint a new token. What we wanna do is create a new function called pay to mint that takes a recipient and metadata a content ID, then mint a new token with that data. Now in order to implement this function, we'll wanna make sure that the same URI can't be minted twice. And to validate that, I'm creating a mapping of Strings to integers to keep track of the existing URIs that have been minted. We might also want to check if an existing URI is already owned, so I'm creating another function called is content owned that takes a URI as its argument and returns true if that URI already exists in the happening.
Now, we have everything in place to implement the paydement function. You'll notice that it's marked as a payable function, which means that somebody can transfer money into the contract. Tracked. Now, we can use the require keyword to run some validation. And, keep in mind that this is not a production ready contract.
billing
My goal is just to show you how some of the basic mechanics in Solidity work. With require, we first pass a condition. In this case, we want to know if the URI has already been minted. If it has not been minted, the function will continue executing.
Otherwise, it will throw an error saying the NFT has already been minted. The next thing we wanna validate is that the user has paid enough ether. There's a global variable of message, and its value property contains the amount of ether being sent into the contract. We can make sure that the minimum value is greater than 0.05.
cryptocurrency
Otherwise, we'll throw an error saying the user needs to pay up. From there, we'll want to create a new item ID. With the counter implemented by OpenZeppelin, it will increment each new token by 1. So it starts at 0 then goes to 1, 2, 3, and so on. After incrementing the counter, we'll update our mapping of the existing URI's, then we call the built in mint method with the recipient's wallet address, and finally, we set the token URI on that ID. That's how someone can pay to mint a new token. And as one final touch, I'm also going to add A function here to get the current count, so we can know exactly how many tokens have been minted so far. And that completes the Solidity code for our back end. At this point, you may want to just jump straight into building a web 3 application, but I would highly recommend that you do some testing first. Hardhat already has a sample test ready to go. And the code you write in a test will be very similar, if not identical, to the code that you write in your front end React application.
It's much easier to detect bugs and issues in a test than it is in a front end application with all the UI stuff going on. If you've never done test driven development before, I have an entire video on it. In the test, we'll first use ethers to get our contract and then deploy it. Once deployed, we'll then need a wallet address with some ether in it for testing. Luckily, we can use a fake wallet with 10,000 ether in it already by going to the terminal and running npx hardhat node. This creates a mock network on localhost and provides us with a bunch of fake accounts to used for testing.
cryptocurrency
software development
Copy one of the public keys and use it in your test. At this point, we can start calling the methods on the deployed smart contract. First, I'll create a variable called balance that checks the current balance of the recipient's wallet address.
Balance of is a method built into the ERC 721 spec. Now Now currently, the user hasn't purchased any NFTs, so we expect the balance to equal 0. Now from there, we'll create another variable called newly minted token that calls the payment method that we defined on the smart contract. It takes the recipient and metadata URI as arguments, and then we can also define the message value as 0.05 ether. For fun, let's go ahead and set the ether value to 0.01.
cryptocurrency
banking
finance
billing
Now go to the terminal and run npx hardhat test. What you'll notice is that we get a failing test, and you'll see the error message here that the user needs to pay up.
Let's go ahead and fix that, and then we'll wait for the newly minted token to be mined by calling the wait method on it. From there, we can query the balance again, and this time we expect it to equal 1. In addition, we can test our is content owned method by making sure that that metadata URI is equal to true.
mining
And there are all kinds of other things we could test here, but you get the general idea. If you test all your smart contract logic first, It'll make the front end development much easier. Now, we're ready to move on to the next phase, where we build a web 3 application that interacts with a smart contract from a website. Let's 1st, go into the sample script provided by HardHat. This script is used to compile the contract, which will populate the artifacts directory with all the information we need to interact with like the ABI I talked about earlier.
patents
logic
software development
software
programming
We'll want to update the default values with the name of the custom contract that we created. You'll want to first make sure you have opened running the npx hardhat node command. This should always be running in the background. From there, we can open up a separate terminal and run npx hard at compile. This runs the solidity compiler to convert your code into binary.
Once that's done, we can run npx hard hat run scripts, sample script, and specify the network as local host. That will take the contract and deploy it to the actual network. And now we have a smart contract running on our local Sheen. Now when it comes to web 3, the way end users interact with a smart contract is typically with a browser plugin like Metamask. For development, You'll want to set up MetaMask with one of the testing addresses provided by Hardhat.
internet
networking
If you don't have it yet, install MetaMask and then go to the local host network and import a new account. It will ask you for a private key, which you can simply copy from the terminal output. And now we're ready to start writing some React code. In order for a user to mint an NFT on the website. They'll need to have MetaMask installed. We'll need to check that at runtime and have 2 different screens based on whether or not installed. I'm creating 2 different components here, one called home and one called install. And in the install component, we'll simply have a link to the MetaMask plug in. Now in the main app component, we can check to see if the user has a plug in installed by checking the window ethereum object. A plug in like Metamask will make this object available automatically when it's installed. Now the next thing I'll do is create a new component called wallet balance. And inside of it, We can start interacting with ethers. Js, which is a JavaScript library that makes it easy to communicate between the smart contract and in end user's wallet. In this component, what we wanna do is get the end user's current balance. We'll first set up state with the use state hook and then define a function called GitBalance.
We can get the connected account on the window Ethereum object and then we use ethers. Js to create a new web 3 provider. The provider provides all kinds of or methods for interacting with the Blockchain. One of which is getBalance, which then takes the account as its argument. That will return the wallet balance of the connected account, which should be 10,000 ether, but it's in a big number format. So ethers also provides a utility to format the ether value, which we can use when setting the balance on on the component. And now we can call this function when a button is clicked and show the balance value in the UI. Now let's go ahead and declare the wallet balance component in the main component and then we can serve the app locally by running npm run dev.
cryptocurrency
networking
internet
banking
I've also added Bootstrap to my project to make things look a little nicer, but the end result should of a button that, when clicked, updates the balance in the UI. That's how we can use Ethers to interact with the wallet, but now how do we interact with the smart contract? We'll first need to import the contract ABI from the artifacts directory. Now earlier, when you compiled your contract and ran the sample script, it should have said contract deployed to an address in the terminal. Let's go ahead and take that contract address and set it up as a global variable here in our code. We can then instantiate a web 3 provider again and use it to get the signer to execute transactions on the blockchain. From there, we can use ethers to instantiate the contract using the address, the ABI and the signer. What we wanna do next is loop over all of the NFT images in the collection. Each one of those images will have a button to mint it. Or if it's already been minted, the owner can view the token URI for the NFT. We'll first need to know how many tokens have already been minted, and to do that, I'm setting up a function here called get count that calls the contract count method that we implemented in solidity earlier. We'll then call this function when the component is first initialized with the useEffect hook. In the JSX, I'm looping over every token that's been minted so far.
For each one of those items, I'm rendering a a component called nft image that takes the index as a prop, which conveniently matches the token ID. Now, in the nft image component, I'm adding a property for the content ID. This content ID comes from pinata. Remember, I uploaded all my graphics to a folder in pinata.
visualization
We can combine the content ID with the token ID to reference that JSON metadata URI. Now, when it comes to the actual image, I tried to use that pinata cloud gateway, but I didn't Find this to be very reliable. I often had broken images, so currently, I'm referencing my images here locally. Now, as we loop over these images, we need to figure out if each metadata URI I has been minted yet. For that, I'm going to set up state on the component of isMinted and then define a function called getMintedStatus that will run the is content own method on the smart contract itself, and then we'll run that function with the useEffect hook. And now we've reached the point where we can actually mint the token. I'm creating another function to handle that, and inside the body, the first thing it will do is make a connection between the contract and the signer.
That will give us access to the recipient's to wallet address. We then call the pay to mint method on the smart contract and pass the address as well as the metadata URI as arguments. In addition, we need to set the value of ether that the user will pay.
cryptocurrency
billing
For that, we pass an object with a value of the amount of ether, which in this case will be 0.05. You may notice how this code is basically identical all to the code we wrote in our unit test earlier. From there, we can wait for the result to be mined, after which point we can call that get minted status function again, and this time it should say that metadata URI has been minted. Now, it's just a matter of using some conditional logic in the JSX to show the image URI if it's already been minted. Otherwise, we'll just show a mystery placeholder and then we'll also show the option to mint the token if it's not already minted. Otherwise, it will say that NFT is taken. Now at this point, if all went well, you should be able to go to the application and When you click the mint button, it will bring up MetaMask confirming that you want to transfer 0.05 ether and will then complete the transaction after you confirm of it. Congratulations, you just built a basic web 3 app. Let's take a quick break to appreciate it. It's Britney, bitch. Now we can move on to phase 7, deployment. This app is by no means production ready and would cost a lot of money to deploy it to the Ethereum mainnet. But one thing we can do is deploy it to a testnet to see how it would work in the real world.
A free tool that can help us do that is Alchemy. The majority of serious web 3 applications use tools like Alchemy and Infura, which are platforms that can help make decentralized apps more reliable. What we're going to do is use Alchemy to deploy our contract to a test net.
software
software development
When you create an account, it will give you the option to create a new application, and I'm going to use the Polygon chain with the Polygon Mumbai network.
Polygon, by the way, is a blockchain built on top of Ethereum that is faster unless expensive. Its native token, MATIC, is very similar to ether. For this tutorial, you can think of MATIC and ether as being the same basic thing. Once the app is created, you'll notice it gives you a link to the network. Go ahead and copy that. Now go back to the hardhat config file in your source code. You'll need a new entry under networks, which in this case will be Matic, and point it to the URL that you just copied.
cryptocurrency
networking
The other thing you'll need is a private key for your account. Go over to MetaMask and switch the network to Mumbai, then from the menu, click account details and export your private key, then paste it into the hardhat config.
The reason you need a private key here is because this account will be the one that deploys the contract, but deploying a contract isn't free and currently there is 0 MATIC in as wallet. To get some free test money, we'll need to go to the Polygon faucet and add our public wallet address there, and after a few minutes of waiting, you should magically see some MATIC appear in your wallet.
cryptocurrency
And now we're ready for the moment of truth. From the terminal, run the hardhat deploy script again, but this time make sure the network option is set to HANA. That should deploy the contract to the Mumbai network, make sure to copy the address and update it in your front end code in the main dot JSX file. You now have a web 3 application running out in the wild, and you could follow the same basic process to deploy to the main net. I'm gonna go ahead and wrap things up there. Hopefully, that gives you a general idea of all the steps involved in building a dApp.
The final thing I'll mention is that if you want to purchase these n f t's yourself, you can do so on OpenSea. E. I don't know why you ever would, but they're there if you want them. Thanks for watching, and I will see you in the next one.
purchasing
amazon
In today's video, we'll build a complete web 3 application step by step from scratch and in the process, we'll talk about the good and bad aspects of developing decentralized web apps on the blockchain. You may have seen the headlines of kids making 1,000,000 of dollars overnight by selling digital art in the form of NFTs. If you're like me and not already an NFT millionaire. You likely have some FOMO about this whole trend. You could point out how NFTs are dumb, pointless, and bad for the environment, or you could try to get in on the trend yourself, and that's exactly what we'll do in this video. I'll show you how I created a collection of 20,000 unique graphics with some crappy artwork I drew by hand in a few minutes. We'll then take that artwork and upload it to the interplanetary file system. At which point, we can write a smart contract with Solidity and OpenZeppelin that will mint a new NFT whenever somebody transfers Ethereum to the smart contract. And finally, we'll use ethers. Js with React to build a web 3 application that provides a front end interface where people can actually interact of a smart contract. By the end of this tutorial, you'll understand the complete process of going from 0 to a web 3 point o NFT application. This tutorial is longer than most on this channel and it's broken down into 7 phases. If you're new here, like and subscribe and follow along with the full tutorial on Fireship biome. And if you wanna see more web 3 content, let me know in the comments. Before we get started, let's first answer the question of what is an NFT collection. A nonfudgeable token is a unique digital asset. Usually, it represents a piece of artwork like an image, but it can also represent things like domain names and physical items in the real world, but you'll often see NFTs packaged in a collection like CryptoPunks, Bored Ape Yacht Club, and doodles just to name a few. These graphics are created with a few base layers, like hair, eyes, clothing, and so on. The layers are then combined together randomly to create a bunch of unique graphics. What's interesting though is that the various traits and attributes have different levels of rarity. When a graphic is generated, it's less likely to have one of the rare traits. This is actually really fun because you can think of a smart contract like a vending machine in the cloud. When an NFT collection is first offered, you can send crypto to that wallet address. It will mint a one of a in token and transfer it to your wallet. If you're lucky, you'll get something with a really rare trait. It's not much different than opening up a pack of Pokemon cards. Most of the cards are very common, but there is a small chance you'll get something that's very rare and valuable. Now after you purchase an NFT, there's a secondary market where you can resell it to someone else on a site like OpenSea. Many people invest in NFTs hoping to flip them for a higher value later on. If you're the original creator, you can also configure your smart on track to receive royalty payments whenever the NFT changes hands in the future. That's pretty cool, but there are a lot of bad things I could say about web 3 as well. The guy who created signal, an encrypted messaging app, created an NFT that actually changes its appearance based on where you view it. On OpenSea, it looks really cool, but in your wallet, but it looks like a piece of poop. Because the NFT image is hosted off chain, he just used a web server to display a different image based on the user agent that was requesting the image. Everybody talks about web 3 being decentralized and trustless, but the reality is that much of it works thanks to centralized APIs. Read his full blog post to learn more. At the end of the day, we don't really care about that we're just here to have fun, get some exercise, and make a ton of money. Now we're ready to kick off phase 1 of this project, where we create the layers or graphics that we'll use for the NFT collection. I'm not much of an artist and everything I draw tends to look really creepy. Not much I can do about that, so I'm just gonna own it. Believe it or not, creating NFT artwork is an art form. I I find it really satisfying because you can take a few basic images and use them to create thousands of different unique combinations. For my NFT collection, I actually used a pen and paper to draw everything by hand. I then digitized it and brought each individual layer into Figma. As you can see here, I have different categories for the various traits, like hair, eyes, nose, mouth, beard, and so on. From there, I created a little script in Node. Js that randomly combines these layers together. You can find the source code on GitHub, but there are many existing tools out there that can help you generate in NFT collection without needing to write any code. If you're looking for a tutorial that doesn't require any code, this is not the video for you. If your goal is to just create a bunch of images and sell them as NFTs. I'd recommend checking out this recent tutorial from Code Stacker for a more simplified approach. I'm not gonna go through every single line of code here, but I just wanna walk you through the process I used to create all my NFT graphics from scratch. 1st, you can see I have a directory called layers that contains a bunch of files like eyes 0, eyes 1, eyes 2, and so on. This directory contains all the possible layers that we would use in an image. From there, I have a file named index.js. Inside of I have an SVG template. I'm using scalable vector graphics here, but I've seen other implementations that just use PNGs. Now each layer in our layers directory as an SVG, so all we have to do is grab the main content from that file and replace each one of these comments with the corresponding traffic like head, hair, eyes, nose, mouth, and beard. In order to do that, I'm using Node. Js to read one of our layer files and then use some regex to grab of the content inside the SVG tags. Then I have a function called create image that will generate a bunch of random numbers and combine them together into an array. I've made this a recursive function that checks to see if that combination has already been taken, in which case it will try running the randomization again. If it is a valid combination, We'll go ahead and replace all the comments in the SVG template with the actual layers from our layers directory. Now, in addition to creating in image. We're also going to create a JSON file with some metadata about it. This metadata is really important because it contains the name of the file as well as a link to its actual image on the interplanetary file system. That represents a unique file upload that cannot be modified. In addition, if the metadata contains attributes of the different traits in the image. Generally, when making an NFT collection, each trait has a different level of rarity. The more rare rates an NFT has, the more valuable it tends to be, thanks to the magic of artificial scarcity. Now, I'll go ahead and write these files to my file system and as an added touch, I'm also burning the SVG to a PNG file as well. I'm using a node package called Sharp to make that possible. And finally, to run the script, I just have a while loop that calls the create image function for the number of images that I want to create. And now when we run the script with node, we get this out directory with a bunch of files that contain both the raw images and JSON for each individual graphic. That takes care of phase 1. We can now generate 1,000 or even millions of individual graphics by simply adding more layers to the layers directory, but keep in mind that my implementation is very crude. There's a lot of optimizations we could make or better yet, we could have used a pre built solution out there to get this job done much faster. Now the next thing we need to think about is how to get these files on the Internet and connect them to a non fungible token. The actual image data and JSON for the NFT t is too big to be efficiently stored on the blockchain. So instead, we store it off chain on the interplanetary file system, which is a decentralized file system in the cloud very similar to BitTorrent. One very important concern that IPFS handles is content addressability. Anytime you upload a file, it creates a unique identifier for at upload, and that allows us to verify the authenticity of any graphics associated to an NFT. Once a file has been uploaded, you can't modify it without changing its content identifier. That means when minting an NFT, the only thing we actually need to store is a link to that file's content identifier. Now the question becomes, How do we take our raw files and upload them to IPFS? There are many ways to go about it, but an easy free solution that I've been using is of it. It's very similar to something like Dropbox where you simply click a button to upload and choose a file from your file system, and you can even host an entire static website from Yotta. It also has a node SDK to upload programmatically, but we're not going to worry about it in this video. I'm just going to upload a few of our images here, and you'll notice when I that it creates a content identifier. Conveniently, we can upload an entire directory all at once. I'm gonna go ahead and upload a few of the graphics that I just generated. For this tutorial, You can upload any random file. It doesn't really matter. And now, we're ready to build a full stack web 3 application using Solidity, Hardhat, and React. The first thing I'm doing here is generating a new React app using Vite. It really doesn't matter which front end framework you use here, but the vast majority of web 3 demos out there use React. That Gives us a front end application. Now we're going to run npx hardhat, which will add a variety of tools to our project to add a blockchain back end. You'll notice it generates a directory for contracts, which contains files written in Solidity, which contains the smart contract code that will interact with the blockchain. It also creates a directory named scripts that contains the code to deploy those contracts to the blockchain. Now there's a couple of configuration things we'll need to do here. In the hardhat config file, We'll update the paths option to create any artifacts in the source directory for the React application. That allows React to access information about the smart contracts. When you compile of smart contract. It creates what's known as an application binary interface, which is basically a middleman that allows your front end JavaScript code to communicate with the smart contract compiled to machine code and all that information lives in the our contract compiled to machine code, and all that information lives in the artifacts directory. From there, we're going to install a bunch of dependencies with npm, like Waffle for automated testing and ethers to interact with smart contracts in the browser and also a tool called OpenZeppelin, which provides templates for quickly building industry standard smart contracts. At this point, I want to focus on writing a smart contract. Its purpose is to accept a payment from a user, then mint a non fungible token and transfer it to that user's wallet. It's important to point out that the code in the smart contract will not actually generate random rates for the NFT images. It's actually extremely difficult to handle randomness in a smart contract. Most NFT collections don't deal with it at all, and instead, they just generate all the images at once, upload them to IPFS, and then mint them after the fact. At which point, they get sold on a secondary market, or you might code up another contract to create your own secondary market. Now it is possible to implement randomness in a smart contract, and if that's what you wanna do, I would highly recommend looking into something like Chainlink. We're going to take the easy approach in this video where the smart contract takes the IPFS URL for the metadata along with some Ethereum and mints a new token from it. To handle that requirement, we'll need to learn a new programming language called Solidity. In the contract x directory. Let's go ahead and create a file ending in dot s o l. Now, we could implement a smart contract from scratch, but that would be a pretty big undertaking on its own. Luckily, there's a tool called in Zeppelin, and it has a wizard that we can use to automatically generate reliable code for us. The Ethereum ecosystem already has a variety of standard interfaces to handle requirements commonly implemented in smart contracts. Like ERC 20 is what you would use to create a fungible token, like if you wanted to create your own coin on the Ethereum network. But to create a non fungible token, we want to use the ERC 721 standard. Before we customize it, you'll notice that there is API documentation with a handful of methods built into the base contract, like balance of to check the owner's balance or owner of to to see who owns a token, as well as methods to transfer tokens from one user to another. Now let's go over to the open Zeppelin wizard to customize our own ERC 721 contract. Most importantly, we need to be able to mint our own tokens. If we check the box for mint, it adds a new method to the contract that allows a privileged account to mint or create a new token. Let's also auto increment IDs and then check the box for URI storage. URI storage allows us to associate and upload on IPFS when this token is minted. Remember, that's the reference to the metadata that we uploaded on pinata earlier. We'll also wanna use a base URI here that points to of PFS to ensure that the URI is properly formatted. That gives us a base contract to work with and you'll notice a button here to open up in the Remix IDE. I'm not going to do it in this video, but Remix is a browser based IDE that makes it really easy to compile and test your smart on tracks. What we're going to do is copy and paste this code and bring it directly into the solidity file that we created. We could use this contract as is, but we want to extend it with some additional code that allows anybody to mint a token as long as they transfer the appropriate amount of Ethereum along with it. Currently, you'll notice a safe mint method that allows the owner of the contract to mint a new token. What we wanna do is create a new function called pay to mint that takes a recipient and metadata a content ID, then mint a new token with that data. Now in order to implement this function, we'll wanna make sure that the same URI can't be minted twice. And to validate that, I'm creating a mapping of Strings to integers to keep track of the existing URIs that have been minted. We might also want to check if an existing URI is already owned, so I'm creating another function called is content owned that takes a URI as its argument and returns true if that URI already exists in the happening. Now, we have everything in place to implement the paydement function. You'll notice that it's marked as a payable function, which means that somebody can transfer money into the contract. Tracked. Now, we can use the require keyword to run some validation. And, keep in mind that this is not a production ready contract. My goal is just to show you how some of the basic mechanics in Solidity work. With require, we first pass a condition. In this case, we want to know if the URI has already been minted. If it has not been minted, the function will continue executing. Otherwise, it will throw an error saying the NFT has already been minted. The next thing we wanna validate is that the user has paid enough ether. There's a global variable of message, and its value property contains the amount of ether being sent into the contract. We can make sure that the minimum value is greater than 0.05. Otherwise, we'll throw an error saying the user needs to pay up. From there, we'll want to create a new item ID. With the counter implemented by OpenZeppelin, it will increment each new token by 1. So it starts at 0 then goes to 1, 2, 3, and so on. After incrementing the counter, we'll update our mapping of the existing URI's, then we call the built in mint method with the recipient's wallet address, and finally, we set the token URI on that ID. That's how someone can pay to mint a new token. And as one final touch, I'm also going to add A function here to get the current count, so we can know exactly how many tokens have been minted so far. And that completes the Solidity code for our back end. At this point, you may want to just jump straight into building a web 3 application, but I would highly recommend that you do some testing first. Hardhat already has a sample test ready to go. And the code you write in a test will be very similar, if not identical, to the code that you write in your front end React application. It's much easier to detect bugs and issues in a test than it is in a front end application with all the UI stuff going on. If you've never done test driven development before, I have an entire video on it. In the test, we'll first use ethers to get our contract and then deploy it. Once deployed, we'll then need a wallet address with some ether in it for testing. Luckily, we can use a fake wallet with 10,000 ether in it already by going to the terminal and running npx hardhat node. This creates a mock network on localhost and provides us with a bunch of fake accounts to used for testing. Copy one of the public keys and use it in your test. At this point, we can start calling the methods on the deployed smart contract. First, I'll create a variable called balance that checks the current balance of the recipient's wallet address. Balance of is a method built into the ERC 721 spec. Now Now currently, the user hasn't purchased any NFTs, so we expect the balance to equal 0. Now from there, we'll create another variable called newly minted token that calls the payment method that we defined on the smart contract. It takes the recipient and metadata URI as arguments, and then we can also define the message value as 0.05 ether. For fun, let's go ahead and set the ether value to 0.01. Now go to the terminal and run npx hardhat test. What you'll notice is that we get a failing test, and you'll see the error message here that the user needs to pay up. Let's go ahead and fix that, and then we'll wait for the newly minted token to be mined by calling the wait method on it. From there, we can query the balance again, and this time we expect it to equal 1. In addition, we can test our is content owned method by making sure that that metadata URI is equal to true. And there are all kinds of other things we could test here, but you get the general idea. If you test all your smart contract logic first, It'll make the front end development much easier. Now, we're ready to move on to the next phase, where we build a web 3 application that interacts with a smart contract from a website. Let's 1st, go into the sample script provided by HardHat. This script is used to compile the contract, which will populate the artifacts directory with all the information we need to interact with like the ABI I talked about earlier. We'll want to update the default values with the name of the custom contract that we created. You'll want to first make sure you have opened running the npx hardhat node command. This should always be running in the background. From there, we can open up a separate terminal and run npx hard at compile. This runs the solidity compiler to convert your code into binary. Once that's done, we can run npx hard hat run scripts, sample script, and specify the network as local host. That will take the contract and deploy it to the actual network. And now we have a smart contract running on our local Sheen. Now when it comes to web 3, the way end users interact with a smart contract is typically with a browser plugin like Metamask. For development, You'll want to set up MetaMask with one of the testing addresses provided by Hardhat. If you don't have it yet, install MetaMask and then go to the local host network and import a new account. It will ask you for a private key, which you can simply copy from the terminal output. And now we're ready to start writing some React code. In order for a user to mint an NFT on the website. They'll need to have MetaMask installed. We'll need to check that at runtime and have 2 different screens based on whether or not installed. I'm creating 2 different components here, one called home and one called install. And in the install component, we'll simply have a link to the MetaMask plug in. Now in the main app component, we can check to see if the user has a plug in installed by checking the window ethereum object. A plug in like Metamask will make this object available automatically when it's installed. Now the next thing I'll do is create a new component called wallet balance. And inside of it, We can start interacting with ethers. Js, which is a JavaScript library that makes it easy to communicate between the smart contract and in end user's wallet. In this component, what we wanna do is get the end user's current balance. We'll first set up state with the use state hook and then define a function called GitBalance. We can get the connected account on the window Ethereum object and then we use ethers. Js to create a new web 3 provider. The provider provides all kinds of or methods for interacting with the Blockchain. One of which is getBalance, which then takes the account as its argument. That will return the wallet balance of the connected account, which should be 10,000 ether, but it's in a big number format. So ethers also provides a utility to format the ether value, which we can use when setting the balance on on the component. And now we can call this function when a button is clicked and show the balance value in the UI. Now let's go ahead and declare the wallet balance component in the main component and then we can serve the app locally by running npm run dev. I've also added Bootstrap to my project to make things look a little nicer, but the end result should of a button that, when clicked, updates the balance in the UI. That's how we can use Ethers to interact with the wallet, but now how do we interact with the smart contract? We'll first need to import the contract ABI from the artifacts directory. Now earlier, when you compiled your contract and ran the sample script, it should have said contract deployed to an address in the terminal. Let's go ahead and take that contract address and set it up as a global variable here in our code. We can then instantiate a web 3 provider again and use it to get the signer to execute transactions on the blockchain. From there, we can use ethers to instantiate the contract using the address, the ABI and the signer. What we wanna do next is loop over all of the NFT images in the collection. Each one of those images will have a button to mint it. Or if it's already been minted, the owner can view the token URI for the NFT. We'll first need to know how many tokens have already been minted, and to do that, I'm setting up a function here called get count that calls the contract count method that we implemented in solidity earlier. We'll then call this function when the component is first initialized with the useEffect hook. In the JSX, I'm looping over every token that's been minted so far. For each one of those items, I'm rendering a a component called nft image that takes the index as a prop, which conveniently matches the token ID. Now, in the nft image component, I'm adding a property for the content ID. This content ID comes from pinata. Remember, I uploaded all my graphics to a folder in pinata. We can combine the content ID with the token ID to reference that JSON metadata URI. Now, when it comes to the actual image, I tried to use that pinata cloud gateway, but I didn't Find this to be very reliable. I often had broken images, so currently, I'm referencing my images here locally. Now, as we loop over these images, we need to figure out if each metadata URI I has been minted yet. For that, I'm going to set up state on the component of isMinted and then define a function called getMintedStatus that will run the is content own method on the smart contract itself, and then we'll run that function with the useEffect hook. And now we've reached the point where we can actually mint the token. I'm creating another function to handle that, and inside the body, the first thing it will do is make a connection between the contract and the signer. That will give us access to the recipient's to wallet address. We then call the pay to mint method on the smart contract and pass the address as well as the metadata URI as arguments. In addition, we need to set the value of ether that the user will pay. For that, we pass an object with a value of the amount of ether, which in this case will be 0.05. You may notice how this code is basically identical all to the code we wrote in our unit test earlier. From there, we can wait for the result to be mined, after which point we can call that get minted status function again, and this time it should say that metadata URI has been minted. Now, it's just a matter of using some conditional logic in the JSX to show the image URI if it's already been minted. Otherwise, we'll just show a mystery placeholder and then we'll also show the option to mint the token if it's not already minted. Otherwise, it will say that NFT is taken. Now at this point, if all went well, you should be able to go to the application and When you click the mint button, it will bring up MetaMask confirming that you want to transfer 0.05 ether and will then complete the transaction after you confirm of it. Congratulations, you just built a basic web 3 app. Let's take a quick break to appreciate it. It's Britney, bitch. Now we can move on to phase 7, deployment. This app is by no means production ready and would cost a lot of money to deploy it to the Ethereum mainnet. But one thing we can do is deploy it to a testnet to see how it would work in the real world. A free tool that can help us do that is Alchemy. The majority of serious web 3 applications use tools like Alchemy and Infura, which are platforms that can help make decentralized apps more reliable. What we're going to do is use Alchemy to deploy our contract to a test net. When you create an account, it will give you the option to create a new application, and I'm going to use the Polygon chain with the Polygon Mumbai network. Polygon, by the way, is a blockchain built on top of Ethereum that is faster unless expensive. Its native token, MATIC, is very similar to ether. For this tutorial, you can think of MATIC and ether as being the same basic thing. Once the app is created, you'll notice it gives you a link to the network. Go ahead and copy that. Now go back to the hardhat config file in your source code. You'll need a new entry under networks, which in this case will be Matic, and point it to the URL that you just copied. The other thing you'll need is a private key for your account. Go over to MetaMask and switch the network to Mumbai, then from the menu, click account details and export your private key, then paste it into the hardhat config. The reason you need a private key here is because this account will be the one that deploys the contract, but deploying a contract isn't free and currently there is 0 MATIC in as wallet. To get some free test money, we'll need to go to the Polygon faucet and add our public wallet address there, and after a few minutes of waiting, you should magically see some MATIC appear in your wallet. And now we're ready for the moment of truth. From the terminal, run the hardhat deploy script again, but this time make sure the network option is set to HANA. That should deploy the contract to the Mumbai network, make sure to copy the address and update it in your front end code in the main dot JSX file. You now have a web 3 application running out in the wild, and you could follow the same basic process to deploy to the main net. I'm gonna go ahead and wrap things up there. Hopefully, that gives you a general idea of all the steps involved in building a dApp. The final thing I'll mention is that if you want to purchase these n f t's yourself, you can do so on OpenSea. E. I don't know why you ever would, but they're there if you want them. Thanks for watching, and I will see you in the next one.
In
in
today's
today's
video,
video
we'll
we'll
build
build
a
a
complete
complete
web
web
3
3
application
application
step
step
by
by
step
step
from
from
scratch
scratch
and
and
in
in
the
the
process,
process
we'll
we'll
talk
talk
about
about
the
the
good
good
and
and
bad
bad
aspects
aspects
of
of
developing
developing
decentralized
decentralized
web
web
apps
apps
on
on
the
the
blockchain.
blockchain
You
you
may
may
have
have
seen
seen
the
the
headlines
headlines
of
of
kids
kids
making
making
1,000,000
1,000,000
of
of
dollars
dollars
overnight
overnight
by
by
selling
selling
digital
digital
art
art
in
in
the
the
form
form
of
of
NFTs.
nfts
If
if
you're
you're
like
like
me
me
and
and
not
not
already
already
an
an
NFT
nft
millionaire.
millionaire
You
you
likely
likely
have
have
some
some
FOMO
fomo
about
about
this
this
whole
whole
trend.
trend
You
you
could
could
point
point
out
out
how
how
NFTs
nfts
are
are
dumb,
dumb
pointless,
pointless
and
and
bad
bad
for
for
the
the
environment,
environment
or
or
you
you
could
could
try
try
to
to
get
get
in
in
on
on
the
the
trend
trend
yourself,
yourself
and
and
that's
that's
exactly
exactly
what
what
we'll
we'll
do
do
in
in
this
this
video.
video
I'll
i'll
show
show
you
you
how
how
I
i
created
created
a
a
collection
collection
of
of
20,000
20,000
unique
unique
graphics
graphics
with
with
some
some
crappy
crappy
artwork
artwork
I
i
drew
drew
by
by
hand
hand
in
in
a
a
few
few
minutes.
minutes
We'll
we'll
then
then
take
take
that
that
artwork
artwork
and
and
upload
upload
it
it
to
to
the
the
interplanetary
interplanetary
file
file
system.
system
At
at
which
which
point,
point
we
we
can
can
write
write
a
a
smart
smart
contract
contract
with
with
Solidity
solidity
and
and
OpenZeppelin
openzeppelin
that
that
will
will
mint
mint
a
a
new
new
NFT
nft
whenever
whenever
somebody
somebody
transfers
transfers
Ethereum
ethereum
to
to
the
the
smart
smart
contract.
contract
And
and
finally,
finally
we'll
we'll
use
use
ethers.
ethers
Js
js
with
with
React
react
to
to
build
build
a
a
web
web
3
3
application
application
that
that
provides
provides
a
a
front
front
end
end
interface
interface
where
where
people
people
can
can
actually
actually
interact
interact
of
of
a
a
smart
smart
contract.
contract
By
by
the
the
end
end
of
of
this
this
tutorial,
tutorial
you'll
you'll
understand
understand
the
the
complete
complete
process
process
of
of
going
going
from
from
0
0
to
to
a
a
web
web
3
3
point
point
o
o
NFT
nft
application.
application
This
this
tutorial
tutorial
is
is
longer
longer
than
than
most
most
on
on
this
this
channel
channel
and
and
it's
it's
broken
broken
down
down
into
into
7
7
phases.
phases
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe
subscribe
and
and
follow
follow
along
along
with
with
the
the
full
full
tutorial
tutorial
on
on
Fireship
fireship
biome.
biome
And
and
if
if
you
you
wanna
wanna
see
see
more
more
web
web
3
3
content,
content
let
let
me
me
know
know
in
in
the
the
comments.
comments
Before
before
we
we
get
get
started,
started
let's
let's
first
first
answer
answer
the
the
question
question
of
of
what
what
is
is
an
an
NFT
nft
collection.
collection
A
a
nonfudgeable
nonfudgeable
token
token
is
is
a
a
unique
unique
digital
digital
asset.
asset
Usually,
usually
it
it
represents
represents
a
a
piece
piece
of
of
artwork
artwork
like
like
an
an
image,
image
but
but
it
it
can
can
also
also
represent
represent
things
things
like
like
domain
domain
names
names
and
and
physical
physical
items
items
in
in
the
the
real
real
world,
world
but
but
you'll
you'll
often
often
see
see
NFTs
nfts
packaged
packaged
in
in
a
a
collection
collection
like
like
CryptoPunks,
cryptopunks
Bored
bored
Ape
ape
Yacht
yacht
Club,
club
and
and
doodles
doodles
just
just
to
to
name
name
a
a
few.
few
These
these
graphics
graphics
are
are
created
created
with
with
a
a
few
few
base
base
layers,
layers
like
like
hair,
hair
eyes,
eyes
clothing,
clothing
and
and
so
so
on.
on
The
the
layers
layers
are
are
then
then
combined
combined
together
together
randomly
randomly
to
to
create
create
a
a
bunch
bunch
of
of
unique
unique
graphics.
graphics
What's
what's
interesting
interesting
though
though
is
is
that
that
the
the
various
various
traits
traits
and
and
attributes
attributes
have
have
different
different
levels
levels
of
of
rarity.
rarity
When
when
a
a
graphic
graphic
is
is
generated,
generated
it's
it's
less
less
likely
likely
to
to
have
have
one
one
of
of
the
the
rare
rare
traits.
traits
This
this
is
is
actually
actually
really
really
fun
fun
because
because
you
you
can
can
think
think
of
of
a
a
smart
smart
contract
contract
like
like
a
a
vending
vending
machine
machine
in
in
the
the
cloud.
cloud
When
when
an
an
NFT
nft
collection
collection
is
is
first
first
offered,
offered
you
you
can
can
send
send
crypto
crypto
to
to
that
that
wallet
wallet
address.
address
It
it
will
will
mint
mint
a
a
one
one
of
of
a
a
in
in
token
token
and
and
transfer
transfer
it
it
to
to
your
your
wallet.
wallet
If
if
you're
you're
lucky,
lucky
you'll
you'll
get
get
something
something
with
with
a
a
really
really
rare
rare
trait.
trait
It's
it's
not
not
much
much
different
different
than
than
opening
opening
up
up
a
a
pack
pack
of
of
Pokemon
pokemon
cards.
cards
Most
most
of
of
the
the
cards
cards
are
are
very
very
common,
common
but
but
there
there
is
is
a
a
small
small
chance
chance
you'll
you'll
get
get
something
something
that's
that's
very
very
rare
rare
and
and
valuable.
valuable
Now
now
after
after
you
you
purchase
purchase
an
an
NFT,
nft
there's
there's
a
a
secondary
secondary
market
market
where
where
you
you
can
can
resell
resell
it
it
to
to
someone
someone
else
else
on
on
a
a
site
site
like
like
OpenSea.
opensea
Many
many
people
people
invest
invest
in
in
NFTs
nfts
hoping
hoping
to
to
flip
flip
them
them
for
for
a
a
higher
higher
value
value
later
later
on.
on
If
if
you're
you're
the
the
original
original
creator,
creator
you
you
can
can
also
also
configure
configure
your
your
smart
smart
on
on
track
track
to
to
receive
receive
royalty
royalty
payments
payments
whenever
whenever
the
the
NFT
nft
changes
changes
hands
hands
in
in
the
the
future.
future
That's
that's
pretty
pretty
cool,
cool
but
but
there
there
are
are
a
a
lot
lot
of
of
bad
bad
things
things
I
i
could
could
say
say
about
about
web
web
3
3
as
as
well.
well
The
the
guy
guy
who
who
created
created
signal,
signal
an
an
encrypted
encrypted
messaging
messaging
app,
app
created
created
an
an
NFT
nft
that
that
actually
actually
changes
changes
its
its
appearance
appearance
based
based
on
on
where
where
you
you
view
view
it.
it
On
on
OpenSea,
opensea
it
it
looks
looks
really
really
cool,
cool
but
but
in
in
your
your
wallet,
wallet
but
but
it
it
looks
looks
like
like
a
a
piece
piece
of
of
poop.
poop
Because
because
the
the
NFT
nft
image
image
is
is
hosted
hosted
off
off
chain,
chain
he
he
just
just
used
used
a
a
web
web
server
server
to
to
display
display
a
a
different
different
image
image
based
based
on
on
the
the
user
user
agent
agent
that
that
was
was
requesting
requesting
the
the
image.
image
Everybody
everybody
talks
talks
about
about
web
web
3
3
being
being
decentralized
decentralized
and
and
trustless,
trustless
but
but
the
the
reality
reality
is
is
that
that
much
much
of
of
it
it
works
works
thanks
thanks
to
to
centralized
centralized
APIs.
apis
Read
read
his
his
full
full
blog
blog
post
post
to
to
learn
learn
more.
more
At
at
the
the
end
end
of
of
the
the
day,
day
we
we
don't
don't
really
really
care
care
about
about
that
that
we're
we're
just
just
here
here
to
to
have
have
fun,
fun
get
get
some
some
exercise,
exercise
and
and
make
make
a
a
ton
ton
of
of
money.
money
Now
now
we're
we're
ready
ready
to
to
kick
kick
off
off
phase
phase
1
1
of
of
this
this
project,
project
where
where
we
we
create
create
the
the
layers
layers
or
or
graphics
graphics
that
that
we'll
we'll
use
use
for
for
the
the
NFT
nft
collection.
collection
I'm
i'm
not
not
much
much
of
of
an
an
artist
artist
and
and
everything
everything
I
i
draw
draw
tends
tends
to
to
look
look
really
really
creepy.
creepy
Not
not
much
much
I
i
can
can
do
do
about
about
that,
that
so
so
I'm
i'm
just
just
gonna
gonna
own
own
it.
it
Believe
believe
it
it
or
or
not,
not
creating
creating
NFT
nft
artwork
artwork
is
is
an
an
art
art
form.
form
I
i
I
i
find
find
it
it
really
really
satisfying
satisfying
because
because
you
you
can
can
take
take
a
a
few
few
basic
basic
images
images
and
and
use
use
them
them
to
to
create
create
thousands
thousands
of
of
different
different
unique
unique
combinations.
combinations
For
for
my
my
NFT
nft
collection,
collection
I
i
actually
actually
used
used
a
a
pen
pen
and
and
paper
paper
to
to
draw
draw
everything
everything
by
by
hand.
hand
I
i
then
then
digitized
digitized
it
it
and
and
brought
brought
each
each
individual
individual
layer
layer
into
into
Figma.
figma
As
as
you
you
can
can
see
see
here,
here
I
i
have
have
different
different
categories
categories
for
for
the
the
various
various
traits,
traits
like
like
hair,
hair
eyes,
eyes
nose,
nose
mouth,
mouth
beard,
beard
and
and
so
so
on.
on
From
from
there,
there
I
i
created
created
a
a
little
little
script
script
in
in
Node.
node
Js
js
that
that
randomly
randomly
combines
combines
these
these
layers
layers
together.
together
You
you
can
can
find
find
the
the
source
source
code
code
on
on
GitHub,
github
but
but
there
there
are
are
many
many
existing
existing
tools
tools
out
out
there
there
that
that
can
can
help
help
you
you
generate
generate
in
in
NFT
nft
collection
collection
without
without
needing
needing
to
to
write
write
any
any
code.
code
If
if
you're
you're
looking
looking
for
for
a
a
tutorial
tutorial
that
that
doesn't
doesn't
require
require
any
any
code,
code
this
this
is
is
not
not
the
the
video
video
for
for
you.
you
If
if
your
your
goal
goal
is
is
to
to
just
just
create
create
a
a
bunch
bunch
of
of
images
images
and
and
sell
sell
them
them
as
as
NFTs.
nfts
I'd
i'd
recommend
recommend
checking
checking
out
out
this
this
recent
recent
tutorial
tutorial
from
from
Code
code
Stacker
stacker
for
for
a
a
more
more
simplified
simplified
approach.
approach
I'm
i'm
not
not
gonna
gonna
go
go
through
through
every
every
single
single
line
line
of
of
code
code
here,
here
but
but
I
i
just
just
wanna
wanna
walk
walk
you
you
through
through
the
the
process
process
I
i
used
used
to
to
create
create
all
all
my
my
NFT
nft
graphics
graphics
from
from
scratch.
scratch
1st,
1st
you
you
can
can
see
see
I
i
have
have
a
a
directory
directory
called
called
layers
layers
that
that
contains
contains
a
a
bunch
bunch
of
of
files
files
like
like
eyes
eyes
0,
0
eyes
eyes
1,
1
eyes
eyes
2,
2
and
and
so
so
on.
on
This
this
directory
directory
contains
contains
all
all
the
the
possible
possible
layers
layers
that
that
we
we
would
would
use
use
in
in
an
an
image.
image
From
from
there,
there
I
i
have
have
a
a
file
file
named
named
index.js.
index.js
Inside
inside
of
of
I
i
have
have
an
an
SVG
svg
template.
template
I'm
i'm
using
using
scalable
scalable
vector
vector
graphics
graphics
here,
here
but
but
I've
i've
seen
seen
other
other
implementations
implementations
that
that
just
just
use
use
PNGs.
pngs
Now
now
each
each
layer
layer
in
in
our
our
layers
layers
directory
directory
as
as
an
an
SVG,
svg
so
so
all
all
we
we
have
have
to
to
do
do
is
is
grab
grab
the
the
main
main
content
content
from
from
that
that
file
file
and
and
replace
replace
each
each
one
one
of
of
these
these
comments
comments
with
with
the
the
corresponding
corresponding
traffic
traffic
like
like
head,
head
hair,
hair
eyes,
eyes
nose,
nose
mouth,
mouth
and
and
beard.
beard
In
in
order
order
to
to
do
do
that,
that
I'm
i'm
using
using
Node.
node
Js
js
to
to
read
read
one
one
of
of
our
our
layer
layer
files
files
and
and
then
then
use
use
some
some
regex
regex
to
to
grab
grab
of
of
the
the
content
content
inside
inside
the
the
SVG
svg
tags.
tags
Then
then
I
i
have
have
a
a
function
function
called
called
create
create
image
image
that
that
will
will
generate
generate
a
a
bunch
bunch
of
of
random
random
numbers
numbers
and
and
combine
combine
them
them
together
together
into
into
an
an
array.
array
I've
i've
made
made
this
this
a
a
recursive
recursive
function
function
that
that
checks
checks
to
to
see
see
if
if
that
that
combination
combination
has
has
already
already
been
been
taken,
taken
in
in
which
which
case
case
it
it
will
will
try
try
running
running
the
the
randomization
randomization
again.
again
If
if
it
it
is
is
a
a
valid
valid
combination,
combination
We'll
we'll
go
go
ahead
ahead
and
and
replace
replace
all
all
the
the
comments
comments
in
in
the
the
SVG
svg
template
template
with
with
the
the
actual
actual
layers
layers
from
from
our
our
layers
layers
directory.
directory
Now,
now
in
in
addition
addition
to
to
creating
creating
in
in
image.
image
We're
we're
also
also
going
going
to
to
create
create
a
a
JSON
json
file
file
with
with
some
some
metadata
metadata
about
about
it.
it
This
this
metadata
metadata
is
is
really
really
important
important
because
because
it
it
contains
contains
the
the
name
name
of
of
the
the
file
file
as
as
well
well
as
as
a
a
link
link
to
to
its
its
actual
actual
image
image
on
on
the
the
interplanetary
interplanetary
file
file
system.
system
That
that
represents
represents
a
a
unique
unique
file
file
upload
upload
that
that
cannot
cannot
be
be
modified.
modified
In
in
addition,
addition
if
if
the
the
metadata
metadata
contains
contains
attributes
attributes
of
of
the
the
different
different
traits
traits
in
in
the
the
image.
image
Generally,
generally
when
when
making
making
an
an
NFT
nft
collection,
collection
each
each
trait
trait
has
has
a
a
different
different
level
level
of
of
rarity.
rarity
The
the
more
more
rare
rare
rates
rates
an
an
NFT
nft
has,
has
the
the
more
more
valuable
valuable
it
it
tends
tends
to
to
be,
be
thanks
thanks
to
to
the
the
magic
magic
of
of
artificial
artificial
scarcity.
scarcity
Now,
now
I'll
i'll
go
go
ahead
ahead
and
and
write
write
these
these
files
files
to
to
my
my
file
file
system
system
and
and
as
as
an
an
added
added
touch,
touch
I'm
i'm
also
also
burning
burning
the
the
SVG
svg
to
to
a
a
PNG
png
file
file
as
as
well.
well
I'm
i'm
using
using
a
a
node
node
package
package
called
called
Sharp
sharp
to
to
make
make
that
that
possible.
possible
And
and
finally,
finally
to
to
run
run
the
the
script,
script
I
i
just
just
have
have
a
a
while
while
loop
loop
that
that
calls
calls
the
the
create
create
image
image
function
function
for
for
the
the
number
number
of
of
images
images
that
that
I
i
want
want
to
to
create.
create
And
and
now
now
when
when
we
we
run
run
the
the
script
script
with
with
node,
node
we
we
get
get
this
this
out
out
directory
directory
with
with
a
a
bunch
bunch
of
of
files
files
that
that
contain
contain
both
both
the
the
raw
raw
images
images
and
and
JSON
json
for
for
each
each
individual
individual
graphic.
graphic
That
that
takes
takes
care
care
of
of
phase
phase
1.
1
We
we
can
can
now
now
generate
generate
1,000
1,000
or
or
even
even
millions
millions
of
of
individual
individual
graphics
graphics
by
by
simply
simply
adding
adding
more
more
layers
layers
to
to
the
the
layers
layers
directory,
directory
but
but
keep
keep
in
in
mind
mind
that
that
my
my
implementation
implementation
is
is
very
very
crude.
crude
There's
there's
a
a
lot
lot
of
of
optimizations
optimizations
we
we
could
could
make
make
or
or
better
better
yet,
yet
we
we
could
could
have
have
used
used
a
a
pre
pre
built
built
solution
solution
out
out
there
there
to
to
get
get
this
this
job
job
done
done
much
much
faster.
faster
Now
now
the
the
next
next
thing
thing
we
we
need
need
to
to
think
think
about
about
is
is
how
how
to
to
get
get
these
these
files
files
on
on
the
the
Internet
internet
and
and
connect
connect
them
them
to
to
a
a
non
non
fungible
fungible
token.
token
The
the
actual
actual
image
image
data
data
and
and
JSON
json
for
for
the
the
NFT
nft
t
t
is
is
too
too
big
big
to
to
be
be
efficiently
efficiently
stored
stored
on
on
the
the
blockchain.
blockchain
So
so
instead,
instead
we
we
store
store
it
it
off
off
chain
chain
on
on
the
the
interplanetary
interplanetary
file
file
system,
system
which
which
is
is
a
a
decentralized
decentralized
file
file
system
system
in
in
the
the
cloud
cloud
very
very
similar
similar
to
to
BitTorrent.
bittorrent
One
one
very
very
important
important
concern
concern
that
that
IPFS
ipfs
handles
handles
is
is
content
content
addressability.
addressability
Anytime
anytime
you
you
upload
upload
a
a
file,
file
it
it
creates
creates
a
a
unique
unique
identifier
identifier
for
for
at
at
upload,
upload
and
and
that
that
allows
allows
us
us
to
to
verify
verify
the
the
authenticity
authenticity
of
of
any
any
graphics
graphics
associated
associated
to
to
an
an
NFT.
nft
Once
once
a
a
file
file
has
has
been
been
uploaded,
uploaded
you
you
can't
can't
modify
modify
it
it
without
without
changing
changing
its
its
content
content
identifier.
identifier
That
that
means
means
when
when
minting
minting
an
an
NFT,
nft
the
the
only
only
thing
thing
we
we
actually
actually
need
need
to
to
store
store
is
is
a
a
link
link
to
to
that
that
file's
file's
content
content
identifier.
identifier
Now
now
the
the
question
question
becomes,
becomes
How
how
do
do
we
we
take
take
our
our
raw
raw
files
files
and
and
upload
upload
them
them
to
to
IPFS?
ipfs
There
there
are
are
many
many
ways
ways
to
to
go
go
about
about
it,
it
but
but
an
an
easy
easy
free
free
solution
solution
that
that
I've
i've
been
been
using
using
is
is
of
of
it.
it
It's
it's
very
very
similar
similar
to
to
something
something
like
like
Dropbox
dropbox
where
where
you
you
simply
simply
click
click
a
a
button
button
to
to
upload
upload
and
and
choose
choose
a
a
file
file
from
from
your
your
file
file
system,
system
and
and
you
you
can
can
even
even
host
host
an
an
entire
entire
static
static
website
website
from
from
Yotta.
yotta
It
it
also
also
has
has
a
a
node
node
SDK
sdk
to
to
upload
upload
programmatically,
programmatically
but
but
we're
we're
not
not
going
going
to
to
worry
worry
about
about
it
it
in
in
this
this
video.
video
I'm
i'm
just
just
going
going
to
to
upload
upload
a
a
few
few
of
of
our
our
images
images
here,
here
and
and
you'll
you'll
notice
notice
when
when
I
i
that
that
it
it
creates
creates
a
a
content
content
identifier.
identifier
Conveniently,
conveniently
we
we
can
can
upload
upload
an
an
entire
entire
directory
directory
all
all
at
at
once.
once
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
upload
upload
a
a
few
few
of
of
the
the
graphics
graphics
that
that
I
i
just
just
generated.
generated
For
for
this
this
tutorial,
tutorial
You
you
can
can
upload
upload
any
any
random
random
file.
file
It
it
doesn't
doesn't
really
really
matter.
matter
And
and
now,
now
we're
we're
ready
ready
to
to
build
build
a
a
full
full
stack
stack
web
web
3
3
application
application
using
using
Solidity,
solidity
Hardhat,
hardhat
and
and
React.
react
The
the
first
first
thing
thing
I'm
i'm
doing
doing
here
here
is
is
generating
generating
a
a
new
new
React
react
app
app
using
using
Vite.
vite
It
it
really
really
doesn't
doesn't
matter
matter
which
which
front
front
end
end
framework
framework
you
you
use
use
here,
here
but
but
the
the
vast
vast
majority
majority
of
of
web
web
3
3
demos
demos
out
out
there
there
use
use
React.
react
That
that
Gives
gives
us
us
a
a
front
front
end
end
application.
application
Now
now
we're
we're
going
going
to
to
run
run
npx
npx
hardhat,
hardhat
which
which
will
will
add
add
a
a
variety
variety
of
of
tools
tools
to
to
our
our
project
project
to
to
add
add
a
a
blockchain
blockchain
back
back
end.
end
You'll
you'll
notice
notice
it
it
generates
generates
a
a
directory
directory
for
for
contracts,
contracts
which
which
contains
contains
files
files
written
written
in
in
Solidity,
solidity
which
which
contains
contains
the
the
smart
smart
contract
contract
code
code
that
that
will
will
interact
interact
with
with
the
the
blockchain.
blockchain
It
it
also
also
creates
creates
a
a
directory
directory
named
named
scripts
scripts
that
that
contains
contains
the
the
code
code
to
to
deploy
deploy
those
those
contracts
contracts
to
to
the
the
blockchain.
blockchain
Now
now
there's
there's
a
a
couple
couple
of
of
configuration
configuration
things
things
we'll
we'll
need
need
to
to
do
do
here.
here
In
in
the
the
hardhat
hardhat
config
config
file,
file
We'll
we'll
update
update
the
the
paths
paths
option
option
to
to
create
create
any
any
artifacts
artifacts
in
in
the
the
source
source
directory
directory
for
for
the
the
React
react
application.
application
That
that
allows
allows
React
react
to
to
access
access
information
information
about
about
the
the
smart
smart
contracts.
contracts
When
when
you
you
compile
compile
of
of
smart
smart
contract.
contract
It
it
creates
creates
what's
what's
known
known
as
as
an
an
application
application
binary
binary
interface,
interface
which
which
is
is
basically
basically
a
a
middleman
middleman
that
that
allows
allows
your
your
front
front
end
end
JavaScript
javascript
code
code
to
to
communicate
communicate
with
with
the
the
smart
smart
contract
contract
compiled
compiled
to
to
machine
machine
code
code
and
and
all
all
that
that
information
information
lives
lives
in
in
the
the
our
our
contract
contract
compiled
compiled
to
to
machine
machine
code,
code
and
and
all
all
that
that
information
information
lives
lives
in
in
the
the
artifacts
artifacts
directory.
directory
From
from
there,
there
we're
we're
going
going
to
to
install
install
a
a
bunch
bunch
of
of
dependencies
dependencies
with
with
npm,
npm
like
like
Waffle
waffle
for
for
automated
automated
testing
testing
and
and
ethers
ethers
to
to
interact
interact
with
with
smart
smart
contracts
contracts
in
in
the
the
browser
browser
and
and
also
also
a
a
tool
tool
called
called
OpenZeppelin,
openzeppelin
which
which
provides
provides
templates
templates
for
for
quickly
quickly
building
building
industry
industry
standard
standard
smart
smart
contracts.
contracts
At
at
this
this
point,
point
I
i
want
want
to
to
focus
focus
on
on
writing
writing
a
a
smart
smart
contract.
contract
Its
its
purpose
purpose
is
is
to
to
accept
accept
a
a
payment
payment
from
from
a
a
user,
user
then
then
mint
mint
a
a
non
non
fungible
fungible
token
token
and
and
transfer
transfer
it
it
to
to
that
that
user's
user's
wallet.
wallet
It's
it's
important
important
to
to
point
point
out
out
that
that
the
the
code
code
in
in
the
the
smart
smart
contract
contract
will
will
not
not
actually
actually
generate
generate
random
random
rates
rates
for
for
the
the
NFT
nft
images.
images
It's
it's
actually
actually
extremely
extremely
difficult
difficult
to
to
handle
handle
randomness
randomness
in
in
a
a
smart
smart
contract.
contract
Most
most
NFT
nft
collections
collections
don't
don't
deal
deal
with
with
it
it
at
at
all,
all
and
and
instead,
instead
they
they
just
just
generate
generate
all
all
the
the
images
images
at
at
once,
once
upload
upload
them
them
to
to
IPFS,
ipfs
and
and
then
then
mint
mint
them
them
after
after
the
the
fact.
fact
At
at
which
which
point,
point
they
they
get
get
sold
sold
on
on
a
a
secondary
secondary
market,
market
or
or
you
you
might
might
code
code
up
up
another
another
contract
contract
to
to
create
create
your
your
own
own
secondary
secondary
market.
market
Now
now
it
it
is
is
possible
possible
to
to
implement
implement
randomness
randomness
in
in
a
a
smart
smart
contract,
contract
and
and
if
if
that's
that's
what
what
you
you
wanna
wanna
do,
do
I
i
would
would
highly
highly
recommend
recommend
looking
looking
into
into
something
something
like
like
Chainlink.
chainlink
We're
we're
going
going
to
to
take
take
the
the
easy
easy
approach
approach
in
in
this
this
video
video
where
where
the
the
smart
smart
contract
contract
takes
takes
the
the
IPFS
ipfs
URL
url
for
for
the
the
metadata
metadata
along
along
with
with
some
some
Ethereum
ethereum
and
and
mints
mints
a
a
new
new
token
token
from
from
it.
it
To
to
handle
handle
that
that
requirement,
requirement
we'll
we'll
need
need
to
to
learn
learn
a
a
new
new
programming
programming
language
language
called
called
Solidity.
solidity
In
in
the
the
contract
contract
x
x
directory.
directory
Let's
let's
go
go
ahead
ahead
and
and
create
create
a
a
file
file
ending
ending
in
in
dot
dot
s
s
o
o
l.
l
Now,
now
we
we
could
could
implement
implement
a
a
smart
smart
contract
contract
from
from
scratch,
scratch
but
but
that
that
would
would
be
be
a
a
pretty
pretty
big
big
undertaking
undertaking
on
on
its
its
own.
own
Luckily,
luckily
there's
there's
a
a
tool
tool
called
called
in
in
Zeppelin,
zeppelin
and
and
it
it
has
has
a
a
wizard
wizard
that
that
we
we
can
can
use
use
to
to
automatically
automatically
generate
generate
reliable
reliable
code
code
for
for
us.
us
The
the
Ethereum
ethereum
ecosystem
ecosystem
already
already
has
has
a
a
variety
variety
of
of
standard
standard
interfaces
interfaces
to
to
handle
handle
requirements
requirements
commonly
commonly
implemented
implemented
in
in
smart
smart
contracts.
contracts
Like
like
ERC
erc
20
20
is
is
what
what
you
you
would
would
use
use
to
to
create
create
a
a
fungible
fungible
token,
token
like
like
if
if
you
you
wanted
wanted
to
to
create
create
your
your
own
own
coin
coin
on
on
the
the
Ethereum
ethereum
network.
network
But
but
to
to
create
create
a
a
non
non
fungible
fungible
token,
token
we
we
want
want
to
to
use
use
the
the
ERC
erc
721
721
standard.
standard
Before
before
we
we
customize
customize
it,
it
you'll
you'll
notice
notice
that
that
there
there
is
is
API
api
documentation
documentation
with
with
a
a
handful
handful
of
of
methods
methods
built
built
into
into
the
the
base
base
contract,
contract
like
like
balance
balance
of
of
to
to
check
check
the
the
owner's
owner's
balance
balance
or
or
owner
owner
of
of
to
to
to
to
see
see
who
who
owns
owns
a
a
token,
token
as
as
well
well
as
as
methods
methods
to
to
transfer
transfer
tokens
tokens
from
from
one
one
user
user
to
to
another.
another
Now
now
let's
let's
go
go
over
over
to
to
the
the
open
open
Zeppelin
zeppelin
wizard
wizard
to
to
customize
customize
our
our
own
own
ERC
erc
721
721
contract.
contract
Most
most
importantly,
importantly
we
we
need
need
to
to
be
be
able
able
to
to
mint
mint
our
our
own
own
tokens.
tokens
If
if
we
we
check
check
the
the
box
box
for
for
mint,
mint
it
it
adds
adds
a
a
new
new
method
method
to
to
the
the
contract
contract
that
that
allows
allows
a
a
privileged
privileged
account
account
to
to
mint
mint
or
or
create
create
a
a
new
new
token.
token
Let's
let's
also
also
auto
auto
increment
increment
IDs
ids
and
and
then
then
check
check
the
the
box
box
for
for
URI
uri
storage.
storage
URI
uri
storage
storage
allows
allows
us
us
to
to
associate
associate
and
and
upload
upload
on
on
IPFS
ipfs
when
when
this
this
token
token
is
is
minted.
minted
Remember,
remember
that's
that's
the
the
reference
reference
to
to
the
the
metadata
metadata
that
that
we
we
uploaded
uploaded
on
on
pinata
pinata
earlier.
earlier
We'll
we'll
also
also
wanna
wanna
use
use
a
a
base
base
URI
uri
here
here
that
that
points
points
to
to
of
of
PFS
pfs
to
to
ensure
ensure
that
that
the
the
URI
uri
is
is
properly
properly
formatted.
formatted
That
that
gives
gives
us
us
a
a
base
base
contract
contract
to
to
work
work
with
with
and
and
you'll
you'll
notice
notice
a
a
button
button
here
here
to
to
open
open
up
up
in
in
the
the
Remix
remix
IDE.
ide
I'm
i'm
not
not
going
going
to
to
do
do
it
it
in
in
this
this
video,
video
but
but
Remix
remix
is
is
a
a
browser
browser
based
based
IDE
ide
that
that
makes
makes
it
it
really
really
easy
easy
to
to
compile
compile
and
and
test
test
your
your
smart
smart
on
on
tracks.
tracks
What
what
we're
we're
going
going
to
to
do
do
is
is
copy
copy
and
and
paste
paste
this
this
code
code
and
and
bring
bring
it
it
directly
directly
into
into
the
the
solidity
solidity
file
file
that
that
we
we
created.
created
We
we
could
could
use
use
this
this
contract
contract
as
as
is,
is
but
but
we
we
want
want
to
to
extend
extend
it
it
with
with
some
some
additional
additional
code
code
that
that
allows
allows
anybody
anybody
to
to
mint
mint
a
a
token
token
as
as
long
long
as
as
they
they
transfer
transfer
the
the
appropriate
appropriate
amount
amount
of
of
Ethereum
ethereum
along
along
with
with
it.
it
Currently,
currently
you'll
you'll
notice
notice
a
a
safe
safe
mint
mint
method
method
that
that
allows
allows
the
the
owner
owner
of
of
the
the
contract
contract
to
to
mint
mint
a
a
new
new
token.
token
What
what
we
we
wanna
wanna
do
do
is
is
create
create
a
a
new
new
function
function
called
called
pay
pay
to
to
mint
mint
that
that
takes
takes
a
a
recipient
recipient
and
and
metadata
metadata
a
a
content
content
ID,
id
then
then
mint
mint
a
a
new
new
token
token
with
with
that
that
data.
data
Now
now
in
in
order
order
to
to
implement
implement
this
this
function,
function
we'll
we'll
wanna
wanna
make
make
sure
sure
that
that
the
the
same
same
URI
uri
can't
can't
be
be
minted
minted
twice.
twice
And
and
to
to
validate
validate
that,
that
I'm
i'm
creating
creating
a
a
mapping
mapping
of
of
Strings
strings
to
to
integers
integers
to
to
keep
keep
track
track
of
of
the
the
existing
existing
URIs
uris
that
that
have
have
been
been
minted.
minted
We
we
might
might
also
also
want
want
to
to
check
check
if
if
an
an
existing
existing
URI
uri
is
is
already
already
owned,
owned
so
so
I'm
i'm
creating
creating
another
another
function
function
called
called
is
is
content
content
owned
owned
that
that
takes
takes
a
a
URI
uri
as
as
its
its
argument
argument
and
and
returns
returns
true
true
if
if
that
that
URI
uri
already
already
exists
exists
in
in
the
the
happening.
happening
Now,
now
we
we
have
have
everything
everything
in
in
place
place
to
to
implement
implement
the
the
paydement
paydement
function.
function
You'll
you'll
notice
notice
that
that
it's
it's
marked
marked
as
as
a
a
payable
payable
function,
function
which
which
means
means
that
that
somebody
somebody
can
can
transfer
transfer
money
money
into
into
the
the
contract.
contract
Tracked.
tracked
Now,
now
we
we
can
can
use
use
the
the
require
require
keyword
keyword
to
to
run
run
some
some
validation.
validation
And,
and
keep
keep
in
in
mind
mind
that
that
this
this
is
is
not
not
a
a
production
production
ready
ready
contract.
contract
My
my
goal
goal
is
is
just
just
to
to
show
show
you
you
how
how
some
some
of
of
the
the
basic
basic
mechanics
mechanics
in
in
Solidity
solidity
work.
work
With
with
require,
require
we
we
first
first
pass
pass
a
a
condition.
condition
In
in
this
this
case,
case
we
we
want
want
to
to
know
know
if
if
the
the
URI
uri
has
has
already
already
been
been
minted.
minted
If
if
it
it
has
has
not
not
been
been
minted,
minted
the
the
function
function
will
will
continue
continue
executing.
executing
Otherwise,
otherwise
it
it
will
will
throw
throw
an
an
error
error
saying
saying
the
the
NFT
nft
has
has
already
already
been
been
minted.
minted
The
the
next
next
thing
thing
we
we
wanna
wanna
validate
validate
is
is
that
that
the
the
user
user
has
has
paid
paid
enough
enough
ether.
ether
There's
there's
a
a
global
global
variable
variable
of
of
message,
message
and
and
its
its
value
value
property
property
contains
contains
the
the
amount
amount
of
of
ether
ether
being
being
sent
sent
into
into
the
the
contract.
contract
We
we
can
can
make
make
sure
sure
that
that
the
the
minimum
minimum
value
value
is
is
greater
greater
than
than
0.05.
0.05
Otherwise,
otherwise
we'll
we'll
throw
throw
an
an
error
error
saying
saying
the
the
user
user
needs
needs
to
to
pay
pay
up.
up
From
from
there,
there
we'll
we'll
want
want
to
to
create
create
a
a
new
new
item
item
ID.
id
With
with
the
the
counter
counter
implemented
implemented
by
by
OpenZeppelin,
openzeppelin
it
it
will
will
increment
increment
each
each
new
new
token
token
by
by
1.
1
So
so
it
it
starts
starts
at
at
0
0
then
then
goes
goes
to
to
1,
1
2,
2
3,
3
and
and
so
so
on.
on
After
after
incrementing
incrementing
the
the
counter,
counter
we'll
we'll
update
update
our
our
mapping
mapping
of
of
the
the
existing
existing
URI's,
uri's
then
then
we
we
call
call
the
the
built
built
in
in
mint
mint
method
method
with
with
the
the
recipient's
recipient's
wallet
wallet
address,
address
and
and
finally,
finally
we
we
set
set
the
the
token
token
URI
uri
on
on
that
that
ID.
id
That's
that's
how
how
someone
someone
can
can
pay
pay
to
to
mint
mint
a
a
new
new
token.
token
And
and
as
as
one
one
final
final
touch,
touch
I'm
i'm
also
also
going
going
to
to
add
add
A
a
function
function
here
here
to
to
get
get
the
the
current
current
count,
count
so
so
we
we
can
can
know
know
exactly
exactly
how
how
many
many
tokens
tokens
have
have
been
been
minted
minted
so
so
far.
far
And
and
that
that
completes
completes
the
the
Solidity
solidity
code
code
for
for
our
our
back
back
end.
end
At
at
this
this
point,
point
you
you
may
may
want
want
to
to
just
just
jump
jump
straight
straight
into
into
building
building
a
a
web
web
3
3
application,
application
but
but
I
i
would
would
highly
highly
recommend
recommend
that
that
you
you
do
do
some
some
testing
testing
first.
first
Hardhat
hardhat
already
already
has
has
a
a
sample
sample
test
test
ready
ready
to
to
go.
go
And
and
the
the
code
code
you
you
write
write
in
in
a
a
test
test
will
will
be
be
very
very
similar,
similar
if
if
not
not
identical,
identical
to
to
the
the
code
code
that
that
you
you
write
write
in
in
your
your
front
front
end
end
React
react
application.
application
It's
it's
much
much
easier
easier
to
to
detect
detect
bugs
bugs
and
and
issues
issues
in
in
a
a
test
test
than
than
it
it
is
is
in
in
a
a
front
front
end
end
application
application
with
with
all
all
the
the
UI
ui
stuff
stuff
going
going
on.
on
If
if
you've
you've
never
never
done
done
test
test
driven
driven
development
development
before,
before
I
i
have
have
an
an
entire
entire
video
video
on
on
it.
it
In
in
the
the
test,
test
we'll
we'll
first
first
use
use
ethers
ethers
to
to
get
get
our
our
contract
contract
and
and
then
then
deploy
deploy
it.
it
Once
once
deployed,
deployed
we'll
we'll
then
then
need
need
a
a
wallet
wallet
address
address
with
with
some
some
ether
ether
in
in
it
it
for
for
testing.
testing
Luckily,
luckily
we
we
can
can
use
use
a
a
fake
fake
wallet
wallet
with
with
10,000
10,000
ether
ether
in
in
it
it
already
already
by
by
going
going
to
to
the
the
terminal
terminal
and
and
running
running
npx
npx
hardhat
hardhat
node.
node
This
this
creates
creates
a
a
mock
mock
network
network
on
on
localhost
localhost
and
and
provides
provides
us
us
with
with
a
a
bunch
bunch
of
of
fake
fake
accounts
accounts
to
to
used
used
for
for
testing.
testing
Copy
copy
one
one
of
of
the
the
public
public
keys
keys
and
and
use
use
it
it
in
in
your
your
test.
test
At
at
this
this
point,
point
we
we
can
can
start
start
calling
calling
the
the
methods
methods
on
on
the
the
deployed
deployed
smart
smart
contract.
contract
First,
first
I'll
i'll
create
create
a
a
variable
variable
called
called
balance
balance
that
that
checks
checks
the
the
current
current
balance
balance
of
of
the
the
recipient's
recipient's
wallet
wallet
address.
address
Balance
balance
of
of
is
is
a
a
method
method
built
built
into
into
the
the
ERC
erc
721
721
spec.
spec
Now
now
Now
now
currently,
currently
the
the
user
user
hasn't
hasn't
purchased
purchased
any
any
NFTs,
nfts
so
so
we
we
expect
expect
the
the
balance
balance
to
to
equal
equal
0.
0
Now
now
from
from
there,
there
we'll
we'll
create
create
another
another
variable
variable
called
called
newly
newly
minted
minted
token
token
that
that
calls
calls
the
the
payment
payment
method
method
that
that
we
we
defined
defined
on
on
the
the
smart
smart
contract.
contract
It
it
takes
takes
the
the
recipient
recipient
and
and
metadata
metadata
URI
uri
as
as
arguments,
arguments
and
and
then
then
we
we
can
can
also
also
define
define
the
the
message
message
value
value
as
as
0.05
0.05
ether.
ether
For
for
fun,
fun
let's
let's
go
go
ahead
ahead
and
and
set
set
the
the
ether
ether
value
value
to
to
0.01.
0.01
Now
now
go
go
to
to
the
the
terminal
terminal
and
and
run
run
npx
npx
hardhat
hardhat
test.
test
What
what
you'll
you'll
notice
notice
is
is
that
that
we
we
get
get
a
a
failing
failing
test,
test
and
and
you'll
you'll
see
see
the
the
error
error
message
message
here
here
that
that
the
the
user
user
needs
needs
to
to
pay
pay
up.
up
Let's
let's
go
go
ahead
ahead
and
and
fix
fix
that,
that
and
and
then
then
we'll
we'll
wait
wait
for
for
the
the
newly
newly
minted
minted
token
token
to
to
be
be
mined
mined
by
by
calling
calling
the
the
wait
wait
method
method
on
on
it.
it
From
from
there,
there
we
we
can
can
query
query
the
the
balance
balance
again,
again
and
and
this
this
time
time
we
we
expect
expect
it
it
to
to
equal
equal
1.
1
In
in
addition,
addition
we
we
can
can
test
test
our
our
is
is
content
content
owned
owned
method
method
by
by
making
making
sure
sure
that
that
that
that
metadata
metadata
URI
uri
is
is
equal
equal
to
to
true.
true
And
and
there
there
are
are
all
all
kinds
kinds
of
of
other
other
things
things
we
we
could
could
test
test
here,
here
but
but
you
you
get
get
the
the
general
general
idea.
idea
If
if
you
you
test
test
all
all
your
your
smart
smart
contract
contract
logic
logic
first,
first
It'll
it'll
make
make
the
the
front
front
end
end
development
development
much
much
easier.
easier
Now,
now
we're
we're
ready
ready
to
to
move
move
on
on
to
to
the
the
next
next
phase,
phase
where
where
we
we
build
build
a
a
web
web
3
3
application
application
that
that
interacts
interacts
with
with
a
a
smart
smart
contract
contract
from
from
a
a
website.
website
Let's
let's
1st,
1st
go
go
into
into
the
the
sample
sample
script
script
provided
provided
by
by
HardHat.
hardhat
This
this
script
script
is
is
used
used
to
to
compile
compile
the
the
contract,
contract
which
which
will
will
populate
populate
the
the
artifacts
artifacts
directory
directory
with
with
all
all
the
the
information
information
we
we
need
need
to
to
interact
interact
with
with
like
like
the
the
ABI
abi
I
i
talked
talked
about
about
earlier.
earlier
We'll
we'll
want
want
to
to
update
update
the
the
default
default
values
values
with
with
the
the
name
name
of
of
the
the
custom
custom
contract
contract
that
that
we
we
created.
created
You'll
you'll
want
want
to
to
first
first
make
make
sure
sure
you
you
have
have
opened
opened
running
running
the
the
npx
npx
hardhat
hardhat
node
node
command.
command
This
this
should
should
always
always
be
be
running
running
in
in
the
the
background.
background
From
from
there,
there
we
we
can
can
open
open
up
up
a
a
separate
separate
terminal
terminal
and
and
run
run
npx
npx
hard
hard
at
at
compile.
compile
This
this
runs
runs
the
the
solidity
solidity
compiler
compiler
to
to
convert
convert
your
your
code
code
into
into
binary.
binary
Once
once
that's
that's
done,
done
we
we
can
can
run
run
npx
npx
hard
hard
hat
hat
run
run
scripts,
scripts
sample
sample
script,
script
and
and
specify
specify
the
the
network
network
as
as
local
local
host.
host
That
that
will
will
take
take
the
the
contract
contract
and
and
deploy
deploy
it
it
to
to
the
the
actual
actual
network.
network
And
and
now
now
we
we
have
have
a
a
smart
smart
contract
contract
running
running
on
on
our
our
local
local
Sheen.
sheen
Now
now
when
when
it
it
comes
comes
to
to
web
web
3,
3
the
the
way
way
end
end
users
users
interact
interact
with
with
a
a
smart
smart
contract
contract
is
is
typically
typically
with
with
a
a
browser
browser
plugin
plugin
like
like
Metamask.
metamask
For
for
development,
development
You'll
you'll
want
want
to
to
set
set
up
up
MetaMask
metamask
with
with
one
one
of
of
the
the
testing
testing
addresses
addresses
provided
provided
by
by
Hardhat.
hardhat
If
if
you
you
don't
don't
have
have
it
it
yet,
yet
install
install
MetaMask
metamask
and
and
then
then
go
go
to
to
the
the
local
local
host
host
network
network
and
and
import
import
a
a
new
new
account.
account
It
it
will
will
ask
ask
you
you
for
for
a
a
private
private
key,
key
which
which
you
you
can
can
simply
simply
copy
copy
from
from
the
the
terminal
terminal
output.
output
And
and
now
now
we're
we're
ready
ready
to
to
start
start
writing
writing
some
some
React
react
code.
code
In
in
order
order
for
for
a
a
user
user
to
to
mint
mint
an
an
NFT
nft
on
on
the
the
website.
website
They'll
they'll
need
need
to
to
have
have
MetaMask
metamask
installed.
installed
We'll
we'll
need
need
to
to
check
check
that
that
at
at
runtime
runtime
and
and
have
have
2
2
different
different
screens
screens
based
based
on
on
whether
whether
or
or
not
not
installed.
installed
I'm
i'm
creating
creating
2
2
different
different
components
components
here,
here
one
one
called
called
home
home
and
and
one
one
called
called
install.
install
And
and
in
in
the
the
install
install
component,
component
we'll
we'll
simply
simply
have
have
a
a
link
link
to
to
the
the
MetaMask
metamask
plug
plug
in.
in
Now
now
in
in
the
the
main
main
app
app
component,
component
we
we
can
can
check
check
to
to
see
see
if
if
the
the
user
user
has
has
a
a
plug
plug
in
in
installed
installed
by
by
checking
checking
the
the
window
window
ethereum
ethereum
object.
object
A
a
plug
plug
in
in
like
like
Metamask
metamask
will
will
make
make
this
this
object
object
available
available
automatically
automatically
when
when
it's
it's
installed.
installed
Now
now
the
the
next
next
thing
thing
I'll
i'll
do
do
is
is
create
create
a
a
new
new
component
component
called
called
wallet
wallet
balance.
balance
And
and
inside
inside
of
of
it,
it
We
we
can
can
start
start
interacting
interacting
with
with
ethers.
ethers
Js,
js
which
which
is
is
a
a
JavaScript
javascript
library
library
that
that
makes
makes
it
it
easy
easy
to
to
communicate
communicate
between
between
the
the
smart
smart
contract
contract
and
and
in
in
end
end
user's
user's
wallet.
wallet
In
in
this
this
component,
component
what
what
we
we
wanna
wanna
do
do
is
is
get
get
the
the
end
end
user's
user's
current
current
balance.
balance
We'll
we'll
first
first
set
set
up
up
state
state
with
with
the
the
use
use
state
state
hook
hook
and
and
then
then
define
define
a
a
function
function
called
called
GitBalance.
gitbalance
We
we
can
can
get
get
the
the
connected
connected
account
account
on
on
the
the
window
window
Ethereum
ethereum
object
object
and
and
then
then
we
we
use
use
ethers.
ethers
Js
js
to
to
create
create
a
a
new
new
web
web
3
3
provider.
provider
The
the
provider
provider
provides
provides
all
all
kinds
kinds
of
of
or
or
methods
methods
for
for
interacting
interacting
with
with
the
the
Blockchain.
blockchain
One
one
of
of
which
which
is
is
getBalance,
getbalance
which
which
then
then
takes
takes
the
the
account
account
as
as
its
its
argument.
argument
That
that
will
will
return
return
the
the
wallet
wallet
balance
balance
of
of
the
the
connected
connected
account,
account
which
which
should
should
be
be
10,000
10,000
ether,
ether
but
but
it's
it's
in
in
a
a
big
big
number
number
format.
format
So
so
ethers
ethers
also
also
provides
provides
a
a
utility
utility
to
to
format
format
the
the
ether
ether
value,
value
which
which
we
we
can
can
use
use
when
when
setting
setting
the
the
balance
balance
on
on
on
on
the
the
component.
component
And
and
now
now
we
we
can
can
call
call
this
this
function
function
when
when
a
a
button
button
is
is
clicked
clicked
and
and
show
show
the
the
balance
balance
value
value
in
in
the
the
UI.
ui
Now
now
let's
let's
go
go
ahead
ahead
and
and
declare
declare
the
the
wallet
wallet
balance
balance
component
component
in
in
the
the
main
main
component
component
and
and
then
then
we
we
can
can
serve
serve
the
the
app
app
locally
locally
by
by
running
running
npm
npm
run
run
dev.
dev
I've
i've
also
also
added
added
Bootstrap
bootstrap
to
to
my
my
project
project
to
to
make
make
things
things
look
look
a
a
little
little
nicer,
nicer
but
but
the
the
end
end
result
result
should
should
of
of
a
a
button
button
that,
that
when
when
clicked,
clicked
updates
updates
the
the
balance
balance
in
in
the
the
UI.
ui
That's
that's
how
how
we
we
can
can
use
use
Ethers
ethers
to
to
interact
interact
with
with
the
the
wallet,
wallet
but
but
now
now
how
how
do
do
we
we
interact
interact
with
with
the
the
smart
smart
contract?
contract
We'll
we'll
first
first
need
need
to
to
import
import
the
the
contract
contract
ABI
abi
from
from
the
the
artifacts
artifacts
directory.
directory
Now
now
earlier,
earlier
when
when
you
you
compiled
compiled
your
your
contract
contract
and
and
ran
ran
the
the
sample
sample
script,
script
it
it
should
should
have
have
said
said
contract
contract
deployed
deployed
to
to
an
an
address
address
in
in
the
the
terminal.
terminal
Let's
let's
go
go
ahead
ahead
and
and
take
take
that
that
contract
contract
address
address
and
and
set
set
it
it
up
up
as
as
a
a
global
global
variable
variable
here
here
in
in
our
our
code.
code
We
we
can
can
then
then
instantiate
instantiate
a
a
web
web
3
3
provider
provider
again
again
and
and
use
use
it
it
to
to
get
get
the
the
signer
signer
to
to
execute
execute
transactions
transactions
on
on
the
the
blockchain.
blockchain
From
from
there,
there
we
we
can
can
use
use
ethers
ethers
to
to
instantiate
instantiate
the
the
contract
contract
using
using
the
the
address,
address
the
the
ABI
abi
and
and
the
the
signer.
signer
What
what
we
we
wanna
wanna
do
do
next
next
is
is
loop
loop
over
over
all
all
of
of
the
the
NFT
nft
images
images
in
in
the
the
collection.
collection
Each
each
one
one
of
of
those
those
images
images
will
will
have
have
a
a
button
button
to
to
mint
mint
it.
it
Or
or
if
if
it's
it's
already
already
been
been
minted,
minted
the
the
owner
owner
can
can
view
view
the
the
token
token
URI
uri
for
for
the
the
NFT.
nft
We'll
we'll
first
first
need
need
to
to
know
know
how
how
many
many
tokens
tokens
have
have
already
already
been
been
minted,
minted
and
and
to
to
do
do
that,
that
I'm
i'm
setting
setting
up
up
a
a
function
function
here
here
called
called
get
get
count
count
that
that
calls
calls
the
the
contract
contract
count
count
method
method
that
that
we
we
implemented
implemented
in
in
solidity
solidity
earlier.
earlier
We'll
we'll
then
then
call
call
this
this
function
function
when
when
the
the
component
component
is
is
first
first
initialized
initialized
with
with
the
the
useEffect
useeffect
hook.
hook
In
in
the
the
JSX,
jsx
I'm
i'm
looping
looping
over
over
every
every
token
token
that's
that's
been
been
minted
minted
so
so
far.
far
For
for
each
each
one
one
of
of
those
those
items,
items
I'm
i'm
rendering
rendering
a
a
a
a
component
component
called
called
nft
nft
image
image
that
that
takes
takes
the
the
index
index
as
as
a
a
prop,
prop
which
which
conveniently
conveniently
matches
matches
the
the
token
token
ID.
id
Now,
now
in
in
the
the
nft
nft
image
image
component,
component
I'm
i'm
adding
adding
a
a
property
property
for
for
the
the
content
content
ID.
id
This
this
content
content
ID
id
comes
comes
from
from
pinata.
pinata
Remember,
remember
I
i
uploaded
uploaded
all
all
my
my
graphics
graphics
to
to
a
a
folder
folder
in
in
pinata.
pinata
We
we
can
can
combine
combine
the
the
content
content
ID
id
with
with
the
the
token
token
ID
id
to
to
reference
reference
that
that
JSON
json
metadata
metadata
URI.
uri
Now,
now
when
when
it
it
comes
comes
to
to
the
the
actual
actual
image,
image
I
i
tried
tried
to
to
use
use
that
that
pinata
pinata
cloud
cloud
gateway,
gateway
but
but
I
i
didn't
didn't
Find
find
this
this
to
to
be
be
very
very
reliable.
reliable
I
i
often
often
had
had
broken
broken
images,
images
so
so
currently,
currently
I'm
i'm
referencing
referencing
my
my
images
images
here
here
locally.
locally
Now,
now
as
as
we
we
loop
loop
over
over
these
these
images,
images
we
we
need
need
to
to
figure
figure
out
out
if
if
each
each
metadata
metadata
URI
uri
I
i
has
has
been
been
minted
minted
yet.
yet
For
for
that,
that
I'm
i'm
going
going
to
to
set
set
up
up
state
state
on
on
the
the
component
component
of
of
isMinted
isminted
and
and
then
then
define
define
a
a
function
function
called
called
getMintedStatus
getmintedstatus
that
that
will
will
run
run
the
the
is
is
content
content
own
own
method
method
on
on
the
the
smart
smart
contract
contract
itself,
itself
and
and
then
then
we'll
we'll
run
run
that
that
function
function
with
with
the
the
useEffect
useeffect
hook.
hook
And
and
now
now
we've
we've
reached
reached
the
the
point
point
where
where
we
we
can
can
actually
actually
mint
mint
the
the
token.
token
I'm
i'm
creating
creating
another
another
function
function
to
to
handle
handle
that,
that
and
and
inside
inside
the
the
body,
body
the
the
first
first
thing
thing
it
it
will
will
do
do
is
is
make
make
a
a
connection
connection
between
between
the
the
contract
contract
and
and
the
the
signer.
signer
That
that
will
will
give
give
us
us
access
access
to
to
the
the
recipient's
recipient's
to
to
wallet
wallet
address.
address
We
we
then
then
call
call
the
the
pay
pay
to
to
mint
mint
method
method
on
on
the
the
smart
smart
contract
contract
and
and
pass
pass
the
the
address
address
as
as
well
well
as
as
the
the
metadata
metadata
URI
uri
as
as
arguments.
arguments
In
in
addition,
addition
we
we
need
need
to
to
set
set
the
the
value
value
of
of
ether
ether
that
that
the
the
user
user
will
will
pay.
pay
For
for
that,
that
we
we
pass
pass
an
an
object
object
with
with
a
a
value
value
of
of
the
the
amount
amount
of
of
ether,
ether
which
which
in
in
this
this
case
case
will
will
be
be
0.05.
0.05
You
you
may
may
notice
notice
how
how
this
this
code
code
is
is
basically
basically
identical
identical
all
all
to
to
the
the
code
code
we
we
wrote
wrote
in
in
our
our
unit
unit
test
test
earlier.
earlier
From
from
there,
there
we
we
can
can
wait
wait
for
for
the
the
result
result
to
to
be
be
mined,
mined
after
after
which
which
point
point
we
we
can
can
call
call
that
that
get
get
minted
minted
status
status
function
function
again,
again
and
and
this
this
time
time
it
it
should
should
say
say
that
that
metadata
metadata
URI
uri
has
has
been
been
minted.
minted
Now,
now
it's
it's
just
just
a
a
matter
matter
of
of
using
using
some
some
conditional
conditional
logic
logic
in
in
the
the
JSX
jsx
to
to
show
show
the
the
image
image
URI
uri
if
if
it's
it's
already
already
been
been
minted.
minted
Otherwise,
otherwise
we'll
we'll
just
just
show
show
a
a
mystery
mystery
placeholder
placeholder
and
and
then
then
we'll
we'll
also
also
show
show
the
the
option
option
to
to
mint
mint
the
the
token
token
if
if
it's
it's
not
not
already
already
minted.
minted
Otherwise,
otherwise
it
it
will
will
say
say
that
that
NFT
nft
is
is
taken.
taken
Now
now
at
at
this
this
point,
point
if
if
all
all
went
went
well,
well
you
you
should
should
be
be
able
able
to
to
go
go
to
to
the
the
application
application
and
and
When
when
you
you
click
click
the
the
mint
mint
button,
button
it
it
will
will
bring
bring
up
up
MetaMask
metamask
confirming
confirming
that
that
you
you
want
want
to
to
transfer
transfer
0.05
0.05
ether
ether
and
and
will
will
then
then
complete
complete
the
the
transaction
transaction
after
after
you
you
confirm
confirm
of
of
it.
it
Congratulations,
congratulations
you
you
just
just
built
built
a
a
basic
basic
web
web
3
3
app.
app
Let's
let's
take
take
a
a
quick
quick
break
break
to
to
appreciate
appreciate
it.
it
It's
it's
Britney,
britney
bitch.
bitch
Now
now
we
we
can
can
move
move
on
on
to
to
phase
phase
7,
7
deployment.
deployment
This
this
app
app
is
is
by
by
no
no
means
means
production
production
ready
ready
and
and
would
would
cost
cost
a
a
lot
lot
of
of
money
money
to
to
deploy
deploy
it
it
to
to
the
the
Ethereum
ethereum
mainnet.
mainnet
But
but
one
one
thing
thing
we
we
can
can
do
do
is
is
deploy
deploy
it
it
to
to
a
a
testnet
testnet
to
to
see
see
how
how
it
it
would
would
work
work
in
in
the
the
real
real
world.
world
A
a
free
free
tool
tool
that
that
can
can
help
help
us
us
do
do
that
that
is
is
Alchemy.
alchemy
The
the
majority
majority
of
of
serious
serious
web
web
3
3
applications
applications
use
use
tools
tools
like
like
Alchemy
alchemy
and
and
Infura,
infura
which
which
are
are
platforms
platforms
that
that
can
can
help
help
make
make
decentralized
decentralized
apps
apps
more
more
reliable.
reliable
What
what
we're
we're
going
going
to
to
do
do
is
is
use
use
Alchemy
alchemy
to
to
deploy
deploy
our
our
contract
contract
to
to
a
a
test
test
net.
net
When
when
you
you
create
create
an
an
account,
account
it
it
will
will
give
give
you
you
the
the
option
option
to
to
create
create
a
a
new
new
application,
application
and
and
I'm
i'm
going
going
to
to
use
use
the
the
Polygon
polygon
chain
chain
with
with
the
the
Polygon
polygon
Mumbai
mumbai
network.
network
Polygon,
polygon
by
by
the
the
way,
way
is
is
a
a
blockchain
blockchain
built
built
on
on
top
top
of
of
Ethereum
ethereum
that
that
is
is
faster
faster
unless
unless
expensive.
expensive
Its
its
native
native
token,
token
MATIC,
matic
is
is
very
very
similar
similar
to
to
ether.
ether
For
for
this
this
tutorial,
tutorial
you
you
can
can
think
think
of
of
MATIC
matic
and
and
ether
ether
as
as
being
being
the
the
same
same
basic
basic
thing.
thing
Once
once
the
the
app
app
is
is
created,
created
you'll
you'll
notice
notice
it
it
gives
gives
you
you
a
a
link
link
to
to
the
the
network.
network
Go
go
ahead
ahead
and
and
copy
copy
that.
that
Now
now
go
go
back
back
to
to
the
the
hardhat
hardhat
config
config
file
file
in
in
your
your
source
source
code.
code
You'll
you'll
need
need
a
a
new
new
entry
entry
under
under
networks,
networks
which
which
in
in
this
this
case
case
will
will
be
be
Matic,
matic
and
and
point
point
it
it
to
to
the
the
URL
url
that
that
you
you
just
just
copied.
copied
The
the
other
other
thing
thing
you'll
you'll
need
need
is
is
a
a
private
private
key
key
for
for
your
your
account.
account
Go
go
over
over
to
to
MetaMask
metamask
and
and
switch
switch
the
the
network
network
to
to
Mumbai,
mumbai
then
then
from
from
the
the
menu,
menu
click
click
account
account
details
details
and
and
export
export
your
your
private
private
key,
key
then
then
paste
paste
it
it
into
into
the
the
hardhat
hardhat
config.
config
The
the
reason
reason
you
you
need
need
a
a
private
private
key
key
here
here
is
is
because
because
this
this
account
account
will
will
be
be
the
the
one
one
that
that
deploys
deploys
the
the
contract,
contract
but
but
deploying
deploying
a
a
contract
contract
isn't
isn't
free
free
and
and
currently
currently
there
there
is
is
0
0
MATIC
matic
in
in
as
as
wallet.
wallet
To
to
get
get
some
some
free
free
test
test
money,
money
we'll
we'll
need
need
to
to
go
go
to
to
the
the
Polygon
polygon
faucet
faucet
and
and
add
add
our
our
public
public
wallet
wallet
address
address
there,
there
and
and
after
after
a
a
few
few
minutes
minutes
of
of
waiting,
waiting
you
you
should
should
magically
magically
see
see
some
some
MATIC
matic
appear
appear
in
in
your
your
wallet.
wallet
And
and
now
now
we're
we're
ready
ready
for
for
the
the
moment
moment
of
of
truth.
truth
From
from
the
the
terminal,
terminal
run
run
the
the
hardhat
hardhat
deploy
deploy
script
script
again,
again
but
but
this
this
time
time
make
make
sure
sure
the
the
network
network
option
option
is
is
set
set
to
to
HANA.
hana
That
that
should
should
deploy
deploy
the
the
contract
contract
to
to
the
the
Mumbai
mumbai
network,
network
make
make
sure
sure
to
to
copy
copy
the
the
address
address
and
and
update
update
it
it
in
in
your
your
front
front
end
end
code
code
in
in
the
the
main
main
dot
dot
JSX
jsx
file.
file
You
you
now
now
have
have
a
a
web
web
3
3
application
application
running
running
out
out
in
in
the
the
wild,
wild
and
and
you
you
could
could
follow
follow
the
the
same
same
basic
basic
process
process
to
to
deploy
deploy
to
to
the
the
main
main
net.
net
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
there.
there
Hopefully,
hopefully
that
that
gives
gives
you
you
a
a
general
general
idea
idea
of
of
all
all
the
the
steps
steps
involved
involved
in
in
building
building
a
a
dApp.
dapp
The
the
final
final
thing
thing
I'll
i'll
mention
mention
is
is
that
that
if
if
you
you
want
want
to
to
purchase
purchase
these
these
n
n
f
f
t's
t's
yourself,
yourself
you
you
can
can
do
do
so
so
on
on
OpenSea.
opensea
E.
e
I
i
don't
don't
know
know
why
why
you
you
ever
ever
would,
would
but
but
they're
they're
there
there
if
if
you
you
want
want
them.
them
Thanks
thanks
for
for
watching,
watching
and
and
I
i
will
will
see
see
you
you
in
in
the
the
next
next
one.
one
success
The speakers discuss the development of a web 3 application using Sol neat, including creating a directory of contracts and updating paths for the blockchain. They recommend using a tool called in Zeppelin and suggest using it for creating a smart contract. They also discuss the use of Ecf to interact with the wallet and smart contract, including setting up state and setting up a wallet balance. The speakers emphasize the importance of metadata in the creation of the NFT and provide a video on building a web 3 application and testing code. They also discuss the use of Ecf to deploy a contract to a test net and the need for a private key for the account.
Build a WEB3 app to mint unlimited NFTs… But should you?
In today's video, we'll build a complete web 3 application step by step from scratch and in the process, we'll talk about the good and bad aspects of developing decentralized web apps on the blockchain. You may have seen the headlines of kids making 1,000,000 of dollars overnight by selling digital art in the form of NFTs. If you're like me and not already an NFT millionaire. You likely have some FOMO about this whole trend. You could point out how NFTs are dumb, pointless, and bad for the environment, or you could try to get in on the trend yourself, and that's exactly what we'll do in this video. I'll show you how I created a collection of 20,000 unique graphics with some crappy artwork I drew by hand in a few minutes. We'll then take that artwork and upload it to the interplanetary file system. At which point, we can write a smart contract with Solidity and OpenZeppelin that will mint a new NFT whenever somebody transfers Ethereum to the smart contract. And finally, we'll use ethers. Js with React to build a web 3 application that provides a front end interface where people can actually interact of a smart contract. By the end of this tutorial, you'll understand the complete process of going from 0 to a web 3 point o NFT application. This tutorial is longer than most on this channel and it's broken down into 7 phases. If you're new here, like and subscribe and follow along with the full tutorial on Fireship biome. And if you wanna see more web 3 content, let me know in the comments. Before we get started, let's first answer the question of what is an NFT collection. A nonfudgeable token is a unique digital asset. Usually, it represents a piece of artwork like an image, but it can also represent things like domain names and physical items in the real world, but you'll often see NFTs packaged in a collection like CryptoPunks, Bored Ape Yacht Club, and doodles just to name a few. These graphics are created with a few base layers, like hair, eyes, clothing, and so on. The layers are then combined together randomly to create a bunch of unique graphics. What's interesting though is that the various traits and attributes have different levels of rarity. When a graphic is generated, it's less likely to have one of the rare traits. This is actually really fun because you can think of a smart contract like a vending machine in the cloud. When an NFT collection is first offered, you can send crypto to that wallet address. It will mint a one of a in token and transfer it to your wallet. If you're lucky, you'll get something with a really rare trait. It's not much different than opening up a pack of Pokemon cards. Most of the cards are very common, but there is a small chance you'll get something that's very rare and valuable. Now after you purchase an NFT, there's a secondary market where you can resell it to someone else on a site like OpenSea. Many people invest in NFTs hoping to flip them for a higher value later on. If you're the original creator, you can also configure your smart on track to receive royalty payments whenever the NFT changes hands in the future. That's pretty cool, but there are a lot of bad things I could say about web 3 as well. The guy who created signal, an encrypted messaging app, created an NFT that actually changes its appearance based on where you view it. On OpenSea, it looks really cool, but in your wallet, but it looks like a piece of poop. Because the NFT image is hosted off chain, he just used a web server to display a different image based on the user agent that was requesting the image. Everybody talks about web 3 being decentralized and trustless, but the reality is that much of it works thanks to centralized APIs. Read his full blog post to learn more. At the end of the day, we don't really care about that we're just here to have fun, get some exercise, and make a ton of money. Now we're ready to kick off phase 1 of this project, where we create the layers or graphics that we'll use for the NFT collection. I'm not much of an artist and everything I draw tends to look really creepy. Not much I can do about that, so I'm just gonna own it. Believe it or not, creating NFT artwork is an art form. I I find it really satisfying because you can take a few basic images and use them to create thousands of different unique combinations. For my NFT collection, I actually used a pen and paper to draw everything by hand. I then digitized it and brought each individual layer into Figma. As you can see here, I have different categories for the various traits, like hair, eyes, nose, mouth, beard, and so on. From there, I created a little script in Node. Js that randomly combines these layers together. You can find the source code on GitHub, but there are many existing tools out there that can help you generate in NFT collection without needing to write any code. If you're looking for a tutorial that doesn't require any code, this is not the video for you. If your goal is to just create a bunch of images and sell them as NFTs. I'd recommend checking out this recent tutorial from Code Stacker for a more simplified approach. I'm not gonna go through every single line of code here, but I just wanna walk you through the process I used to create all my NFT graphics from scratch. 1st, you can see I have a directory called layers that contains a bunch of files like eyes 0, eyes 1, eyes 2, and so on. This directory contains all the possible layers that we would use in an image. From there, I have a file named index.js. Inside of I have an SVG template. I'm using scalable vector graphics here, but I've seen other implementations that just use PNGs. Now each layer in our layers directory as an SVG, so all we have to do is grab the main content from that file and replace each one of these comments with the corresponding traffic like head, hair, eyes, nose, mouth, and beard. In order to do that, I'm using Node. Js to read one of our layer files and then use some regex to grab of the content inside the SVG tags. Then I have a function called create image that will generate a bunch of random numbers and combine them together into an array. I've made this a recursive function that checks to see if that combination has already been taken, in which case it will try running the randomization again. If it is a valid combination, We'll go ahead and replace all the comments in the SVG template with the actual layers from our layers directory. Now, in addition to creating in image. We're also going to create a JSON file with some metadata about it. This metadata is really important because it contains the name of the file as well as a link to its actual image on the interplanetary file system. That represents a unique file upload that cannot be modified. In addition, if the metadata contains attributes of the different traits in the image. Generally, when making an NFT collection, each trait has a different level of rarity. The more rare rates an NFT has, the more valuable it tends to be, thanks to the magic of artificial scarcity. Now, I'll go ahead and write these files to my file system and as an added touch, I'm also burning the SVG to a PNG file as well. I'm using a node package called Sharp to make that possible. And finally, to run the script, I just have a while loop that calls the create image function for the number of images that I want to create. And now when we run the script with node, we get this out directory with a bunch of files that contain both the raw images and JSON for each individual graphic. That takes care of phase 1. We can now generate 1,000 or even millions of individual graphics by simply adding more layers to the layers directory, but keep in mind that my implementation is very crude. There's a lot of optimizations we could make or better yet, we could have used a pre built solution out there to get this job done much faster. Now the next thing we need to think about is how to get these files on the Internet and connect them to a non fungible token. The actual image data and JSON for the NFT t is too big to be efficiently stored on the blockchain. So instead, we store it off chain on the interplanetary file system, which is a decentralized file system in the cloud very similar to BitTorrent. One very important concern that IPFS handles is content addressability. Anytime you upload a file, it creates a unique identifier for at upload, and that allows us to verify the authenticity of any graphics associated to an NFT. Once a file has been uploaded, you can't modify it without changing its content identifier. That means when minting an NFT, the only thing we actually need to store is a link to that file's content identifier. Now the question becomes, How do we take our raw files and upload them to IPFS? There are many ways to go about it, but an easy free solution that I've been using is of it. It's very similar to something like Dropbox where you simply click a button to upload and choose a file from your file system, and you can even host an entire static website from Yotta. It also has a node SDK to upload programmatically, but we're not going to worry about it in this video. I'm just going to upload a few of our images here, and you'll notice when I that it creates a content identifier. Conveniently, we can upload an entire directory all at once. I'm gonna go ahead and upload a few of the graphics that I just generated. For this tutorial, You can upload any random file. It doesn't really matter. And now, we're ready to build a full stack web 3 application using Solidity, Hardhat, and React. The first thing I'm doing here is generating a new React app using Vite. It really doesn't matter which front end framework you use here, but the vast majority of web 3 demos out there use React. That Gives us a front end application. Now we're going to run npx hardhat, which will add a variety of tools to our project to add a blockchain back end. You'll notice it generates a directory for contracts, which contains files written in Solidity, which contains the smart contract code that will interact with the blockchain. It also creates a directory named scripts that contains the code to deploy those contracts to the blockchain. Now there's a couple of configuration things we'll need to do here. In the hardhat config file, We'll update the paths option to create any artifacts in the source directory for the React application. That allows React to access information about the smart contracts. When you compile of smart contract. It creates what's known as an application binary interface, which is basically a middleman that allows your front end JavaScript code to communicate with the smart contract compiled to machine code and all that information lives in the our contract compiled to machine code, and all that information lives in the artifacts directory. From there, we're going to install a bunch of dependencies with npm, like Waffle for automated testing and ethers to interact with smart contracts in the browser and also a tool called OpenZeppelin, which provides templates for quickly building industry standard smart contracts. At this point, I want to focus on writing a smart contract. Its purpose is to accept a payment from a user, then mint a non fungible token and transfer it to that user's wallet. It's important to point out that the code in the smart contract will not actually generate random rates for the NFT images. It's actually extremely difficult to handle randomness in a smart contract. Most NFT collections don't deal with it at all, and instead, they just generate all the images at once, upload them to IPFS, and then mint them after the fact. At which point, they get sold on a secondary market, or you might code up another contract to create your own secondary market. Now it is possible to implement randomness in a smart contract, and if that's what you wanna do, I would highly recommend looking into something like Chainlink. We're going to take the easy approach in this video where the smart contract takes the IPFS URL for the metadata along with some Ethereum and mints a new token from it. To handle that requirement, we'll need to learn a new programming language called Solidity. In the contract x directory. Let's go ahead and create a file ending in dot s o l. Now, we could implement a smart contract from scratch, but that would be a pretty big undertaking on its own. Luckily, there's a tool called in Zeppelin, and it has a wizard that we can use to automatically generate reliable code for us. The Ethereum ecosystem already has a variety of standard interfaces to handle requirements commonly implemented in smart contracts. Like ERC 20 is what you would use to create a fungible token, like if you wanted to create your own coin on the Ethereum network. But to create a non fungible token, we want to use the ERC 721 standard. Before we customize it, you'll notice that there is API documentation with a handful of methods built into the base contract, like balance of to check the owner's balance or owner of to to see who owns a token, as well as methods to transfer tokens from one user to another. Now let's go over to the open Zeppelin wizard to customize our own ERC 721 contract. Most importantly, we need to be able to mint our own tokens. If we check the box for mint, it adds a new method to the contract that allows a privileged account to mint or create a new token. Let's also auto increment IDs and then check the box for URI storage. URI storage allows us to associate and upload on IPFS when this token is minted. Remember, that's the reference to the metadata that we uploaded on pinata earlier. We'll also wanna use a base URI here that points to of PFS to ensure that the URI is properly formatted. That gives us a base contract to work with and you'll notice a button here to open up in the Remix IDE. I'm not going to do it in this video, but Remix is a browser based IDE that makes it really easy to compile and test your smart on tracks. What we're going to do is copy and paste this code and bring it directly into the solidity file that we created. We could use this contract as is, but we want to extend it with some additional code that allows anybody to mint a token as long as they transfer the appropriate amount of Ethereum along with it. Currently, you'll notice a safe mint method that allows the owner of the contract to mint a new token. What we wanna do is create a new function called pay to mint that takes a recipient and metadata a content ID, then mint a new token with that data. Now in order to implement this function, we'll wanna make sure that the same URI can't be minted twice. And to validate that, I'm creating a mapping of Strings to integers to keep track of the existing URIs that have been minted. We might also want to check if an existing URI is already owned, so I'm creating another function called is content owned that takes a URI as its argument and returns true if that URI already exists in the happening. Now, we have everything in place to implement the paydement function. You'll notice that it's marked as a payable function, which means that somebody can transfer money into the contract. Tracked. Now, we can use the require keyword to run some validation. And, keep in mind that this is not a production ready contract. My goal is just to show you how some of the basic mechanics in Solidity work. With require, we first pass a condition. In this case, we want to know if the URI has already been minted. If it has not been minted, the function will continue executing. Otherwise, it will throw an error saying the NFT has already been minted. The next thing we wanna validate is that the user has paid enough ether. There's a global variable of message, and its value property contains the amount of ether being sent into the contract. We can make sure that the minimum value is greater than 0.05. Otherwise, we'll throw an error saying the user needs to pay up. From there, we'll want to create a new item ID. With the counter implemented by OpenZeppelin, it will increment each new token by 1. So it starts at 0 then goes to 1, 2, 3, and so on. After incrementing the counter, we'll update our mapping of the existing URI's, then we call the built in mint method with the recipient's wallet address, and finally, we set the token URI on that ID. That's how someone can pay to mint a new token. And as one final touch, I'm also going to add A function here to get the current count, so we can know exactly how many tokens have been minted so far. And that completes the Solidity code for our back end. At this point, you may want to just jump straight into building a web 3 application, but I would highly recommend that you do some testing first. Hardhat already has a sample test ready to go. And the code you write in a test will be very similar, if not identical, to the code that you write in your front end React application. It's much easier to detect bugs and issues in a test than it is in a front end application with all the UI stuff going on. If you've never done test driven development before, I have an entire video on it. In the test, we'll first use ethers to get our contract and then deploy it. Once deployed, we'll then need a wallet address with some ether in it for testing. Luckily, we can use a fake wallet with 10,000 ether in it already by going to the terminal and running npx hardhat node. This creates a mock network on localhost and provides us with a bunch of fake accounts to used for testing. Copy one of the public keys and use it in your test. At this point, we can start calling the methods on the deployed smart contract. First, I'll create a variable called balance that checks the current balance of the recipient's wallet address. Balance of is a method built into the ERC 721 spec. Now Now currently, the user hasn't purchased any NFTs, so we expect the balance to equal 0. Now from there, we'll create another variable called newly minted token that calls the payment method that we defined on the smart contract. It takes the recipient and metadata URI as arguments, and then we can also define the message value as 0.05 ether. For fun, let's go ahead and set the ether value to 0.01. Now go to the terminal and run npx hardhat test. What you'll notice is that we get a failing test, and you'll see the error message here that the user needs to pay up. Let's go ahead and fix that, and then we'll wait for the newly minted token to be mined by calling the wait method on it. From there, we can query the balance again, and this time we expect it to equal 1. In addition, we can test our is content owned method by making sure that that metadata URI is equal to true. And there are all kinds of other things we could test here, but you get the general idea. If you test all your smart contract logic first, It'll make the front end development much easier. Now, we're ready to move on to the next phase, where we build a web 3 application that interacts with a smart contract from a website. Let's 1st, go into the sample script provided by HardHat. This script is used to compile the contract, which will populate the artifacts directory with all the information we need to interact with like the ABI I talked about earlier. We'll want to update the default values with the name of the custom contract that we created. You'll want to first make sure you have opened running the npx hardhat node command. This should always be running in the background. From there, we can open up a separate terminal and run npx hard at compile. This runs the solidity compiler to convert your code into binary. Once that's done, we can run npx hard hat run scripts, sample script, and specify the network as local host. That will take the contract and deploy it to the actual network. And now we have a smart contract running on our local Sheen. Now when it comes to web 3, the way end users interact with a smart contract is typically with a browser plugin like Metamask. For development, You'll want to set up MetaMask with one of the testing addresses provided by Hardhat. If you don't have it yet, install MetaMask and then go to the local host network and import a new account. It will ask you for a private key, which you can simply copy from the terminal output. And now we're ready to start writing some React code. In order for a user to mint an NFT on the website. They'll need to have MetaMask installed. We'll need to check that at runtime and have 2 different screens based on whether or not installed. I'm creating 2 different components here, one called home and one called install. And in the install component, we'll simply have a link to the MetaMask plug in. Now in the main app component, we can check to see if the user has a plug in installed by checking the window ethereum object. A plug in like Metamask will make this object available automatically when it's installed. Now the next thing I'll do is create a new component called wallet balance. And inside of it, We can start interacting with ethers. Js, which is a JavaScript library that makes it easy to communicate between the smart contract and in end user's wallet. In this component, what we wanna do is get the end user's current balance. We'll first set up state with the use state hook and then define a function called GitBalance. We can get the connected account on the window Ethereum object and then we use ethers. Js to create a new web 3 provider. The provider provides all kinds of or methods for interacting with the Blockchain. One of which is getBalance, which then takes the account as its argument. That will return the wallet balance of the connected account, which should be 10,000 ether, but it's in a big number format. So ethers also provides a utility to format the ether value, which we can use when setting the balance on on the component. And now we can call this function when a button is clicked and show the balance value in the UI. Now let's go ahead and declare the wallet balance component in the main component and then we can serve the app locally by running npm run dev. I've also added Bootstrap to my project to make things look a little nicer, but the end result should of a button that, when clicked, updates the balance in the UI. That's how we can use Ethers to interact with the wallet, but now how do we interact with the smart contract? We'll first need to import the contract ABI from the artifacts directory. Now earlier, when you compiled your contract and ran the sample script, it should have said contract deployed to an address in the terminal. Let's go ahead and take that contract address and set it up as a global variable here in our code. We can then instantiate a web 3 provider again and use it to get the signer to execute transactions on the blockchain. From there, we can use ethers to instantiate the contract using the address, the ABI and the signer. What we wanna do next is loop over all of the NFT images in the collection. Each one of those images will have a button to mint it. Or if it's already been minted, the owner can view the token URI for the NFT. We'll first need to know how many tokens have already been minted, and to do that, I'm setting up a function here called get count that calls the contract count method that we implemented in solidity earlier. We'll then call this function when the component is first initialized with the useEffect hook. In the JSX, I'm looping over every token that's been minted so far. For each one of those items, I'm rendering a a component called nft image that takes the index as a prop, which conveniently matches the token ID. Now, in the nft image component, I'm adding a property for the content ID. This content ID comes from pinata. Remember, I uploaded all my graphics to a folder in pinata. We can combine the content ID with the token ID to reference that JSON metadata URI. Now, when it comes to the actual image, I tried to use that pinata cloud gateway, but I didn't Find this to be very reliable. I often had broken images, so currently, I'm referencing my images here locally. Now, as we loop over these images, we need to figure out if each metadata URI I has been minted yet. For that, I'm going to set up state on the component of isMinted and then define a function called getMintedStatus that will run the is content own method on the smart contract itself, and then we'll run that function with the useEffect hook. And now we've reached the point where we can actually mint the token. I'm creating another function to handle that, and inside the body, the first thing it will do is make a connection between the contract and the signer. That will give us access to the recipient's to wallet address. We then call the pay to mint method on the smart contract and pass the address as well as the metadata URI as arguments. In addition, we need to set the value of ether that the user will pay. For that, we pass an object with a value of the amount of ether, which in this case will be 0.05. You may notice how this code is basically identical all to the code we wrote in our unit test earlier. From there, we can wait for the result to be mined, after which point we can call that get minted status function again, and this time it should say that metadata URI has been minted. Now, it's just a matter of using some conditional logic in the JSX to show the image URI if it's already been minted. Otherwise, we'll just show a mystery placeholder and then we'll also show the option to mint the token if it's not already minted. Otherwise, it will say that NFT is taken. Now at this point, if all went well, you should be able to go to the application and When you click the mint button, it will bring up MetaMask confirming that you want to transfer 0.05 ether and will then complete the transaction after you confirm of it. Congratulations, you just built a basic web 3 app. Let's take a quick break to appreciate it. It's Britney, bitch. Now we can move on to phase 7, deployment. This app is by no means production ready and would cost a lot of money to deploy it to the Ethereum mainnet. But one thing we can do is deploy it to a testnet to see how it would work in the real world. A free tool that can help us do that is Alchemy. The majority of serious web 3 applications use tools like Alchemy and Infura, which are platforms that can help make decentralized apps more reliable. What we're going to do is use Alchemy to deploy our contract to a test net. When you create an account, it will give you the option to create a new application, and I'm going to use the Polygon chain with the Polygon Mumbai network. Polygon, by the way, is a blockchain built on top of Ethereum that is faster unless expensive. Its native token, MATIC, is very similar to ether. For this tutorial, you can think of MATIC and ether as being the same basic thing. Once the app is created, you'll notice it gives you a link to the network. Go ahead and copy that. Now go back to the hardhat config file in your source code. You'll need a new entry under networks, which in this case will be Matic, and point it to the URL that you just copied. The other thing you'll need is a private key for your account. Go over to MetaMask and switch the network to Mumbai, then from the menu, click account details and export your private key, then paste it into the hardhat config. The reason you need a private key here is because this account will be the one that deploys the contract, but deploying a contract isn't free and currently there is 0 MATIC in as wallet. To get some free test money, we'll need to go to the Polygon faucet and add our public wallet address there, and after a few minutes of waiting, you should magically see some MATIC appear in your wallet. And now we're ready for the moment of truth. From the terminal, run the hardhat deploy script again, but this time make sure the network option is set to HANA. That should deploy the contract to the Mumbai network, make sure to copy the address and update it in your front end code in the main dot JSX file. You now have a web 3 application running out in the wild, and you could follow the same basic process to deploy to the main net. I'm gonna go ahead and wrap things up there. Hopefully, that gives you a general idea of all the steps involved in building a dApp. The final thing I'll mention is that if you want to purchase these n f t's yourself, you can do so on OpenSea. E. I don't know why you ever would, but they're there if you want them. Thanks for watching, and I will see you in the next one.
The speakers discuss the development of a web 3 application using Sol neat, including creating a directory of contracts and updating paths for the blockchain. They recommend using a tool called in Zeppelin and suggest using it for creating a smart contract. They also discuss the use of Ecf to interact with the wallet and smart contract, including setting up state and setting up a wallet balance. The speakers emphasize the importance of metadata in the creation of the NFT and provide a video on building a web 3 application and testing code. They also discuss the use of Ecf to deploy a contract to a test net and the need for a private key for the account.