diff --git a/erc721-solidity-101/.DS_Store b/erc721-solidity-101/.DS_Store new file mode 100644 index 0000000..f7d5e4f Binary files /dev/null and b/erc721-solidity-101/.DS_Store differ diff --git a/erc721-solidity-101/.env_sample b/erc721-solidity-101/.env_sample new file mode 100644 index 0000000..f93641e --- /dev/null +++ b/erc721-solidity-101/.env_sample @@ -0,0 +1,5 @@ +API_URL = "https://eth-rinkeby.alchemyapi.io/v2/" +PUBLIC_KEY = +PRIVATE_KEY = +METADATA_URL = " +CONTRACT_ADDRESS = diff --git a/erc721-solidity-101/README.md b/erc721-solidity-101/README.md new file mode 100644 index 0000000..85395a3 --- /dev/null +++ b/erc721-solidity-101/README.md @@ -0,0 +1,20 @@ +# One: A special summer + + +1. Compile contract: + +``` +npx hardhat compile +``` + +2. Deploy contract: + +``` +npx hardhat run scripts/deploy-contract.js --network rinkeby +``` + +3. Mint NFT: + +``` +node scripts/mint-nft.js +``` \ No newline at end of file diff --git a/erc721-solidity-101/contracts/MiaNFT.sol b/erc721-solidity-101/contracts/MiaNFT.sol new file mode 100644 index 0000000..1bb8d51 --- /dev/null +++ b/erc721-solidity-101/contracts/MiaNFT.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.3 <0.9.0; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + + +contract MiaNFT is ERC721, Ownable { + + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + constructor() public ERC721("Mia's NFT, "NFT") {} + + function mintNFT(address recipient, string memory tokenURI) + public onlyOwner + returns (uint256) + { + _tokenIds.increment(); + + uint256 newItemId = _tokenIds.current(); + _mint(recipient, newItemId); + _setTokenURI(newItemId, tokenURI); + + return newItemId; + } +} \ No newline at end of file diff --git a/erc721-solidity-101/hardhat.config.js b/erc721-solidity-101/hardhat.config.js new file mode 100644 index 0000000..8b52766 --- /dev/null +++ b/erc721-solidity-101/hardhat.config.js @@ -0,0 +1,19 @@ +/** +* @type import('hardhat/config').HardhatUserConfig +*/ +require('dotenv').config(); +require("@nomiclabs/hardhat-ethers"); + +const { API_URL, PRIVATE_KEY } = process.env; + +module.exports = { + solidity: "0.7.3", + defaultNetwork: "rinkeby", + networks: { + hardhat: {}, + rinkeby: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`] + } + }, +} diff --git a/erc721-solidity-101/package.json b/erc721-solidity-101/package.json new file mode 100644 index 0000000..a863d5e --- /dev/null +++ b/erc721-solidity-101/package.json @@ -0,0 +1,23 @@ +{ + "name": "MiaNFT", + "version": "1.0.0", + "description": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Mia von Steinkirch", + "license": "MIT", + "devDependencies": { + "@nomiclabs/hardhat-ethers": "^2.0.2", + "@nomiclabs/hardhat-waffle": "^2.0.1", + "@openzeppelin/contracts": "^3.1.0-solc-0.7", + "chai": "^4.3.4", + "ethereum-waffle": "^3.4.0", + "ethers": "^5.4.6", + "hardhat": "^2.6.2" + }, + "dependencies": { + "@alch/alchemy-web3": "^1.1.4", + "dotenv": "^10.0.0" + } +} diff --git a/erc721-solidity-101/scripts/deploy-contract.js b/erc721-solidity-101/scripts/deploy-contract.js new file mode 100644 index 0000000..630b540 --- /dev/null +++ b/erc721-solidity-101/scripts/deploy-contract.js @@ -0,0 +1,14 @@ +async function main() { + const nft = await ethers.getContractFactory("MiaNFT"); + + const nft_deploy = await nft.deploy(); + console.log(" ⛓🧱✨ Contract address:", nft_deploy.address); + console.log(" ➡️ (Please add this string to .env)"); +} + +main() + .then(() => process.exit(0)) + .catch(e => { + console.error(e); + process.exit(1); + }); diff --git a/erc721-solidity-101/scripts/mint-nft.js b/erc721-solidity-101/scripts/mint-nft.js new file mode 100644 index 0000000..f4333b9 --- /dev/null +++ b/erc721-solidity-101/scripts/mint-nft.js @@ -0,0 +1,41 @@ +require('dotenv').config(); + +const PUBLIC_KEY = process.env.PUBLIC_KEY; +const PRIVATE_KEY = process.env.PRIVATE_KEY; +const API_URL = process.env.API_URL; +const METADATA_URL = process.env.METADATA_URL; +const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS; +const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); +const web3 = createAlchemyWeb3(API_URL); +const contract = require("../artifacts/contracts/MiaNFT.sol/MiaNFT.json"); +const nftContract = new web3.eth.Contract(contract.abi, CONTRACT_ADDRESS); + +async function mintNFT(tokenURI) { + + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); + + const transaction = { + 'from': PUBLIC_KEY, + 'to': CONTRACT_ADDRESS, + 'nonce': nonce, + 'gas': 500000, + 'maxPriorityFeePerGas': 1999999987, + 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI() + }; + + const sign = web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY); + sign.then((signedTransaction) => { + + web3.eth.sendSignedTransaction(signedTransaction.rawTransaction, function(e, hash) { + if (!e) { + console.log("💾 Transaction hash: ", hash); + } else { + console.log("ERROR:", e) + } + }); + }).catch((e) => { + console.log("ERROR:", e); + }); +} + +mintNFT(METADATA_URL);