As we now live in a rollup-centric world, minting an NFT on Ethereum Mainnet (L1) is getting less and less relevant. zkSync 2.0 public testnet went live in February 2022, so let's just give it a try!
Please note that zkSync 2.0 Mainnet is not available yet, but the whole community is waiting for the announcement. When it's out, you'll be ready to deploy your NFT contract.
We'll work with this Github repository, you can go ahead and clone or fork it:
https://github.com/julienbrg/zksync-minter
I mainly used zkSync 2.0 quickstart.
Prerequisites
Please make sure you have the two following tools in place:
Add your own keys
Rename the .env.example
to .env
. To run the app, you need these three keys to be valid.
Web3 Storage
As you might know, Web3 Storage uses IPFS and Filecoin. We'll use that to store the metadata of our NFT in a rather persistent way.
Infura
You can signup and get a project ID directly on Infura's website: https://infura.io/
Wallet private key
From your ArgentX browser wallet, you can export one of your accounts' private key. Make sure you have a handful of Goerli ETH on this wallet.
Now you can
yarn
Edit the NFT smart contract
In case if your new, an NFT is just a unique digital object. Wether it's a gaming asset, a ticket to a party or an artwork, it most often can be transferred, that's the main feature of an NFT.
I used the Contracts Wizard provided by the all mighty OpenZeppelin team.
It's a very basic ERC-721 contract. In the constructor, you attach the NFT metadata, mint the ID 1, transfer it to yourself and then revoke the ownership of the contract so that absolutely nobody can mint another NFT with this contract (including yourself).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Thistle is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
constructor(string memory uri) ERC721("Thistle", "THISTLE") {
safeMint(msg.sender, 1, uri);
renounceOwnership();
}
function _baseURI() internal pure override returns (string memory) {
return "https://ipfs.io/ipfs/";
}
function safeMint(
address to,
uint256 tokenId,
string memory uri
) public onlyOwner {
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
function _burn(uint256 tokenId)
internal
override(ERC721, ERC721URIStorage)
{
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
}
You can change the name of the contract (Thistle
), and also the name and symbol of the NFT in ERC721("Thistle", "THISTLE")
.
Once you've done that, your contract is ready.
You can:
yarn hardhat compile
Edit the NFT metadata
In the nft
directory, open the metadata.json
file and edit this file exactly like you want. You can use Web3.Storage to store an image and paste the url as the value of image
.
Deploy
yarn hardhat deploy-zksync
You should get something like this:
Now you can copy the address of your contract and paste in the search bar of the zkSync 2.0 explorer. Here's my deployment transaction:
You have deployed your NFT contract to zkSync 2.0 testnet and minted 1 NFT! 🎉
You now hold this NFT in your wallet. The tx was confirmed within 3 seconds. If we were on Mainnet it would have costed less than 0.02 USD equivalent.
When the time's right, you'll be able to:
- move your NFT to Ethereum Mainnet (L1)
- move it to another L2
- build an interface to sell it using the zkSync development toolbox
- add a personalized IP license using Āto
- store it safely using Argent
If you have any question, feel free to call me or file an issue.
Thanks for reading!
Photo by Jay Mantri
Top comments (0)