npm init
to initialize the project. If you don’t already have npm installed, follow these instructions (we’ll also need Node.js, so download that too!).my-nft
project folder, then run:hardhat.config.js
file for us which is where we’ll specify all of the set up for our project (on step 13).contracts/
is where we’ll keep our NFT smart contract codescripts/
is where we’ll keep scripts to deploy and interact with our smart contractnpm install @openzeppelin/[email protected]
@openzeppelin/contracts/token/ERC721/ERC721.sol
contains the implementation of the ERC721 standard, which our NFT smart contract will inherit. (To be a valid NFT, your smart contract must implement all the methods of the ERC721 standard.) To learn more about the inherited ERC721 functions, check out the interface definition here.@openzeppelin/contracts/utils/Counters.sol
provides counters that can only be incremented or decremented by one. Our smart contract uses a counter to keep track of the total number of NFTs minted and set the unique ID to our new NFT. Each NFT minted using a smart contract must be assigned a unique ID—here our unique ID is just determined by the total number of NFTs in existance. For example, the first NFT we mint with our smart contract has an ID of "1," our second NFT has an ID of "2," etc.@openzeppelin/contracts/access/Ownable.sol
sets up access control on our smart contract, so only the owner of the smart contract (you) can mint NFTs. Note, including access control is entirely a preference. If you'd like anyone to be able to mint an NFT using your smart contract, remove the word Ownable
on line 10 and onlyOwner
on line 17.ownerOf
(returns the owner of the NFT) and transferFrom
(transfers ownership of the NFT).mintNFT()
that allows us to mint an NFT! You'll notice this function takes in two variables:address recipient
specifies the address that will receive your freshly minted NFTstring memory tokenURI
is a string that should resolve to a JSON document that describes the NFT's metadata. An NFT's metadata is really what brings it to life, allowing it to have additional properties, such as a name, description, image, and other attributes. In part 2 of this tutorial, we will describe how to configure this metadata.mintNFT
calls some methods from the inherited ERC721 library, and ultimately returns a number that represents the ID of the freshly minted NFT..env
file in the root directory of our project, and add your Metamask private key and HTTP Alchemy API URL to it..env
file must be named .env
! Do not change the name to xx.env
.env
should look like this:hardhat.config.js
file on step 13.hardhat.config.js
in the next step.hardhat.config.js
so that our project knows about all of them.hardhat.config.js
to look like this:compile
task is one of the built-in hardhat tasks.SPDX license identifier not provided in source file
, but no need to worry about that — hopefully everything else looks good! If not, you can always message in the Alchemy discord.scripts/
folder and create a new file called deploy.js
, adding the following contents to it:ContractFactory
in ethers.js is an abstraction used to deploy new smart contracts, so MyNFT here is a factory for instances of our NFT contract. When using the hardhat-ethers
plugin ContractFactory
and Contract
instances are connected to the first signer by default.deploy()
on a ContractFactory
will start the deployment, and return a Promise
that resolves to a Contract
. This is the object that has a method for each of our smart contract functions.From
address should match your Metamask account address and the To address will say “Contract Creation.” If we click into the transaction, we’ll see our contract address in the To
field:.deploy()
function.eth_sendRawTransaction
, which is the request to actually write our smart contract onto the Ropsten chain, and eth_getTransactionByHash
which is a request to read information about our transaction given the hash (a typical pattern when sending transactions).