Base page for NFT minting built on Moonbeam

  • Installed Node.js
  • Metamask extension in the browser

Project setup

  1. Creating a new project
npx create-next-app digital-marketplace
cd digital-marketplace

npm install ethers hardhat @nomiclabs/hardhat-waffle \
ethereum-waffle chai @nomiclabs/hardhat-ethers \
web3modal @openzeppelin/contracts ipfs-http-client@50.1.2 \
axios

Setting up Tailwind CSS

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
/* tailwind.config.js */
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
@tailwind base;
@tailwind components;
@tailwind utilities;

Setting up Hardhat

npx hardhat
require("@nomiclabs/hardhat-waffle")
const fs = require('fs')
const privateKey = fs.readFileSync(".secret").toString().trim() || "01234567890123456789"

module.exports = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 1337
},
Moonbeam: {
url: "https://rpc.api.moonbeam.network",
accounts: [privateKey]
},
Moonriver: {
url: "https://rpc.api.moonriver.moonbeam.network",
accounts: [privateKey]
},
MoonbaseAlpha: {
url: "https://rpc.api.moonbase.moonbeam.network",
accounts: [privateKey]
}
},
solidity: {
version: "0.8.4",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}
}

Smart Contracts

// contracts/NFT.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.3;

import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "hardhat/console.sol";

contract NFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

constructor() ERC721("Moonbeam Test NFT", "MTN") {
}

function createToken(string memory tokenURI) public {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();

_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
}
}

Testing smart contracts

/* test/sample-test.js */
describe("NFTMarket", function() {
it("Should create and execute market sales", async function() {
/* deploy contract */
const NFT = await ethers.getContractFactory("NFT")
const nft = await NFT.deploy()
await nft.deployed()
const nftContractAddress = nft.address

/*get test minter address*/
const [_, minterAddress] = await ethers.getSigners()

/* mint tokens */
const txid1 = await nft.connect(minterAddress).createToken("https://www.mytokenlocation.com")
const txid1 = await nft.connect(minterAddress).createToken("https://www.mytokenlocation2.com")

console.log('NFT Contract Address: ', nftContractAddress)
console.log('txid1: ', txid1)
console.log('txid2: ', txid2)
})
})

Building the front end

import '../styles/globals.css'function MyApp({ Component, pageProps }) {
return (
<div>
<nav className="border-b p-6">
<p className="text-4xl font-bold">Moonbeam NFT</p>
</nav>
<Component {...pageProps} />
</div>
)
}
export default MyApp
import { useState } from 'react'
import { ethers } from 'ethers'
import { create as ipfsHttpClient } from 'ipfs-http-client'
import { useRouter } from 'next/router'
import Web3Modal from 'web3modal'

const client = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0')

import {
nftaddress
} from '../config'

import NFT from '../artifacts/contracts/NFT.sol/NFT.json'

export default function CreateItem() {
const [fileUrl, setFileUrl] = useState(null)
const [formInput, updateFormInput] = useState({ price: '', name: '', description: '' })
const router = useRouter()

async function onChange(e) {
const file = e.target.files[0]
try {
const added = await client.add(
file,
{
progress: (prog) => console.log(`received: ${prog}`)
}
)
const url = `https://ipfs.infura.io/ipfs/${added.path}`
setFileUrl(url)
} catch (error) {
console.log('Error uploading file: ', error)
}
}
async function createAndMintNFT() {
const { name, description } = formInput
if (!name || !description || !fileUrl) return
const data = JSON.stringify({
name, description, image: fileUrl
})
try {
const added = await client.add(data)
const url = `https://ipfs.infura.io/ipfs/${added.path}`
const web3Modal = new Web3Modal()
const connection = await web3Modal.connect()
const provider = new ethers.providers.Web3Provider(connection)
const signer = provider.getSigner()

let contract = new ethers.Contract(nftaddress, NFT.abi, signer)
let transaction = await contract.createToken(url)
await transaction.wait()
router.push('/')
} catch (error) {
console.log('Error uploading file: ', error)
}
}

async function createSale(url) {

}

return (
<div className="flex justify-center">
<div className="w-1/2 flex flex-col pb-12">
<input
placeholder="Asset Name"
className="mt-8 border rounded p-4"
onChange={e => updateFormInput({ ...formInput, name: e.target.value })}
/>
<textarea
placeholder="Asset Description"
className="mt-2 border rounded p-4"
onChange={e => updateFormInput({ ...formInput, description: e.target.value })}
/>
<input
placeholder="Asset Price"
className="mt-2 border rounded p-4"
onChange={e => updateFormInput({ ...formInput, price: e.target.value })}
/>
<input
type="file"
name="Asset"
className="my-4"
onChange={onChange}
/>
{
fileUrl && (
<img className="rounded mt-4" width="350" src={fileUrl} />
)
}
<button onClick={createAndMintNFT} className="font-bold mt-4 bg-pink-500 text-white rounded p-4 shadow-lg">
Mint NFT
</button>
</div>
</div>
)
}
import {
nftaddress
} from '../config'

Project launch on local network

const hre = require("hardhat");
const fs = require('fs');
async function main() {
const NFT = await hre.ethers.getContractFactory("NFT");
const nft = await NFT.deploy(nftMarket.address);
await nft.deployed();
console.log("nft deployed to:", nft.address);
let config = `
export const nftaddress = "${nft.address}" `

let data = JSON.stringify(config)
fs.writeFileSync('config.js', JSON.parse(data))
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
npx hardhat node
npx hardhat run scripts/deploy.js --network localhost
npm run dev

Project launch on Moonbeam/Moonbase Alpha/Moonriver

npx hardhat run scripts/deploy.js --network MoonbaseAlpha
npx hardhat run scripts/deploy.js --network Moonriver
npx hardhat run scripts/deploy.js --network Moonbeam

Thanks for reading and good luck!

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Starting with Flutter: Lists

We’ve been writing numbers wrong

Distributed Aggregation Queries — A Rockset Intern Story

Resolving intra-project imports in Python — A simple guide — PyCharm

My relationship with coding

How to setup SwiftLint in your project.

Python Packages Commonly Used Together

How PagoNxt’s cloud-nativeness is allowing our payment services to prosper

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
AlexM

AlexM

More from Medium

Status update Jan 24, 2022

Parachains; Polkadot’s Gameplan

How to Add Liquidity for Wrapped XRP (wXRP) on SushiSwap

Introducing the BaconCoin token, BACON