diff --git a/README.md b/README.md index 5f617e5..a5eb95e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Demo NFT collection for learning purposes. +https://testnets.opensea.io/collection/squarenft-lsikgsvytr + ## Built With - [Solidity](https://soliditylang.org/) diff --git a/contracts/EpicNFT.sol b/contracts/EpicNFT.sol index 45eac13..8db7853 100644 --- a/contracts/EpicNFT.sol +++ b/contracts/EpicNFT.sol @@ -2,9 +2,22 @@ pragma solidity ^0.8.0; import "hardhat/console.sol"; +import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; -contract EpicNFT { - constructor() { - console.log("My first NFT contract!"); +contract EpicNFT is ERC721URIStorage { + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + constructor() ERC721("SquareNFT", "SQUARE") { + console.log("My first NFT contract! EPIC!!!"); + } + + function mint() public { + uint256 tokenID = _tokenIds.current(); + _safeMint(msg.sender, tokenID); + _setTokenURI(tokenID, "https://jsonkeeper.com/b/EU51"); // points to the metadata JSON file + console.log("NFT %s minted to %s", tokenID, msg.sender); + _tokenIds.increment(); } } diff --git a/hardhat.config.js b/hardhat.config.js index 20a3341..20964b2 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,4 +1,5 @@ require("@nomiclabs/hardhat-waffle"); +require("dotenv").config(); task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { const accounts = await hre.ethers.getSigners(); @@ -13,4 +14,14 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { */ module.exports = { solidity: "0.8.4", + networks: { + rinkeby: { + url: process.env.STAGING_URL, + accounts: [process.env.PRIVATE_KEY], + }, + mainnet: { + url: process.env.PROD_URL, + accounts: [process.env.PRIVATE_KEY], + }, + }, }; diff --git a/package.json b/package.json index 3adac09..d11ad3b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "main": "index.js", "license": "MIT", "scripts": { - "dev": "npx hardhat run scripts/run.js" + "dev": "npx hardhat run scripts/run.js", + "deploy:testnet": "npx hardhat run scripts/deploy.js --network rinkeby", + "test": "npx hardhat test" }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.0", @@ -15,6 +17,7 @@ "hardhat": "^2.9.3" }, "dependencies": { - "@openzeppelin/contracts": "^4.5.0" + "@openzeppelin/contracts": "^4.5.0", + "dotenv": "^16.0.0" } } diff --git a/scripts/deploy.js b/scripts/deploy.js new file mode 100644 index 0000000..1ff8537 --- /dev/null +++ b/scripts/deploy.js @@ -0,0 +1,27 @@ +const { ethers } = require("hardhat"); // this import is optional + +async function main() { + const EpicNFT = await ethers.getContractFactory("EpicNFT"); + const contract = await EpicNFT.deploy(); + await contract.deployed(); + console.log("EpicNFT deployed to:", contract.address); + + let txn = await contract.mint(); + txn.wait(); + console.log("Mint NFT #1") + + txn = await contract.mint(); + txn.wait(); + console.log("Mint NFT #2") +} + +// run the script +(async () => { + try { + await main(); + process.exit(0); + } catch (err) { + console.error(err); + process.exit(1); + } +})(); diff --git a/scripts/run.js b/scripts/run.js index b601dd0..7b84be9 100644 --- a/scripts/run.js +++ b/scripts/run.js @@ -1,12 +1,19 @@ -const hre = require("hardhat"); // this import is optional +const { ethers } = require("hardhat"); // this import is optional async function main() { - const EpicNFT = await hre.ethers.getContractFactory("EpicNFT"); + const EpicNFT = await ethers.getContractFactory("EpicNFT"); const contract = await EpicNFT.deploy(); await contract.deployed(); console.log("EpicNFT deployed to:", contract.address); + + let txn = await contract.mint(); + txn.wait(); + + txn = await contract.mint(); + txn.wait(); } +// run the script (async () => { try { await main(); diff --git a/test/epicNFT.spec.js b/test/epicNFT.spec.js new file mode 100644 index 0000000..80c71ce --- /dev/null +++ b/test/epicNFT.spec.js @@ -0,0 +1,14 @@ +const { expect } = require("chai"); +const { ethers } = require("hardhat"); + +describe("EpicNFT", function () { + it("Should increment token count after each mint", async () => { + const EpicNFT = await ethers.getContractFactory("EpicNFT"); + const contract = await EpicNFT.deploy(); + await contract.deployed(); + const txn = await contract.mint(); + txn.wait(); + + expect(contract._tokenIds).to.equal(1); + }); +}); diff --git a/test/run.js b/test/run.js deleted file mode 100644 index 44e0fcb..0000000 --- a/test/run.js +++ /dev/null @@ -1,19 +0,0 @@ -const { expect } = require("chai"); -const { ethers } = require("hardhat"); - -describe("Greeter", function () { - it("Should return the new greeting once it's changed", async function () { - const Greeter = await ethers.getContractFactory("Greeter"); - const greeter = await Greeter.deploy("Hello, world!"); - await greeter.deployed(); - - expect(await greeter.greet()).to.equal("Hello, world!"); - - const setGreetingTx = await greeter.setGreeting("Hola, mundo!"); - - // wait until the transaction is mined - await setGreetingTx.wait(); - - expect(await greeter.greet()).to.equal("Hola, mundo!"); - }); -}); diff --git a/yarn.lock b/yarn.lock index 1569dfc..e3a4943 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2556,6 +2556,11 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== +dotenv@^16.0.0: + version "16.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411" + integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q== + dotignore@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905"