├── .gitignore ├── .vscode └── settings.json ├── README.md ├── contracts ├── EternalNFT.sol ├── Lock.sol └── libraries │ └── Base64.sol ├── frontend ├── .eslintrc.json ├── .gitignore ├── README.md ├── app │ ├── favicon.ico │ ├── globals.css │ ├── layout.js │ └── page.js ├── config.js ├── jsconfig.json ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public │ ├── next.svg │ ├── screenshot.PNG │ └── vercel.svg ├── tailwind.config.js └── utils │ └── EternalNFT.json ├── hardhat.config.cjs ├── ignition └── modules │ └── Lock.js ├── package-lock.json ├── package.json ├── scripts └── deploy.js └── test └── EternalNFT-test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | 132 | node_modules 133 | .env 134 | 135 | # Hardhat files 136 | /cache 137 | /artifacts 138 | 139 | # TypeChain files 140 | /typechain 141 | /typechain-types 142 | 143 | # solidity-coverage files 144 | /coverage 145 | /coverage.json 146 | 147 | # Hardhat Ignition default folder for deployments against a local node 148 | ignition/deployments/chain-31337 149 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "solidity.compileUsingRemoteVersion": "v0.8.24+commit.e11b9ed9" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FullStack-NFT-minting-dApp 2 | 3 | A full stack dApp starter for minting NFTs built on Ethereum (Solidity) with Next.js (React). 4 | 5 | ## Table of Contents 6 | - [Deployed Website url](#deployed-website-url) 7 | - [Deployed Contract Address](#deployed-contract-address) 8 | - [Project Description](#project-description) 9 | - [Workflow](#workflow) 10 | - [Directory structure](#directory-structure) 11 | - [Clone, Install and Build steps](#clone-install-and-build-steps) 12 | - [Prerequisites](#prerequisites) 13 | - [Cloning and installing dependencies](#cloning-and-installing-dependencies) 14 | - [Testing Contracts](#testing-contracts) 15 | - [Running the frontend](#running-the-frontend) 16 | 17 | 18 | ## Deployed Website url 19 | 20 | https://eternal-nft.vercel.app/ 21 | 22 | ## Deployed Contract Address 23 | 24 | 0x9b6dd9b898c300037c8C245e8E619a0934158065 25 | 26 | ## Project Description 27 | 28 | A dapp to mint your own text-based **Eternal Character NFT**. 29 | 30 | **Eternal Characters** are the residents of **Eternal Domain world**. They consist of 3 main characteristics, Area of Control, Weapon and Rank. 31 | 32 | **Area of Control -** Fire, Wind, Wave, Earth, Light, Shadow, Thunder, Space, Time, Gravity, Ice 33 | **Weapon -** Sword, Spear, Shield, Hammer, Saber, Axe, Bow, Staff, Wand, Fist, Dagger, Scythe, Mace, Blade, Katana 34 | **Rank -** Lord, King, Emperor, Venerable, Ancestor, Saint, God 35 | 36 | ## Workflow 37 | 38 | 1. Enter the dApp and connect the wallet to rinkeby network. 39 | 2. Click on the Mint Character button. 40 | 3. Metamask pops up and asks to confirm the transaction. 41 | 4. After the transaction is successfully processed the user can see the minted character. 42 | 5. The minted character is also added to My NFT page under Minted Characters section. 43 | 44 | ## Directory structure 45 | 46 | ``` 47 | EternalNFT 48 | ┣ frontend 49 | ┃ ┣ app 50 | ┃ ┃ ┃ favicon.ico 51 | ┃ ┃ ┃ globals.css 52 | ┃ ┃ ┃ layout.js 53 | ┃ ┃ ┗ page.js 54 | ┃ ┣ public 55 | ┃ ┃ ┃ next.svg 56 | ┃ ┃ ┃ screenshot.png 57 | ┃ ┃ ┗ vercel.svg 58 | ┃ ┣ utils 59 | ┃ ┃ ┗ EternalNFT.json 60 | ┃ ┣ .gitignore 61 | ┃ ┣ README.md 62 | ┃ ┣ config.js 63 | ┃ ┣ package-lock.json 64 | ┃ ┣ package.json 65 | ┃ ┣ postcss.config.js 66 | ┃ ┗ tailwind.config.js 67 | ┣ contracts 68 | ┃ ┣ libraries 69 | ┃ ┃ ┗ Base64.sol 70 | ┃ ┗ EternalNFT.sol 71 | ┣ scripts 72 | ┃ ┗ deploy.js 73 | ┣ test 74 | ┃ ┗ EternalNFT-test.js 75 | ┣ .gitignore 76 | ┣ README.md 77 | ┣ hardhat.config.js 78 | ┣ package-lock.json 79 | ┗ package.json 80 | ``` 81 | 82 | ## Clone, Install and Build steps 83 | 84 | ### Prerequisites 85 | 86 | 1. [Git](https://git-scm.com/) 87 | 2. [Node JS](https://nodejs.org/en/) (everything was installed and tested under v15.12.0) 88 | 3. A Browser with the [MetaMask extension](https://metamask.io/) installed. 89 | 4. Test Ether on the Rinkeby network. 90 | 91 |
92 | 93 | ### Cloning and installing dependencies 94 | 95 | 1. Clone the project repository on your local machine 96 | 97 | ``` 98 | git clone https://github.com/imcrazysteven/FullStack-NFT-minting-dApp.git 99 | cd FullStack-NFT-minting-dApp 100 | ``` 101 | 102 | 2. Installing dependencies 103 | 104 | - For contracts - 105 | ``` 106 | npm install 107 | ``` 108 | - For client - 109 | ``` 110 | cd client 111 | npm install 112 | ``` 113 | 114 | ### Testing Contracts 115 | 116 | For testing contracts run command: 117 | 118 | ``` 119 | npx hardhat test 120 | ``` 121 | 122 | ### Running the frontend 123 | 124 | For running frontend locally run command: 125 | 126 | ``` 127 | cd client 128 | npm run dev 129 | ``` 130 | 131 | ### Environment variables (not needed for running project locally) 132 | 133 | ``` 134 | ALCHEMY_RINKEBY_URL = 135 | ACCOUNT_KEY = 136 | ``` 137 | -------------------------------------------------------------------------------- /contracts/EternalNFT.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier:MIT 2 | pragma solidity ^0.8.24; 3 | 4 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; 5 | import {Base64} from "./libraries/Base64.sol"; 6 | 7 | contract EternalNFT is ERC721URIStorage { 8 | uint256 private _tokenId; 9 | string public collectionName; 10 | string public collectionSymbol; 11 | 12 | string baseSvg = 13 | ""; 14 | 15 | string[] element = [ 16 | "Fire", 17 | "Wind", 18 | "Wave", 19 | "Earth", 20 | "Thunder", 21 | "Space", 22 | "Time" 23 | ]; 24 | string[] weapon = [ 25 | "Sword", 26 | "Spear", 27 | "Shield", 28 | "Hammer", 29 | "Saber", 30 | "Axe", 31 | "Bow" 32 | ]; 33 | 34 | string[] rank = [ 35 | "Lord", 36 | "King", 37 | "Emperor", 38 | "Venerable", 39 | "Ancestor", 40 | "Saint", 41 | "God" 42 | ]; 43 | 44 | constructor() ERC721("EternalNFT", "ENFT") { 45 | collectionName = name(); 46 | collectionSymbol = symbol(); 47 | } 48 | 49 | function random(string memory _input) internal pure returns (uint256) { 50 | return uint256(keccak256(abi.encodePacked(_input))); 51 | } 52 | 53 | function pickFirstWord( 54 | uint256 tokenId 55 | ) public view returns (string memory) { 56 | uint256 rand = random( 57 | string(abi.encodePacked("element", Strings.toString(tokenId))) 58 | ); 59 | rand = rand % element.length; 60 | return element[rand]; 61 | } 62 | 63 | function pickSecondWord( 64 | uint256 tokenId 65 | ) public view returns (string memory) { 66 | uint256 rand = random( 67 | string(abi.encodePacked("weapon", Strings.toString(tokenId))) 68 | ); 69 | rand = rand % weapon.length; 70 | return weapon[rand]; 71 | } 72 | 73 | function pickThirdWord( 74 | uint256 tokenId 75 | ) public view returns (string memory) { 76 | uint rand = random( 77 | string(abi.encodePacked("rank", Strings.toString(tokenId))) 78 | ); 79 | rand = rand % rank.length; 80 | return rank[rand]; 81 | } 82 | 83 | function createEternalNFT() public returns (uint256) { 84 | uint256 newItemId = _tokenId; 85 | 86 | string memory first = pickFirstWord(newItemId); 87 | string memory second = pickSecondWord(newItemId); 88 | string memory third = pickThirdWord(newItemId); 89 | string memory combinedWord = string( 90 | abi.encodePacked(first, second, third) 91 | ); 92 | 93 | string memory finalSvg = string( 94 | abi.encodePacked(baseSvg, first, second, third, "") 95 | ); 96 | 97 | string memory json = Base64.encode( 98 | bytes( 99 | string( 100 | abi.encodePacked( 101 | '{"name": "', 102 | combinedWord, 103 | '", "description": "A highly acclaimed collection Eternal Warriors", "image": "data:image/svg+xml;base64,', 104 | Base64.encode(bytes(finalSvg)), 105 | '"}' 106 | ) 107 | ) 108 | ) 109 | ); 110 | 111 | string memory finalTokenURI = string( 112 | abi.encodePacked("data:application/json;base64,", json) 113 | ); 114 | 115 | _safeMint(msg.sender, newItemId); 116 | _setTokenURI(newItemId, finalTokenURI); 117 | 118 | _tokenId += 1; 119 | 120 | return newItemId; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /contracts/Lock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.24; 3 | 4 | // Uncomment this line to use console.log 5 | // import "hardhat/console.sol"; 6 | 7 | contract Lock { 8 | uint public unlockTime; 9 | address payable public owner; 10 | 11 | event Withdrawal(uint amount, uint when); 12 | 13 | constructor(uint _unlockTime) payable { 14 | require( 15 | block.timestamp < _unlockTime, 16 | "Unlock time should be in the future" 17 | ); 18 | 19 | unlockTime = _unlockTime; 20 | owner = payable(msg.sender); 21 | } 22 | 23 | function withdraw() public { 24 | // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal 25 | // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); 26 | 27 | require(block.timestamp >= unlockTime, "You can't withdraw yet"); 28 | require(msg.sender == owner, "You aren't the owner"); 29 | 30 | emit Withdrawal(address(this).balance, block.timestamp); 31 | 32 | owner.transfer(address(this).balance); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/libraries/Base64.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2021-09-05 3 | */ 4 | 5 | // SPDX-License-Identifier: MIT 6 | 7 | pragma solidity ^0.8.24; 8 | 9 | /// [MIT License] 10 | /// @title Base64 11 | /// @notice Provides a function for encoding some bytes in base64 12 | /// @author Brecht Devos 13 | library Base64 { 14 | bytes internal constant TABLE = 15 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 16 | 17 | /// @notice Encodes some bytes to the base64 representation 18 | function encode(bytes memory data) internal pure returns (string memory) { 19 | uint256 len = data.length; 20 | if (len == 0) return ""; 21 | 22 | // multiply by 4/3 rounded up 23 | uint256 encodedLen = 4 * ((len + 2) / 3); 24 | 25 | // Add some extra buffer at the end 26 | bytes memory result = new bytes(encodedLen + 32); 27 | 28 | bytes memory table = TABLE; 29 | 30 | assembly { 31 | let tablePtr := add(table, 1) 32 | let resultPtr := add(result, 32) 33 | 34 | for { 35 | let i := 0 36 | } lt(i, len) { 37 | 38 | } { 39 | i := add(i, 3) 40 | let input := and(mload(add(data, i)), 0xffffff) 41 | 42 | let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) 43 | out := shl(8, out) 44 | out := add( 45 | out, 46 | and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF) 47 | ) 48 | out := shl(8, out) 49 | out := add( 50 | out, 51 | and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF) 52 | ) 53 | out := shl(8, out) 54 | out := add( 55 | out, 56 | and(mload(add(tablePtr, and(input, 0x3F))), 0xFF) 57 | ) 58 | out := shl(224, out) 59 | 60 | mstore(resultPtr, out) 61 | 62 | resultPtr := add(resultPtr, 4) 63 | } 64 | 65 | switch mod(len, 3) 66 | case 1 { 67 | mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) 68 | } 69 | case 2 { 70 | mstore(sub(resultPtr, 1), shl(248, 0x3d)) 71 | } 72 | 73 | mstore(result, encodedLen) 74 | } 75 | 76 | return string(result); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | # or 14 | bun dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 20 | 21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 22 | 23 | ## Learn More 24 | 25 | To learn more about Next.js, take a look at the following resources: 26 | 27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 29 | 30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 31 | 32 | ## Deploy on Vercel 33 | 34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 35 | 36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 37 | -------------------------------------------------------------------------------- /frontend/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imcrazysteven/FullStack-NFT-minting-dApp/99baef32142d23745993b479c0a01413a95d4aa7/frontend/app/favicon.ico -------------------------------------------------------------------------------- /frontend/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | 29 | @layer utilities { 30 | .text-balance { 31 | text-wrap: balance; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /frontend/app/layout.js: -------------------------------------------------------------------------------- 1 | import { Inter } from "next/font/google"; 2 | import "./globals.css"; 3 | 4 | const inter = Inter({ subsets: ["latin"] }); 5 | 6 | export const metadata = { 7 | title: "EternalNFT", 8 | description: "This is NFT minting website", 9 | }; 10 | 11 | export default function RootLayout({ children }) { 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /frontend/app/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useState, useEffect } from 'react'; 3 | import { ethers } from 'ethers'; 4 | import axios from "axios"; 5 | import { Loader } from 'react-loader-spinner' 6 | 7 | import { nftContractAddress } from '@/config'; 8 | import NFT from '@/utils/EternalNFT.json' 9 | 10 | const Home = () => { 11 | 12 | const [mintedNFT, setMintedNFT] = useState(null); 13 | const [miningStatus, setMiningStatus] = useState(null); 14 | const [loadingState, setLoadingState] = useState(0); 15 | const [txError, setTxError] = useState(null); 16 | const [currentAccount, setCurrentAccount] = useState(''); 17 | const [isCorrectNetwork, setIsCorrectNetwork] = useState(false); 18 | 19 | const sepoliaChainId = "0xaa36a7"; 20 | const devChainId = 1337 21 | const localhostChainId = `0x${Number(devChainId).toString(16)}` 22 | 23 | //Checks if wallet is connected 24 | const checkIfWalletIsConnected = async () => { 25 | const { ethereum } = window; 26 | if (ethereum) { 27 | console.log('Got the ethereum Object: ', ethereum) 28 | } else { 29 | console.log('No Wallet found. Please connect Wallet') 30 | } 31 | 32 | const accounts = await ethereum.request({ method: 'eth_requestAccounts' }) 33 | if (accounts.length !== 0) { 34 | console.log('Found authorized Account: ', accounts[0]) 35 | } else { 36 | console.log('No authorized account found, please add account to your wallet') 37 | } 38 | } 39 | 40 | //Calls metamask to connect wallet on clicking Connect Wallet Button 41 | const connectWallet = async () => { 42 | try { 43 | const { ethereum } = window; 44 | if (!ethereum) { 45 | console.log('Metamask not detected! Please install Metamask'); 46 | return 47 | } 48 | 49 | let chainId = await ethereum.request({ method: 'eth_chainId' }); 50 | console.log('Connected to chain: ' + chainId) 51 | 52 | if (chainId !== sepoliaChainId && chainId !== localhostChainId) { 53 | alert('You are not connected to the Sepolia testnet') 54 | return 55 | } 56 | const accounts = await ethereum.request({ method: 'eth_requestAccounts' }) 57 | 58 | console.log('Found account', accounts[0]) 59 | setCurrentAccount(accounts[0]) 60 | } catch (error) { 61 | console.log('Error connecting to metamask', error) 62 | } 63 | } 64 | 65 | //Checks if wallet is connected to the correct Network 66 | const checkCorrectNetwork = async () => { 67 | const { ethereum } = window; 68 | let chainId = await ethereum.request({ method: 'eth_chainId' }); 69 | if (chainId !== sepoliaChainId && chainId !== localhostChainId) { 70 | setIsCorrectNetwork(false); 71 | } else { setIsCorrectNetwork(true) } 72 | } 73 | 74 | useEffect(() => { 75 | checkIfWalletIsConnected(); 76 | checkCorrectNetwork(); 77 | }, []) 78 | 79 | const mintCharacter = async () => { 80 | try { 81 | const { ethereum } = window; 82 | console.log("Ethereum object:", ethereum); 83 | if (ethereum) { 84 | const provider = new ethers.providers.Web3Provider(ethereum); 85 | console.log("Provider created:", provider); 86 | const signer = provider.getSigner(); 87 | console.log("Signer obtained:", signer); 88 | const nftContract = new ethers.Contract(nftContractAddress, NFT.abi, signer); 89 | let nftTx = await nftContract.createEternalNFT(); 90 | console.log('Mining...', nftTx.hash); 91 | setMiningStatus(0); 92 | let tx = await nftTx.wait(); 93 | setLoadingState(1); 94 | console.log('Mined!', tx); 95 | let event = tx.events[0]; 96 | let value = event.args[2]; 97 | let tokenId = value.toNumber(); 98 | console.log(`Mined, see transaction: https://rinkeby.etherscan.io/tx/${nftTx.hash}`); 99 | // let event = tx.events[0]; 100 | // let value = event.args[2]; 101 | // let tokenId = value.toNumber(); 102 | 103 | getMintedNFT(tokenId); 104 | } else { 105 | console.log("Ethereum object doesn't exist"); 106 | } 107 | } catch (error) { 108 | console.log('Error minting character', error); 109 | setTxError(error.message); 110 | } 111 | }; 112 | 113 | //Gets the minted NFT data 114 | const getMintedNFT = async (tokenId) => { 115 | try { 116 | const { ethereum } = window; 117 | if (ethereum) { 118 | const provider = new ethers.providers.Web3Provider(ethereum); 119 | const signer = provider.getSigner(); 120 | const nftContract = new ethers.Contract(nftContractAddress, NFT.abi, signer); 121 | 122 | let tokenURI = await nftContract.tokenURI(tokenId); 123 | let data = await axios.get(tokenURI); 124 | let meta = data.data; 125 | 126 | setMiningStatus(1); 127 | setMintedNFT(meta.image) 128 | } else { 129 | console.log("Ethereum object doesn't exist") 130 | } 131 | } catch (error) { 132 | console.log(error); 133 | setTxError(error.mesage) 134 | } 135 | } 136 | 137 | return ( 138 |
139 |
140 | 147 | 148 | 149 |
150 |

151 | Mint your Eternal Domain NFT! 152 |

153 | {currentAccount === '' ? ( 154 | 160 | ) : isCorrectNetwork ? ( 161 | 167 | ) : ( 168 |
169 |
----------------------------------------
170 |
Please connect to the Rinkeby Testnet
171 |
and reload the page
172 |
----------------------------------------
173 |
174 | )} 175 | 176 |
177 | 181 | 182 | View Collection on Rarible 183 | 184 | 185 |
186 | {loadingState === 0 ? ( 187 | miningStatus === 0 ? ( 188 | txError === null ? ( 189 |
190 |
191 | Processing your transaction 192 |
193 | 200 |
201 | ) : ( 202 |
{txError}
203 | ) 204 | ) : ( 205 |
206 | ) 207 | ) : ( 208 |
209 |
210 | Your Eternal Domain Character 211 |
212 | 217 |
218 | )} 219 |
220 | ); 221 | } 222 | 223 | export default Home -------------------------------------------------------------------------------- /frontend/config.js: -------------------------------------------------------------------------------- 1 | export const nftContractAddress = '0x9b6dd9b898c300037c8C245e8E619a0934158065' -------------------------------------------------------------------------------- /frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "axios": "^1.7.4", 13 | "ethers": "^6.13.2", 14 | "next": "14.2.5", 15 | "react": "^18", 16 | "react-dom": "^18", 17 | "react-loader-spinner": "^6.1.6" 18 | }, 19 | "devDependencies": { 20 | "eslint": "^8", 21 | "eslint-config-next": "14.2.5", 22 | "postcss": "^8", 23 | "tailwindcss": "^3.4.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /frontend/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /frontend/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/public/screenshot.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imcrazysteven/FullStack-NFT-minting-dApp/99baef32142d23745993b479c0a01413a95d4aa7/frontend/public/screenshot.PNG -------------------------------------------------------------------------------- /frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 5 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./app/**/*.{js,ts,jsx,tsx,mdx}", 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", 12 | "gradient-conic": 13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | }; 19 | -------------------------------------------------------------------------------- /frontend/utils/EternalNFT.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "EternalNFT", 4 | "sourceName": "contracts/EternalNFT.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "stateMutability": "nonpayable", 9 | "type": "constructor" 10 | }, 11 | { 12 | "inputs": [ 13 | { 14 | "internalType": "address", 15 | "name": "sender", 16 | "type": "address" 17 | }, 18 | { 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | }, 23 | { 24 | "internalType": "address", 25 | "name": "owner", 26 | "type": "address" 27 | } 28 | ], 29 | "name": "ERC721IncorrectOwner", 30 | "type": "error" 31 | }, 32 | { 33 | "inputs": [ 34 | { 35 | "internalType": "address", 36 | "name": "operator", 37 | "type": "address" 38 | }, 39 | { 40 | "internalType": "uint256", 41 | "name": "tokenId", 42 | "type": "uint256" 43 | } 44 | ], 45 | "name": "ERC721InsufficientApproval", 46 | "type": "error" 47 | }, 48 | { 49 | "inputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "approver", 53 | "type": "address" 54 | } 55 | ], 56 | "name": "ERC721InvalidApprover", 57 | "type": "error" 58 | }, 59 | { 60 | "inputs": [ 61 | { 62 | "internalType": "address", 63 | "name": "operator", 64 | "type": "address" 65 | } 66 | ], 67 | "name": "ERC721InvalidOperator", 68 | "type": "error" 69 | }, 70 | { 71 | "inputs": [ 72 | { 73 | "internalType": "address", 74 | "name": "owner", 75 | "type": "address" 76 | } 77 | ], 78 | "name": "ERC721InvalidOwner", 79 | "type": "error" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "address", 85 | "name": "receiver", 86 | "type": "address" 87 | } 88 | ], 89 | "name": "ERC721InvalidReceiver", 90 | "type": "error" 91 | }, 92 | { 93 | "inputs": [ 94 | { 95 | "internalType": "address", 96 | "name": "sender", 97 | "type": "address" 98 | } 99 | ], 100 | "name": "ERC721InvalidSender", 101 | "type": "error" 102 | }, 103 | { 104 | "inputs": [ 105 | { 106 | "internalType": "uint256", 107 | "name": "tokenId", 108 | "type": "uint256" 109 | } 110 | ], 111 | "name": "ERC721NonexistentToken", 112 | "type": "error" 113 | }, 114 | { 115 | "anonymous": false, 116 | "inputs": [ 117 | { 118 | "indexed": true, 119 | "internalType": "address", 120 | "name": "owner", 121 | "type": "address" 122 | }, 123 | { 124 | "indexed": true, 125 | "internalType": "address", 126 | "name": "approved", 127 | "type": "address" 128 | }, 129 | { 130 | "indexed": true, 131 | "internalType": "uint256", 132 | "name": "tokenId", 133 | "type": "uint256" 134 | } 135 | ], 136 | "name": "Approval", 137 | "type": "event" 138 | }, 139 | { 140 | "anonymous": false, 141 | "inputs": [ 142 | { 143 | "indexed": true, 144 | "internalType": "address", 145 | "name": "owner", 146 | "type": "address" 147 | }, 148 | { 149 | "indexed": true, 150 | "internalType": "address", 151 | "name": "operator", 152 | "type": "address" 153 | }, 154 | { 155 | "indexed": false, 156 | "internalType": "bool", 157 | "name": "approved", 158 | "type": "bool" 159 | } 160 | ], 161 | "name": "ApprovalForAll", 162 | "type": "event" 163 | }, 164 | { 165 | "anonymous": false, 166 | "inputs": [ 167 | { 168 | "indexed": false, 169 | "internalType": "uint256", 170 | "name": "_fromTokenId", 171 | "type": "uint256" 172 | }, 173 | { 174 | "indexed": false, 175 | "internalType": "uint256", 176 | "name": "_toTokenId", 177 | "type": "uint256" 178 | } 179 | ], 180 | "name": "BatchMetadataUpdate", 181 | "type": "event" 182 | }, 183 | { 184 | "anonymous": false, 185 | "inputs": [ 186 | { 187 | "indexed": false, 188 | "internalType": "uint256", 189 | "name": "_tokenId", 190 | "type": "uint256" 191 | } 192 | ], 193 | "name": "MetadataUpdate", 194 | "type": "event" 195 | }, 196 | { 197 | "anonymous": false, 198 | "inputs": [ 199 | { 200 | "indexed": true, 201 | "internalType": "address", 202 | "name": "from", 203 | "type": "address" 204 | }, 205 | { 206 | "indexed": true, 207 | "internalType": "address", 208 | "name": "to", 209 | "type": "address" 210 | }, 211 | { 212 | "indexed": true, 213 | "internalType": "uint256", 214 | "name": "tokenId", 215 | "type": "uint256" 216 | } 217 | ], 218 | "name": "Transfer", 219 | "type": "event" 220 | }, 221 | { 222 | "inputs": [ 223 | { 224 | "internalType": "address", 225 | "name": "to", 226 | "type": "address" 227 | }, 228 | { 229 | "internalType": "uint256", 230 | "name": "tokenId", 231 | "type": "uint256" 232 | } 233 | ], 234 | "name": "approve", 235 | "outputs": [], 236 | "stateMutability": "nonpayable", 237 | "type": "function" 238 | }, 239 | { 240 | "inputs": [ 241 | { 242 | "internalType": "address", 243 | "name": "owner", 244 | "type": "address" 245 | } 246 | ], 247 | "name": "balanceOf", 248 | "outputs": [ 249 | { 250 | "internalType": "uint256", 251 | "name": "", 252 | "type": "uint256" 253 | } 254 | ], 255 | "stateMutability": "view", 256 | "type": "function" 257 | }, 258 | { 259 | "inputs": [], 260 | "name": "collectionName", 261 | "outputs": [ 262 | { 263 | "internalType": "string", 264 | "name": "", 265 | "type": "string" 266 | } 267 | ], 268 | "stateMutability": "view", 269 | "type": "function" 270 | }, 271 | { 272 | "inputs": [], 273 | "name": "collectionSymbol", 274 | "outputs": [ 275 | { 276 | "internalType": "string", 277 | "name": "", 278 | "type": "string" 279 | } 280 | ], 281 | "stateMutability": "view", 282 | "type": "function" 283 | }, 284 | { 285 | "inputs": [], 286 | "name": "createEternalNFT", 287 | "outputs": [ 288 | { 289 | "internalType": "uint256", 290 | "name": "", 291 | "type": "uint256" 292 | } 293 | ], 294 | "stateMutability": "nonpayable", 295 | "type": "function" 296 | }, 297 | { 298 | "inputs": [ 299 | { 300 | "internalType": "uint256", 301 | "name": "tokenId", 302 | "type": "uint256" 303 | } 304 | ], 305 | "name": "getApproved", 306 | "outputs": [ 307 | { 308 | "internalType": "address", 309 | "name": "", 310 | "type": "address" 311 | } 312 | ], 313 | "stateMutability": "view", 314 | "type": "function" 315 | }, 316 | { 317 | "inputs": [ 318 | { 319 | "internalType": "address", 320 | "name": "owner", 321 | "type": "address" 322 | }, 323 | { 324 | "internalType": "address", 325 | "name": "operator", 326 | "type": "address" 327 | } 328 | ], 329 | "name": "isApprovedForAll", 330 | "outputs": [ 331 | { 332 | "internalType": "bool", 333 | "name": "", 334 | "type": "bool" 335 | } 336 | ], 337 | "stateMutability": "view", 338 | "type": "function" 339 | }, 340 | { 341 | "inputs": [], 342 | "name": "name", 343 | "outputs": [ 344 | { 345 | "internalType": "string", 346 | "name": "", 347 | "type": "string" 348 | } 349 | ], 350 | "stateMutability": "view", 351 | "type": "function" 352 | }, 353 | { 354 | "inputs": [ 355 | { 356 | "internalType": "uint256", 357 | "name": "tokenId", 358 | "type": "uint256" 359 | } 360 | ], 361 | "name": "ownerOf", 362 | "outputs": [ 363 | { 364 | "internalType": "address", 365 | "name": "", 366 | "type": "address" 367 | } 368 | ], 369 | "stateMutability": "view", 370 | "type": "function" 371 | }, 372 | { 373 | "inputs": [ 374 | { 375 | "internalType": "uint256", 376 | "name": "tokenId", 377 | "type": "uint256" 378 | } 379 | ], 380 | "name": "pickFirstWord", 381 | "outputs": [ 382 | { 383 | "internalType": "string", 384 | "name": "", 385 | "type": "string" 386 | } 387 | ], 388 | "stateMutability": "view", 389 | "type": "function" 390 | }, 391 | { 392 | "inputs": [ 393 | { 394 | "internalType": "uint256", 395 | "name": "tokenId", 396 | "type": "uint256" 397 | } 398 | ], 399 | "name": "pickSecondWord", 400 | "outputs": [ 401 | { 402 | "internalType": "string", 403 | "name": "", 404 | "type": "string" 405 | } 406 | ], 407 | "stateMutability": "view", 408 | "type": "function" 409 | }, 410 | { 411 | "inputs": [ 412 | { 413 | "internalType": "uint256", 414 | "name": "tokenId", 415 | "type": "uint256" 416 | } 417 | ], 418 | "name": "pickThirdWord", 419 | "outputs": [ 420 | { 421 | "internalType": "string", 422 | "name": "", 423 | "type": "string" 424 | } 425 | ], 426 | "stateMutability": "view", 427 | "type": "function" 428 | }, 429 | { 430 | "inputs": [ 431 | { 432 | "internalType": "address", 433 | "name": "from", 434 | "type": "address" 435 | }, 436 | { 437 | "internalType": "address", 438 | "name": "to", 439 | "type": "address" 440 | }, 441 | { 442 | "internalType": "uint256", 443 | "name": "tokenId", 444 | "type": "uint256" 445 | } 446 | ], 447 | "name": "safeTransferFrom", 448 | "outputs": [], 449 | "stateMutability": "nonpayable", 450 | "type": "function" 451 | }, 452 | { 453 | "inputs": [ 454 | { 455 | "internalType": "address", 456 | "name": "from", 457 | "type": "address" 458 | }, 459 | { 460 | "internalType": "address", 461 | "name": "to", 462 | "type": "address" 463 | }, 464 | { 465 | "internalType": "uint256", 466 | "name": "tokenId", 467 | "type": "uint256" 468 | }, 469 | { 470 | "internalType": "bytes", 471 | "name": "data", 472 | "type": "bytes" 473 | } 474 | ], 475 | "name": "safeTransferFrom", 476 | "outputs": [], 477 | "stateMutability": "nonpayable", 478 | "type": "function" 479 | }, 480 | { 481 | "inputs": [ 482 | { 483 | "internalType": "address", 484 | "name": "operator", 485 | "type": "address" 486 | }, 487 | { 488 | "internalType": "bool", 489 | "name": "approved", 490 | "type": "bool" 491 | } 492 | ], 493 | "name": "setApprovalForAll", 494 | "outputs": [], 495 | "stateMutability": "nonpayable", 496 | "type": "function" 497 | }, 498 | { 499 | "inputs": [ 500 | { 501 | "internalType": "bytes4", 502 | "name": "interfaceId", 503 | "type": "bytes4" 504 | } 505 | ], 506 | "name": "supportsInterface", 507 | "outputs": [ 508 | { 509 | "internalType": "bool", 510 | "name": "", 511 | "type": "bool" 512 | } 513 | ], 514 | "stateMutability": "view", 515 | "type": "function" 516 | }, 517 | { 518 | "inputs": [], 519 | "name": "symbol", 520 | "outputs": [ 521 | { 522 | "internalType": "string", 523 | "name": "", 524 | "type": "string" 525 | } 526 | ], 527 | "stateMutability": "view", 528 | "type": "function" 529 | }, 530 | { 531 | "inputs": [ 532 | { 533 | "internalType": "uint256", 534 | "name": "tokenId", 535 | "type": "uint256" 536 | } 537 | ], 538 | "name": "tokenURI", 539 | "outputs": [ 540 | { 541 | "internalType": "string", 542 | "name": "", 543 | "type": "string" 544 | } 545 | ], 546 | "stateMutability": "view", 547 | "type": "function" 548 | }, 549 | { 550 | "inputs": [ 551 | { 552 | "internalType": "address", 553 | "name": "from", 554 | "type": "address" 555 | }, 556 | { 557 | "internalType": "address", 558 | "name": "to", 559 | "type": "address" 560 | }, 561 | { 562 | "internalType": "uint256", 563 | "name": "tokenId", 564 | "type": "uint256" 565 | } 566 | ], 567 | "name": "transferFrom", 568 | "outputs": [], 569 | "stateMutability": "nonpayable", 570 | "type": "function" 571 | } 572 | ], 573 | "bytecode": "0x608060405260405180610160016040528061012f815260200162003c1f61012f9139600a908162000031919062000ae0565b506040518060e001604052806040518060400160405280600481526020017f466972650000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f57696e640000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f576176650000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f456172746800000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600781526020017f5468756e6465720000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f537061636500000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f54696d6500000000000000000000000000000000000000000000000000000000815250815250600b906007620001ea92919062000779565b506040518060e001604052806040518060400160405280600581526020017f53776f726400000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f537065617200000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f536869656c64000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600681526020017f48616d6d6572000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f536162657200000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f417865000000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f426f770000000000000000000000000000000000000000000000000000000000815250815250600c906007620003a392919062000779565b506040518060e001604052806040518060400160405280600481526020017f4c6f72640000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600481526020017f4b696e670000000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600781526020017f456d7065726f720000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600981526020017f56656e657261626c65000000000000000000000000000000000000000000000081525081526020016040518060400160405280600881526020017f416e636573746f7200000000000000000000000000000000000000000000000081525081526020016040518060400160405280600581526020017f5361696e7400000000000000000000000000000000000000000000000000000081525081526020016040518060400160405280600381526020017f476f640000000000000000000000000000000000000000000000000000000000815250815250600d9060076200055c92919062000779565b503480156200056a57600080fd5b506040518060400160405280600a81526020017f457465726e616c4e4654000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f454e4654000000000000000000000000000000000000000000000000000000008152508160009081620005e8919062000ae0565b508060019081620005fa919062000ae0565b5050506200060d6200064560201b60201c565b600890816200061d919062000ae0565b506200062e620006df60201b60201c565b600990816200063e919062000ae0565b5062000bc7565b6060600080546200065690620008cf565b80601f01602080910402602001604051908101604052809291908181526020018280546200068490620008cf565b8015620006d55780601f10620006a957610100808354040283529160200191620006d5565b820191906000526020600020905b815481529060010190602001808311620006b757829003601f168201915b5050505050905090565b606060018054620006f090620008cf565b80601f01602080910402602001604051908101604052809291908181526020018280546200071e90620008cf565b80156200076f5780601f1062000743576101008083540402835291602001916200076f565b820191906000526020600020905b8154815290600101906020018083116200075157829003601f168201915b5050505050905090565b828054828255906000526020600020908101928215620007c6579160200282015b82811115620007c5578251829081620007b4919062000ae0565b50916020019190600101906200079a565b5b509050620007d59190620007d9565b5090565b5b80821115620007fd5760008181620007f3919062000801565b50600101620007da565b5090565b5080546200080f90620008cf565b6000825580601f1062000823575062000844565b601f01602090049060005260206000209081019062000843919062000847565b5b50565b5b808211156200086257600081600090555060010162000848565b5090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620008e857607f821691505b602082108103620008fe57620008fd620008a0565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620009687fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000929565b62000974868362000929565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620009c1620009bb620009b5846200098c565b62000996565b6200098c565b9050919050565b6000819050919050565b620009dd83620009a0565b620009f5620009ec82620009c8565b84845462000936565b825550505050565b600090565b62000a0c620009fd565b62000a19818484620009d2565b505050565b5b8181101562000a415762000a3560008262000a02565b60018101905062000a1f565b5050565b601f82111562000a905762000a5a8162000904565b62000a658462000919565b8101602085101562000a75578190505b62000a8d62000a848562000919565b83018262000a1e565b50505b505050565b600082821c905092915050565b600062000ab56000198460080262000a95565b1980831691505092915050565b600062000ad0838362000aa2565b9150826002028217905092915050565b62000aeb8262000866565b67ffffffffffffffff81111562000b075762000b0662000871565b5b62000b138254620008cf565b62000b2082828562000a45565b600060209050601f83116001811462000b58576000841562000b43578287015190505b62000b4f858262000ac2565b86555062000bbf565b601f19841662000b688662000904565b60005b8281101562000b925784890151825560018201915060208501945060208101905062000b6b565b8683101562000bb2578489015162000bae601f89168262000aa2565b8355505b6001600288020188555050505b505050505050565b6130488062000bd76000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c80636352211e116100ad578063c630338611610071578063c63033861461031a578063c87b56dd1461034a578063e2d2c3081461037a578063e5326ab1146103aa578063e985e9c5146103c857610121565b80636352211e1461026457806370a082311461029457806395d89b41146102c4578063a22cb465146102e2578063b88d4fde146102fe57610121565b806323b872dd116100f457806323b872dd146101c05780632f39352a146101dc5780633330880e146101fa5780633bad0d361461021857806342842e0e1461024857610121565b806301ffc9a71461012657806306fdde0314610156578063081812fc14610174578063095ea7b3146101a4575b600080fd5b610140600480360381019061013b9190611feb565b6103f8565b60405161014d9190612033565b60405180910390f35b61015e610459565b60405161016b91906120de565b60405180910390f35b61018e60048036038101906101899190612136565b6104eb565b60405161019b91906121a4565b60405180910390f35b6101be60048036038101906101b991906121eb565b610507565b005b6101da60048036038101906101d5919061222b565b61051d565b005b6101e461061f565b6040516101f191906120de565b60405180910390f35b6102026106ad565b60405161020f919061228d565b60405180910390f35b610232600480360381019061022d9190612136565b6107c5565b60405161023f91906120de565b60405180910390f35b610262600480360381019061025d919061222b565b6108bd565b005b61027e60048036038101906102799190612136565b6108dd565b60405161028b91906121a4565b60405180910390f35b6102ae60048036038101906102a991906122a8565b6108ef565b6040516102bb919061228d565b60405180910390f35b6102cc6109a9565b6040516102d991906120de565b60405180910390f35b6102fc60048036038101906102f79190612301565b610a3b565b005b61031860048036038101906103139190612476565b610a51565b005b610334600480360381019061032f9190612136565b610a6e565b60405161034191906120de565b60405180910390f35b610364600480360381019061035f9190612136565b610b66565b60405161037191906120de565b60405180910390f35b610394600480360381019061038f9190612136565b610c79565b6040516103a191906120de565b60405180910390f35b6103b2610d71565b6040516103bf91906120de565b60405180910390f35b6103e260048036038101906103dd91906124f9565b610dff565b6040516103ef9190612033565b60405180910390f35b6000634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610452575061045182610e93565b5b9050919050565b60606000805461046890612568565b80601f016020809104026020016040519081016040528092919081815260200182805461049490612568565b80156104e15780601f106104b6576101008083540402835291602001916104e1565b820191906000526020600020905b8154815290600101906020018083116104c457829003601f168201915b5050505050905090565b60006104f682610f75565b5061050082610ffd565b9050919050565b610519828261051461103a565b611042565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361058f5760006040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161058691906121a4565b60405180910390fd5b60006105a3838361059e61103a565b611054565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610619578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161061093929190612599565b60405180910390fd5b50505050565b6009805461062c90612568565b80601f016020809104026020016040519081016040528092919081815260200182805461065890612568565b80156106a55780601f1061067a576101008083540402835291602001916106a5565b820191906000526020600020905b81548152906001019060200180831161068857829003601f168201915b505050505081565b600080600754905060006106c0826107c5565b905060006106cd83610a6e565b905060006106da84610c79565b905060008383836040516020016106f39392919061260c565b60405160208183030381529060405290506000600a85858560405160200161071e9493929190612721565b604051602081830303815290604052905060006107638361073e8461126e565b60405160200161074f9291906128c0565b60405160208183030381529060405261126e565b90506000816040516020016107789190612951565b60405160208183030381529060405290506107933389611405565b61079d8882611423565b6001600760008282546107b091906129a2565b92505081905550879850505050505050505090565b606060006107f96107d58461147f565b6040516020016107e59190612a22565b60405160208183030381529060405261154d565b9050600b805490508161080c9190612a73565b9050600b818154811061082257610821612aa4565b5b90600052602060002001805461083790612568565b80601f016020809104026020016040519081016040528092919081815260200182805461086390612568565b80156108b05780601f10610885576101008083540402835291602001916108b0565b820191906000526020600020905b81548152906001019060200180831161089357829003601f168201915b5050505050915050919050565b6108d883838360405180602001604052806000815250610a51565b505050565b60006108e882610f75565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109625760006040517f89c62b6400000000000000000000000000000000000000000000000000000000815260040161095991906121a4565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060600180546109b890612568565b80601f01602080910402602001604051908101604052809291908181526020018280546109e490612568565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505050905090565b610a4d610a4661103a565b8383611580565b5050565b610a5c84848461051d565b610a68848484846116ef565b50505050565b60606000610aa2610a7e8461147f565b604051602001610a8e9190612b1f565b60405160208183030381529060405261154d565b9050600c8054905081610ab59190612a73565b9050600c8181548110610acb57610aca612aa4565b5b906000526020600020018054610ae090612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610b0c90612568565b8015610b595780601f10610b2e57610100808354040283529160200191610b59565b820191906000526020600020905b815481529060010190602001808311610b3c57829003601f168201915b5050505050915050919050565b6060610b7182610f75565b506000600660008481526020019081526020016000208054610b9290612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610bbe90612568565b8015610c0b5780601f10610be057610100808354040283529160200191610c0b565b820191906000526020600020905b815481529060010190602001808311610bee57829003601f168201915b505050505090506000610c1c6118a6565b90506000815103610c31578192505050610c74565b600082511115610c66578082604051602001610c4e929190612b41565b60405160208183030381529060405292505050610c74565b610c6f846118bd565b925050505b919050565b60606000610cad610c898461147f565b604051602001610c999190612bb1565b60405160208183030381529060405261154d565b9050600d8054905081610cc09190612a73565b9050600d8181548110610cd657610cd5612aa4565b5b906000526020600020018054610ceb90612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1790612568565b8015610d645780601f10610d3957610100808354040283529160200191610d64565b820191906000526020600020905b815481529060010190602001808311610d4757829003601f168201915b5050505050915050919050565b60088054610d7e90612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610daa90612568565b8015610df75780601f10610dcc57610100808354040283529160200191610df7565b820191906000526020600020905b815481529060010190602001808311610dda57829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610f5e57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f6e5750610f6d82611926565b5b9050919050565b600080610f8183611990565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610ff457826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610feb919061228d565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b61104f83838360016119cd565b505050565b60008061106084611990565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146110a2576110a1818486611b92565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611133576110e46000856000806119cd565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146111b6576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b6060600082519050600081036112965760405180602001604052806000815250915050611400565b600060036002836112a791906129a2565b6112b19190612bd3565b60046112bd9190612c04565b905060006020826112ce91906129a2565b67ffffffffffffffff8111156112e7576112e661234b565b5b6040519080825280601f01601f1916602001820160405280156113195781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001612fd3604091399050600181016020830160005b868110156113bd5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611344565b5060038606600181146113d757600281146113e7576113f2565b613d3d60f01b60028303526113f2565b603d60f81b60018303525b508484525050819450505050505b919050565b61141f828260405180602001604052806000815250611c56565b5050565b806006600084815260200190815260200160002090816114439190612ddd565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce782604051611473919061228d565b60405180910390a15050565b60606000600161148e84611c72565b01905060008167ffffffffffffffff8111156114ad576114ac61234b565b5b6040519080825280601f01601f1916602001820160405280156114df5781602001600182028036833780820191505090505b509050600082602001820190505b600115611542578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161153657611535612a44565b5b049450600085036114ed575b819350505050919050565b6000816040516020016115609190612eaf565b6040516020818303038152906040528051906020012060001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115f157816040517f5b08ba180000000000000000000000000000000000000000000000000000000081526004016115e891906121a4565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116e29190612033565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b11156118a0578273ffffffffffffffffffffffffffffffffffffffff1663150b7a0261173361103a565b8685856040518563ffffffff1660e01b81526004016117559493929190612f1b565b6020604051808303816000875af192505050801561179157506040513d601f19601f8201168201806040525081019061178e9190612f7c565b60015b611815573d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b50600081510361180d57836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161180491906121a4565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461189e57836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161189591906121a4565b60405180910390fd5b505b50505050565b606060405180602001604052806000815250905090565b60606118c882610f75565b5060006118d36118a6565b905060008151116118f3576040518060200160405280600081525061191e565b806118fd8461147f565b60405160200161190e929190612b41565b6040516020818303038152906040525b915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8080611a065750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611b3a576000611a1684610f75565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611a8157508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611a945750611a928184610dff565b155b15611ad657826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611acd91906121a4565b60405180910390fd5b8115611b3857838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611b9d838383611dc5565b611c5157600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c1257806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611c09919061228d565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611c48929190612fa9565b60405180910390fd5b505050565b611c608383611e86565b611c6d60008484846116ef565b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611cd0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611cc657611cc5612a44565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611d0d576d04ee2d6d415b85acef81000000008381611d0357611d02612a44565b5b0492506020810190505b662386f26fc100008310611d3c57662386f26fc100008381611d3257611d31612a44565b5b0492506010810190505b6305f5e1008310611d65576305f5e1008381611d5b57611d5a612a44565b5b0492506008810190505b6127108310611d8a576127108381611d8057611d7f612a44565b5b0492506004810190505b60648310611dad5760648381611da357611da2612a44565b5b0492506002810190505b600a8310611dbc576001810190505b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611e7d57508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e3e5750611e3d8484610dff565b5b80611e7c57508273ffffffffffffffffffffffffffffffffffffffff16611e6483610ffd565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ef85760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611eef91906121a4565b60405180910390fd5b6000611f0683836000611054565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f7a5760006040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401611f7191906121a4565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fc881611f93565b8114611fd357600080fd5b50565b600081359050611fe581611fbf565b92915050565b60006020828403121561200157612000611f89565b5b600061200f84828501611fd6565b91505092915050565b60008115159050919050565b61202d81612018565b82525050565b60006020820190506120486000830184612024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561208857808201518184015260208101905061206d565b60008484015250505050565b6000601f19601f8301169050919050565b60006120b08261204e565b6120ba8185612059565b93506120ca81856020860161206a565b6120d381612094565b840191505092915050565b600060208201905081810360008301526120f881846120a5565b905092915050565b6000819050919050565b61211381612100565b811461211e57600080fd5b50565b6000813590506121308161210a565b92915050565b60006020828403121561214c5761214b611f89565b5b600061215a84828501612121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061218e82612163565b9050919050565b61219e81612183565b82525050565b60006020820190506121b96000830184612195565b92915050565b6121c881612183565b81146121d357600080fd5b50565b6000813590506121e5816121bf565b92915050565b6000806040838503121561220257612201611f89565b5b6000612210858286016121d6565b925050602061222185828601612121565b9150509250929050565b60008060006060848603121561224457612243611f89565b5b6000612252868287016121d6565b9350506020612263868287016121d6565b925050604061227486828701612121565b9150509250925092565b61228781612100565b82525050565b60006020820190506122a2600083018461227e565b92915050565b6000602082840312156122be576122bd611f89565b5b60006122cc848285016121d6565b91505092915050565b6122de81612018565b81146122e957600080fd5b50565b6000813590506122fb816122d5565b92915050565b6000806040838503121561231857612317611f89565b5b6000612326858286016121d6565b9250506020612337858286016122ec565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61238382612094565b810181811067ffffffffffffffff821117156123a2576123a161234b565b5b80604052505050565b60006123b5611f7f565b90506123c1828261237a565b919050565b600067ffffffffffffffff8211156123e1576123e061234b565b5b6123ea82612094565b9050602081019050919050565b82818337600083830152505050565b6000612419612414846123c6565b6123ab565b90508281526020810184848401111561243557612434612346565b5b6124408482856123f7565b509392505050565b600082601f83011261245d5761245c612341565b5b813561246d848260208601612406565b91505092915050565b600080600080608085870312156124905761248f611f89565b5b600061249e878288016121d6565b94505060206124af878288016121d6565b93505060406124c087828801612121565b925050606085013567ffffffffffffffff8111156124e1576124e0611f8e565b5b6124ed87828801612448565b91505092959194509250565b600080604083850312156125105761250f611f89565b5b600061251e858286016121d6565b925050602061252f858286016121d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061258057607f821691505b60208210810361259357612592612539565b5b50919050565b60006060820190506125ae6000830186612195565b6125bb602083018561227e565b6125c86040830184612195565b949350505050565b600081905092915050565b60006125e68261204e565b6125f081856125d0565b935061260081856020860161206a565b80840191505092915050565b600061261882866125db565b915061262482856125db565b915061263082846125db565b9150819050949350505050565b60008190508160005260206000209050919050565b6000815461265f81612568565b61266981866125d0565b945060018216600081146126845760018114612699576126cc565b60ff19831686528115158202860193506126cc565b6126a28561263d565b60005b838110156126c4578154818901526001820191506020810190506126a5565b838801955050505b50505092915050565b7f3c2f746578743e3c2f7376673e00000000000000000000000000000000000000600082015250565b600061270b600d836125d0565b9150612716826126d5565b600d82019050919050565b600061272d8287612652565b915061273982866125db565b915061274582856125db565b915061275182846125db565b915061275c826126fe565b915081905095945050505050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b60006127a0600a836125d0565b91506127ab8261276a565b600a82019050919050565b7f222c20226465736372697074696f6e223a20224120686967686c79206163636c60008201527f61696d656420636f6c6c656374696f6e20457465726e616c2057617272696f7260208201527f73222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c60408201527f3b6261736536342c000000000000000000000000000000000000000000000000606082015250565b600061285e6068836125d0565b9150612869826127b6565b606882019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006128aa6002836125d0565b91506128b582612874565b600282019050919050565b60006128cb82612793565b91506128d782856125db565b91506128e282612851565b91506128ee82846125db565b91506128f98261289d565b91508190509392505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061293b601d836125d0565b915061294682612905565b601d82019050919050565b600061295c8261292e565b915061296882846125db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006129ad82612100565b91506129b883612100565b92508282019050808211156129d0576129cf612973565b5b92915050565b7f656c656d656e7400000000000000000000000000000000000000000000000000600082015250565b6000612a0c6007836125d0565b9150612a17826129d6565b600782019050919050565b6000612a2d826129ff565b9150612a3982846125db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612a7e82612100565b9150612a8983612100565b925082612a9957612a98612a44565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f776561706f6e0000000000000000000000000000000000000000000000000000600082015250565b6000612b096006836125d0565b9150612b1482612ad3565b600682019050919050565b6000612b2a82612afc565b9150612b3682846125db565b915081905092915050565b6000612b4d82856125db565b9150612b5982846125db565b91508190509392505050565b7f72616e6b00000000000000000000000000000000000000000000000000000000600082015250565b6000612b9b6004836125d0565b9150612ba682612b65565b600482019050919050565b6000612bbc82612b8e565b9150612bc882846125db565b915081905092915050565b6000612bde82612100565b9150612be983612100565b925082612bf957612bf8612a44565b5b828204905092915050565b6000612c0f82612100565b9150612c1a83612100565b9250828202612c2881612100565b91508282048414831517612c3f57612c3e612973565b5b5092915050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612c937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612c56565b612c9d8683612c56565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612cda612cd5612cd084612100565b612cb5565b612100565b9050919050565b6000819050919050565b612cf483612cbf565b612d08612d0082612ce1565b848454612c63565b825550505050565b600090565b612d1d612d10565b612d28818484612ceb565b505050565b5b81811015612d4c57612d41600082612d15565b600181019050612d2e565b5050565b601f821115612d9157612d628161263d565b612d6b84612c46565b81016020851015612d7a578190505b612d8e612d8685612c46565b830182612d2d565b50505b505050565b600082821c905092915050565b6000612db460001984600802612d96565b1980831691505092915050565b6000612dcd8383612da3565b9150826002028217905092915050565b612de68261204e565b67ffffffffffffffff811115612dff57612dfe61234b565b5b612e098254612568565b612e14828285612d50565b600060209050601f831160018114612e475760008415612e35578287015190505b612e3f8582612dc1565b865550612ea7565b601f198416612e558661263d565b60005b82811015612e7d57848901518255600182019150602085019450602081019050612e58565b86831015612e9a5784890151612e96601f891682612da3565b8355505b6001600288020188555050505b505050505050565b6000612ebb82846125db565b915081905092915050565b600081519050919050565b600082825260208201905092915050565b6000612eed82612ec6565b612ef78185612ed1565b9350612f0781856020860161206a565b612f1081612094565b840191505092915050565b6000608082019050612f306000830187612195565b612f3d6020830186612195565b612f4a604083018561227e565b8181036060830152612f5c8184612ee2565b905095945050505050565b600081519050612f7681611fbf565b92915050565b600060208284031215612f9257612f91611f89565b5b6000612fa084828501612f67565b91505092915050565b6000604082019050612fbe6000830185612195565b612fcb602083018461227e565b939250505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212207fcd0aeba3eb5a54a1ee8864f56e811724ef8b21c76e1f895168ff01444a4b1764736f6c634300081800333c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f73766727207072657365727665417370656374526174696f3d27784d696e594d696e206d656574272076696577426f783d273020302033353020333530273e3c7374796c653e2e62617365207b2066696c6c3a2077686974653b20666f6e742d66616d696c793a2073657269663b20666f6e742d73697a653a20323470783b207d3c2f7374796c653e3c726563742077696474683d273130302527206865696768743d2731303025272066696c6c3d27626c61636b27202f3e3c7465787420783d273530252720793d273530252720636c6173733d27626173652720646f6d696e616e742d626173656c696e653d276d6964646c652720746578742d616e63686f723d276d6964646c65273e", 574 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101215760003560e01c80636352211e116100ad578063c630338611610071578063c63033861461031a578063c87b56dd1461034a578063e2d2c3081461037a578063e5326ab1146103aa578063e985e9c5146103c857610121565b80636352211e1461026457806370a082311461029457806395d89b41146102c4578063a22cb465146102e2578063b88d4fde146102fe57610121565b806323b872dd116100f457806323b872dd146101c05780632f39352a146101dc5780633330880e146101fa5780633bad0d361461021857806342842e0e1461024857610121565b806301ffc9a71461012657806306fdde0314610156578063081812fc14610174578063095ea7b3146101a4575b600080fd5b610140600480360381019061013b9190611feb565b6103f8565b60405161014d9190612033565b60405180910390f35b61015e610459565b60405161016b91906120de565b60405180910390f35b61018e60048036038101906101899190612136565b6104eb565b60405161019b91906121a4565b60405180910390f35b6101be60048036038101906101b991906121eb565b610507565b005b6101da60048036038101906101d5919061222b565b61051d565b005b6101e461061f565b6040516101f191906120de565b60405180910390f35b6102026106ad565b60405161020f919061228d565b60405180910390f35b610232600480360381019061022d9190612136565b6107c5565b60405161023f91906120de565b60405180910390f35b610262600480360381019061025d919061222b565b6108bd565b005b61027e60048036038101906102799190612136565b6108dd565b60405161028b91906121a4565b60405180910390f35b6102ae60048036038101906102a991906122a8565b6108ef565b6040516102bb919061228d565b60405180910390f35b6102cc6109a9565b6040516102d991906120de565b60405180910390f35b6102fc60048036038101906102f79190612301565b610a3b565b005b61031860048036038101906103139190612476565b610a51565b005b610334600480360381019061032f9190612136565b610a6e565b60405161034191906120de565b60405180910390f35b610364600480360381019061035f9190612136565b610b66565b60405161037191906120de565b60405180910390f35b610394600480360381019061038f9190612136565b610c79565b6040516103a191906120de565b60405180910390f35b6103b2610d71565b6040516103bf91906120de565b60405180910390f35b6103e260048036038101906103dd91906124f9565b610dff565b6040516103ef9190612033565b60405180910390f35b6000634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610452575061045182610e93565b5b9050919050565b60606000805461046890612568565b80601f016020809104026020016040519081016040528092919081815260200182805461049490612568565b80156104e15780601f106104b6576101008083540402835291602001916104e1565b820191906000526020600020905b8154815290600101906020018083116104c457829003601f168201915b5050505050905090565b60006104f682610f75565b5061050082610ffd565b9050919050565b610519828261051461103a565b611042565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361058f5760006040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161058691906121a4565b60405180910390fd5b60006105a3838361059e61103a565b611054565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610619578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161061093929190612599565b60405180910390fd5b50505050565b6009805461062c90612568565b80601f016020809104026020016040519081016040528092919081815260200182805461065890612568565b80156106a55780601f1061067a576101008083540402835291602001916106a5565b820191906000526020600020905b81548152906001019060200180831161068857829003601f168201915b505050505081565b600080600754905060006106c0826107c5565b905060006106cd83610a6e565b905060006106da84610c79565b905060008383836040516020016106f39392919061260c565b60405160208183030381529060405290506000600a85858560405160200161071e9493929190612721565b604051602081830303815290604052905060006107638361073e8461126e565b60405160200161074f9291906128c0565b60405160208183030381529060405261126e565b90506000816040516020016107789190612951565b60405160208183030381529060405290506107933389611405565b61079d8882611423565b6001600760008282546107b091906129a2565b92505081905550879850505050505050505090565b606060006107f96107d58461147f565b6040516020016107e59190612a22565b60405160208183030381529060405261154d565b9050600b805490508161080c9190612a73565b9050600b818154811061082257610821612aa4565b5b90600052602060002001805461083790612568565b80601f016020809104026020016040519081016040528092919081815260200182805461086390612568565b80156108b05780601f10610885576101008083540402835291602001916108b0565b820191906000526020600020905b81548152906001019060200180831161089357829003601f168201915b5050505050915050919050565b6108d883838360405180602001604052806000815250610a51565b505050565b60006108e882610f75565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036109625760006040517f89c62b6400000000000000000000000000000000000000000000000000000000815260040161095991906121a4565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060600180546109b890612568565b80601f01602080910402602001604051908101604052809291908181526020018280546109e490612568565b8015610a315780601f10610a0657610100808354040283529160200191610a31565b820191906000526020600020905b815481529060010190602001808311610a1457829003601f168201915b5050505050905090565b610a4d610a4661103a565b8383611580565b5050565b610a5c84848461051d565b610a68848484846116ef565b50505050565b60606000610aa2610a7e8461147f565b604051602001610a8e9190612b1f565b60405160208183030381529060405261154d565b9050600c8054905081610ab59190612a73565b9050600c8181548110610acb57610aca612aa4565b5b906000526020600020018054610ae090612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610b0c90612568565b8015610b595780601f10610b2e57610100808354040283529160200191610b59565b820191906000526020600020905b815481529060010190602001808311610b3c57829003601f168201915b5050505050915050919050565b6060610b7182610f75565b506000600660008481526020019081526020016000208054610b9290612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610bbe90612568565b8015610c0b5780601f10610be057610100808354040283529160200191610c0b565b820191906000526020600020905b815481529060010190602001808311610bee57829003601f168201915b505050505090506000610c1c6118a6565b90506000815103610c31578192505050610c74565b600082511115610c66578082604051602001610c4e929190612b41565b60405160208183030381529060405292505050610c74565b610c6f846118bd565b925050505b919050565b60606000610cad610c898461147f565b604051602001610c999190612bb1565b60405160208183030381529060405261154d565b9050600d8054905081610cc09190612a73565b9050600d8181548110610cd657610cd5612aa4565b5b906000526020600020018054610ceb90612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1790612568565b8015610d645780601f10610d3957610100808354040283529160200191610d64565b820191906000526020600020905b815481529060010190602001808311610d4757829003601f168201915b5050505050915050919050565b60088054610d7e90612568565b80601f0160208091040260200160405190810160405280929190818152602001828054610daa90612568565b8015610df75780601f10610dcc57610100808354040283529160200191610df7565b820191906000526020600020905b815481529060010190602001808311610dda57829003601f168201915b505050505081565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610f5e57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610f6e5750610f6d82611926565b5b9050919050565b600080610f8183611990565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610ff457826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610feb919061228d565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b61104f83838360016119cd565b505050565b60008061106084611990565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146110a2576110a1818486611b92565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611133576110e46000856000806119cd565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146111b6576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b6060600082519050600081036112965760405180602001604052806000815250915050611400565b600060036002836112a791906129a2565b6112b19190612bd3565b60046112bd9190612c04565b905060006020826112ce91906129a2565b67ffffffffffffffff8111156112e7576112e661234b565b5b6040519080825280601f01601f1916602001820160405280156113195781602001600182028036833780820191505090505b5090506000604051806060016040528060408152602001612fd3604091399050600181016020830160005b868110156113bd5760038101905062ffffff818a015116603f8160121c168401518060081b905060ff603f83600c1c1686015116810190508060081b905060ff603f8360061c1686015116810190508060081b905060ff603f831686015116810190508060e01b90508084526004840193505050611344565b5060038606600181146113d757600281146113e7576113f2565b613d3d60f01b60028303526113f2565b603d60f81b60018303525b508484525050819450505050505b919050565b61141f828260405180602001604052806000815250611c56565b5050565b806006600084815260200190815260200160002090816114439190612ddd565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce782604051611473919061228d565b60405180910390a15050565b60606000600161148e84611c72565b01905060008167ffffffffffffffff8111156114ad576114ac61234b565b5b6040519080825280601f01601f1916602001820160405280156114df5781602001600182028036833780820191505090505b509050600082602001820190505b600115611542578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161153657611535612a44565b5b049450600085036114ed575b819350505050919050565b6000816040516020016115609190612eaf565b6040516020818303038152906040528051906020012060001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036115f157816040517f5b08ba180000000000000000000000000000000000000000000000000000000081526004016115e891906121a4565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116e29190612033565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b11156118a0578273ffffffffffffffffffffffffffffffffffffffff1663150b7a0261173361103a565b8685856040518563ffffffff1660e01b81526004016117559493929190612f1b565b6020604051808303816000875af192505050801561179157506040513d601f19601f8201168201806040525081019061178e9190612f7c565b60015b611815573d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b50600081510361180d57836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161180491906121a4565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461189e57836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161189591906121a4565b60405180910390fd5b505b50505050565b606060405180602001604052806000815250905090565b60606118c882610f75565b5060006118d36118a6565b905060008151116118f3576040518060200160405280600081525061191e565b806118fd8461147f565b60405160200161190e929190612b41565b6040516020818303038152906040525b915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8080611a065750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611b3a576000611a1684610f75565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611a8157508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611a945750611a928184610dff565b155b15611ad657826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611acd91906121a4565b60405180910390fd5b8115611b3857838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b611b9d838383611dc5565b611c5157600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611c1257806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401611c09919061228d565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401611c48929190612fa9565b60405180910390fd5b505050565b611c608383611e86565b611c6d60008484846116ef565b505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611cd0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381611cc657611cc5612a44565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611d0d576d04ee2d6d415b85acef81000000008381611d0357611d02612a44565b5b0492506020810190505b662386f26fc100008310611d3c57662386f26fc100008381611d3257611d31612a44565b5b0492506010810190505b6305f5e1008310611d65576305f5e1008381611d5b57611d5a612a44565b5b0492506008810190505b6127108310611d8a576127108381611d8057611d7f612a44565b5b0492506004810190505b60648310611dad5760648381611da357611da2612a44565b5b0492506002810190505b600a8310611dbc576001810190505b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611e7d57508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e3e5750611e3d8484610dff565b5b80611e7c57508273ffffffffffffffffffffffffffffffffffffffff16611e6483610ffd565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ef85760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401611eef91906121a4565b60405180910390fd5b6000611f0683836000611054565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f7a5760006040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401611f7191906121a4565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fc881611f93565b8114611fd357600080fd5b50565b600081359050611fe581611fbf565b92915050565b60006020828403121561200157612000611f89565b5b600061200f84828501611fd6565b91505092915050565b60008115159050919050565b61202d81612018565b82525050565b60006020820190506120486000830184612024565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561208857808201518184015260208101905061206d565b60008484015250505050565b6000601f19601f8301169050919050565b60006120b08261204e565b6120ba8185612059565b93506120ca81856020860161206a565b6120d381612094565b840191505092915050565b600060208201905081810360008301526120f881846120a5565b905092915050565b6000819050919050565b61211381612100565b811461211e57600080fd5b50565b6000813590506121308161210a565b92915050565b60006020828403121561214c5761214b611f89565b5b600061215a84828501612121565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061218e82612163565b9050919050565b61219e81612183565b82525050565b60006020820190506121b96000830184612195565b92915050565b6121c881612183565b81146121d357600080fd5b50565b6000813590506121e5816121bf565b92915050565b6000806040838503121561220257612201611f89565b5b6000612210858286016121d6565b925050602061222185828601612121565b9150509250929050565b60008060006060848603121561224457612243611f89565b5b6000612252868287016121d6565b9350506020612263868287016121d6565b925050604061227486828701612121565b9150509250925092565b61228781612100565b82525050565b60006020820190506122a2600083018461227e565b92915050565b6000602082840312156122be576122bd611f89565b5b60006122cc848285016121d6565b91505092915050565b6122de81612018565b81146122e957600080fd5b50565b6000813590506122fb816122d5565b92915050565b6000806040838503121561231857612317611f89565b5b6000612326858286016121d6565b9250506020612337858286016122ec565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61238382612094565b810181811067ffffffffffffffff821117156123a2576123a161234b565b5b80604052505050565b60006123b5611f7f565b90506123c1828261237a565b919050565b600067ffffffffffffffff8211156123e1576123e061234b565b5b6123ea82612094565b9050602081019050919050565b82818337600083830152505050565b6000612419612414846123c6565b6123ab565b90508281526020810184848401111561243557612434612346565b5b6124408482856123f7565b509392505050565b600082601f83011261245d5761245c612341565b5b813561246d848260208601612406565b91505092915050565b600080600080608085870312156124905761248f611f89565b5b600061249e878288016121d6565b94505060206124af878288016121d6565b93505060406124c087828801612121565b925050606085013567ffffffffffffffff8111156124e1576124e0611f8e565b5b6124ed87828801612448565b91505092959194509250565b600080604083850312156125105761250f611f89565b5b600061251e858286016121d6565b925050602061252f858286016121d6565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061258057607f821691505b60208210810361259357612592612539565b5b50919050565b60006060820190506125ae6000830186612195565b6125bb602083018561227e565b6125c86040830184612195565b949350505050565b600081905092915050565b60006125e68261204e565b6125f081856125d0565b935061260081856020860161206a565b80840191505092915050565b600061261882866125db565b915061262482856125db565b915061263082846125db565b9150819050949350505050565b60008190508160005260206000209050919050565b6000815461265f81612568565b61266981866125d0565b945060018216600081146126845760018114612699576126cc565b60ff19831686528115158202860193506126cc565b6126a28561263d565b60005b838110156126c4578154818901526001820191506020810190506126a5565b838801955050505b50505092915050565b7f3c2f746578743e3c2f7376673e00000000000000000000000000000000000000600082015250565b600061270b600d836125d0565b9150612716826126d5565b600d82019050919050565b600061272d8287612652565b915061273982866125db565b915061274582856125db565b915061275182846125db565b915061275c826126fe565b915081905095945050505050565b7f7b226e616d65223a202200000000000000000000000000000000000000000000600082015250565b60006127a0600a836125d0565b91506127ab8261276a565b600a82019050919050565b7f222c20226465736372697074696f6e223a20224120686967686c79206163636c60008201527f61696d656420636f6c6c656374696f6e20457465726e616c2057617272696f7260208201527f73222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c60408201527f3b6261736536342c000000000000000000000000000000000000000000000000606082015250565b600061285e6068836125d0565b9150612869826127b6565b606882019050919050565b7f227d000000000000000000000000000000000000000000000000000000000000600082015250565b60006128aa6002836125d0565b91506128b582612874565b600282019050919050565b60006128cb82612793565b91506128d782856125db565b91506128e282612851565b91506128ee82846125db565b91506128f98261289d565b91508190509392505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b600061293b601d836125d0565b915061294682612905565b601d82019050919050565b600061295c8261292e565b915061296882846125db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006129ad82612100565b91506129b883612100565b92508282019050808211156129d0576129cf612973565b5b92915050565b7f656c656d656e7400000000000000000000000000000000000000000000000000600082015250565b6000612a0c6007836125d0565b9150612a17826129d6565b600782019050919050565b6000612a2d826129ff565b9150612a3982846125db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612a7e82612100565b9150612a8983612100565b925082612a9957612a98612a44565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f776561706f6e0000000000000000000000000000000000000000000000000000600082015250565b6000612b096006836125d0565b9150612b1482612ad3565b600682019050919050565b6000612b2a82612afc565b9150612b3682846125db565b915081905092915050565b6000612b4d82856125db565b9150612b5982846125db565b91508190509392505050565b7f72616e6b00000000000000000000000000000000000000000000000000000000600082015250565b6000612b9b6004836125d0565b9150612ba682612b65565b600482019050919050565b6000612bbc82612b8e565b9150612bc882846125db565b915081905092915050565b6000612bde82612100565b9150612be983612100565b925082612bf957612bf8612a44565b5b828204905092915050565b6000612c0f82612100565b9150612c1a83612100565b9250828202612c2881612100565b91508282048414831517612c3f57612c3e612973565b5b5092915050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302612c937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612c56565b612c9d8683612c56565b95508019841693508086168417925050509392505050565b6000819050919050565b6000612cda612cd5612cd084612100565b612cb5565b612100565b9050919050565b6000819050919050565b612cf483612cbf565b612d08612d0082612ce1565b848454612c63565b825550505050565b600090565b612d1d612d10565b612d28818484612ceb565b505050565b5b81811015612d4c57612d41600082612d15565b600181019050612d2e565b5050565b601f821115612d9157612d628161263d565b612d6b84612c46565b81016020851015612d7a578190505b612d8e612d8685612c46565b830182612d2d565b50505b505050565b600082821c905092915050565b6000612db460001984600802612d96565b1980831691505092915050565b6000612dcd8383612da3565b9150826002028217905092915050565b612de68261204e565b67ffffffffffffffff811115612dff57612dfe61234b565b5b612e098254612568565b612e14828285612d50565b600060209050601f831160018114612e475760008415612e35578287015190505b612e3f8582612dc1565b865550612ea7565b601f198416612e558661263d565b60005b82811015612e7d57848901518255600182019150602085019450602081019050612e58565b86831015612e9a5784890151612e96601f891682612da3565b8355505b6001600288020188555050505b505050505050565b6000612ebb82846125db565b915081905092915050565b600081519050919050565b600082825260208201905092915050565b6000612eed82612ec6565b612ef78185612ed1565b9350612f0781856020860161206a565b612f1081612094565b840191505092915050565b6000608082019050612f306000830187612195565b612f3d6020830186612195565b612f4a604083018561227e565b8181036060830152612f5c8184612ee2565b905095945050505050565b600081519050612f7681611fbf565b92915050565b600060208284031215612f9257612f91611f89565b5b6000612fa084828501612f67565b91505092915050565b6000604082019050612fbe6000830185612195565b612fcb602083018461227e565b939250505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212207fcd0aeba3eb5a54a1ee8864f56e811724ef8b21c76e1f895168ff01444a4b1764736f6c63430008180033", 575 | "linkReferences": {}, 576 | "deployedLinkReferences": {} 577 | } 578 | -------------------------------------------------------------------------------- /hardhat.config.cjs: -------------------------------------------------------------------------------- 1 | // require("@nomicfoundation/hardhat-waffle"); 2 | // requrei('dotenv').config(); 3 | 4 | // const { API_URL, PRIVATE_KEY } = process.env; 5 | 6 | // /** @type import('hardhat/config').HardhatUserConfig */ 7 | // module.exports = { 8 | // solidity: "0.8.24", 9 | // networks: { 10 | // rinkeby: { 11 | // url: API_URL, 12 | // accounts: [PRIVATE_KEY] 13 | // } 14 | // } 15 | // }; 16 | 17 | 18 | /** @type import('hardhat/config').HardhatUserConfig */ 19 | 20 | require('dotenv').config(); 21 | require('@nomiclabs/hardhat-ethers'); 22 | 23 | const { API_URL, PRIVATE_KEY } = process.env; 24 | 25 | module.exports = { 26 | solidity: "0.8.24", 27 | defaultNetwork: 'sepolia', 28 | networks: { 29 | hardhat: {}, 30 | sepolia: { 31 | url: API_URL, 32 | accounts: [`0x${PRIVATE_KEY}`] 33 | } 34 | } 35 | }; -------------------------------------------------------------------------------- /ignition/modules/Lock.js: -------------------------------------------------------------------------------- 1 | const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); 2 | 3 | const JAN_1ST_2030 = 1893456000; 4 | const ONE_GWEI = 1_000_000_000n; 5 | 6 | module.exports = buildModule("LockModule", (m) => { 7 | const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); 8 | const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); 9 | 10 | const lock = m.contract("Lock", [unlockTime], { 11 | value: lockedAmount, 12 | }); 13 | 14 | return { lock }; 15 | }); 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fullstack-nft-minting-dapp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "dependencies": { 11 | "@nomiclabs/hardhat-ethers": "^2.2.3", 12 | "@nomiclabs/hardhat-waffle": "^2.0.6", 13 | "@openzeppelin/contracts": "^5.0.2", 14 | "axios": "^1.7.4", 15 | "chai": "^5.1.1", 16 | "dotenv": "^16.4.5", 17 | "ethereum-waffle": "^4.0.10", 18 | "ethers": "^5.7.2", 19 | "hardhat": "^2.22.8", 20 | "react-loader-spinner": "^6.1.6" 21 | }, 22 | "type": "module" 23 | } -------------------------------------------------------------------------------- /scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const main = async () => { 2 | const nftContractFactory = await ethers.getContractFactory('EternalNFT'); 3 | const nftContract = await nftContractFactory.deploy(); 4 | await nftContract.deployed(); 5 | console.log('Contract deployed to: ', nftContract.address) 6 | } 7 | 8 | const runMain = async () => { 9 | try { 10 | await main(); 11 | process.exit(0); 12 | } catch (error) { 13 | console.log(error); 14 | process.exit(1) 15 | } 16 | } 17 | 18 | runMain(); -------------------------------------------------------------------------------- /test/EternalNFT-test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import pkg from 'hardhat'; 3 | const { ethers } = pkg; 4 | 5 | describe('EternalNFT', async () => { 6 | let nft; 7 | let nftContractAddress; 8 | let tokenId; 9 | 10 | 11 | // Deploy the EternalNFT Contract before each test 12 | beforeEach('Setup Contract', async () => { 13 | const EternalNFT = await ethers.getContractFactory('EternalNFT'); 14 | nft = await EternalNFT.deploy(); 15 | await nft.deployed(); 16 | nftContractAddress = await nft.address; 17 | }); 18 | 19 | // Tests address for the EternalNFT contract 20 | it('Should have the contract address', async () => { 21 | expect(nftContractAddress).to.not.equal('0x0'); 22 | expect(nftContractAddress).to.not.equal(''); 23 | expect(nftContractAddress).to.not.equal(null); 24 | expect(nftContractAddress).to.not.equal(undefined); 25 | }); 26 | 27 | // Tests the name for token on EternalNFT contract 28 | it('Should have the name', async () => { 29 | const name = await nft.collectionName(); 30 | expect(name).to.equal('EternalNFT'); 31 | }); 32 | 33 | // Tests the symbol for token on EternalNFT contract 34 | it('Should have the symbol', async () => { 35 | const symbol = await nft.collectionSymbol(); 36 | expect(symbol).to.equal('ENFT'); 37 | }); 38 | 39 | // Tests for NFT minting function 40 | it('Should be able to mint NFT', async () => { 41 | // Mints the first NFT 42 | let txn = await nft.createEternalNFT(); 43 | let tx = await txn.wait(); 44 | // tokenId of the minted NFT 45 | let event = tx.events[0]; 46 | let value = event.args[2]; 47 | tokenId = value.toNumber(); 48 | expect(tokenId).to.equal(0); 49 | // Mints the second NFT 50 | txn = await nft.createEternalNFT(); 51 | tx = await txn.wait(); 52 | // tokenId of minted NFT secondly 53 | event = tx.events[0]; 54 | value = event.args[2]; 55 | tokenId = value.toNumber(); 56 | expect(tokenId).to.equal(1); 57 | }); 58 | }); --------------------------------------------------------------------------------