Deploying it to the World So, we have it working great locally, how do we get it out to the world?
Deploying smart contract to Goerli test network Get some test GoEth I really recommend this faucet https://goerli-faucet.pk910.de/ . It doesn’t register any account. It is easy.
Get the goerli RPC url sign up the https://infura.io and you can find it.
It looks like this:https://goerli.infura.io/v3/YOUR_API_KEY
Get the etherscan api key to verify https://etherscan.io/myapikey here find your api key.
The smart contract deploys to Goerli test network 1 2 3 // on ./DApp-Demo cd chain_endforge create --rpc-url https://goerli.infura.io/v3/YOUR_API_KEY --private-key YOUR_PRIVATE_KEY src/Counter.sol:Counter --etherscan-api-key YOUR_ETHERSCAN_API_KEY --verify
Output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [⠆] Compiling... No files changed, compilation skipped Deployer: 0x858F72b2919d5A5794bE7b93ce4e603f8FFB8792 Deployed to: 0x4B54941BB18D54dD78D9bA598bc799a759c671c9 Transaction hash : 0x736ac18b04092b9acf3d4140ae49d7e93e450a49f14fe96081ed5e4fe26f38cc Starting contract verification... Waiting for etherscan to detect contract deployment... Submitting verification for [src/Counter.sol:Counter] "0x4B54941BB18D54dD78D9bA598bc799a759c671c9" . Submitting verification for [src/Counter.sol:Counter] "0x4B54941BB18D54dD78D9bA598bc799a759c671c9" . Submitting verification for [src/Counter.sol:Counter] "0x4B54941BB18D54dD78D9bA598bc799a759c671c9" . Submitting verification for [src/Counter.sol:Counter] "0x4B54941BB18D54dD78D9bA598bc799a759c671c9" . Submitting verification for [src/Counter.sol:Counter] "0x4B54941BB18D54dD78D9bA598bc799a759c671c9" . Submitted contract for verification: Response: `OK` GUID: `ukrqjb5n3rmrxbns2jf91a2nbbmiqkjv8vticjhti3t4dzw6jf` URL: https://goerli.etherscan.io/address/0x4b54941bb18d54dd78d9ba598bc799a759c671c9 Waiting for verification result... Contract successfully verified
Please remember this is deployed to value. It is your smart contract address.
Checks it on Etherscan
Our code was verified. Nice!
Deploying website to IPFS Update our front-end code We need to do two things:
replace StaticJsonRpcProvider
with InfuraProvider
Uses the correct smart contract address. replace const COUNTER_ADDRESS
value.
We changed our front_end/pages/index.tsx
file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 import type { NextPage } from 'next' import React from 'react' import { useState, useEffect } from 'react' import { ethers } from 'ethers' import { Counter __factory } from '../generated/contract-types' import { Navbar , Footer , Card , Label , TextInput , Button , Alert , } from 'flowbite-react' declare let window : any const Home : NextPage = () => { const [address, setAddress] = useState<string>() const [balance, setBalance] = useState<string>() const [count, setCount] = useState<number>(0 ) const [number, setNumber] = useState<number>(0 ) const [time, setTime] = useState (Date .now ()) const COUNTER_ADDRESS = '0x4B54941BB18D54dD78D9bA598bc799a759c671c9' useEffect (() => { const interval = setInterval (() => setTime (Date .now ()), 5000 ) return () => { clearInterval (interval) } }, []) useEffect (() => { const provider = new ethers.providers .InfuraProvider ('goerli' ) const counter = Counter __factory.connect (COUNTER_ADDRESS , provider) if (counter) { counter.number ().then ((count ) => { setCount (count.toNumber ()) }) } }, [time]) const handleConnectWallet = async ( ) => { const provider = new ethers.providers .Web3Provider (window .ethereum ) await provider.send ('eth_requestAccounts' , []) const signer = provider.getSigner () setAddress (await signer.getAddress ()) setBalance (ethers.utils .formatEther (await signer.getBalance ())) } const handleRefresh = async ( ) => { const provider = new ethers.providers .InfuraProvider ('goerli' ) const counter = Counter __factory.connect (COUNTER_ADDRESS , provider) const n = await counter.number () setCount (n.toNumber ()) } const handleIncrement = async ( ) => { console .log ('increment' ) const provider = new ethers.providers .Web3Provider (window .ethereum ) const signer = await provider.getSigner () const counter = Counter __factory.connect (COUNTER_ADDRESS , signer) await counter.increment () } const handleSetNumber = async ( ) => { console .log ('set number' ) const provider = new ethers.providers .Web3Provider (window .ethereum ) const signer = await provider.getSigner () const contract = Counter __factory.connect (COUNTER_ADDRESS , signer) await contract.setNumber (number) } return ( <div className ="" > <Navbar fluid ={true} rounded ={true} > <Navbar.Brand href ="/" > <img src ="https://flowbite.com/docs/images/logo.svg" className ="mr-3 h-6 sm:h-9" alt ="Flowbite Logo" /> <span className ="self-center whitespace-nowrap text-xl font-semibold dark:text-white" > DApp Demo </span > </Navbar.Brand > <Navbar.Toggle /> <Navbar.Collapse > {address ? ( <> <div > {address}</div > <div > {balance}</div > </> ) : ( <Button onClick ={handleConnectWallet} > Connect Wallet</Button > )} </Navbar.Collapse > </Navbar > <Alert color ="warning" additionalContent ={ <> <a href ={ `https: //goerli.etherscan.io /address /${COUNTER_ADDRESS }`} className ="mr-2 inline-flex items-center rounded-lg bg-yellow-700 px-3 py-1.5 text-center text-xs font-medium text-white hover:bg-yellow-800 focus:ring-4 focus:ring-yellow-300 dark:bg-yellow-800 dark:hover:bg-yellow-900" > View more </a > </> } > <div className ="flex w-full justify-between flex-row space-x-5" > <div > <span className ="font-medium" > Alert!</span > This smart contract runs on the Goerli testnet. </div > </div > </Alert > <div className ="min-w-screen min-h-full mx-auto mt-8" > <div className ="container flex flex-col justify-center items-center space-y-5" > <div className ="text-3xl font-bold" > Counter {count}</div > <Button color ="light" onClick ={handleRefresh} > Refresh Counter </Button > <Card > <Button onClick ={handleIncrement} > Increment Counter</Button > </Card > <Card > <div > <div className ="mb-2 block" > <Label htmlFor ="number" value ="Set Number" /> </div > <TextInput id ="number" type ="number" placeholder ="Enter number" value ={number} required ={true} onChange ={(e) => setNumber(parseInt(e.target.value))} /> </div > <Button type ="submit" onClick ={handleSetNumber} > Submit </Button > </Card > </div > </div > <Footer container ={true} > <Footer.Copyright href ="#" by ="OhMyApps™" year ={new Date ().getFullYear ()} /> <Footer.LinkGroup > <Footer.Link href ="#" > About</Footer.Link > <Footer.Link href ="#" > Privacy Policy</Footer.Link > <Footer.Link href ="#" > Licensing</Footer.Link > <Footer.Link href ="#" > Contact</Footer.Link > </Footer.LinkGroup > </Footer > </div> ) } export default Home
Update front end project config
Open package.json
and add the following scripts
1 2 3 4 5 6 7 8 ... "scripts" : { "dev" : "next" , "build" : "next build" , "start" : "next start" , "export" : "next export" } ...
Open next.config.js
and add two lines of code.
1 2 3 4 5 6 module.exports = { reactStrictMode: true , exportTrailingSlash: true , assetPrefix: './', }
Deploys front end project to IPFS We will use the fleek to help us to deploy our front end project.
The fleek likes vercel . They are the same and easy to use. Just the fleek pushes the file to IPFS.
So First we sign up the fleek or sign in if you already have an account.
Then,
Create a new site
Connect to Github
Pick a repository
Deploy location
Build options, and deploy!
Framework selects Next.JS
Build commandnpm install && npm run build && npm run export
changes to
cd front_end && npm install && npm run build && npm run export
Publish directoryout
changes tofront_end/out
All right. Wait a few minutes.
You will see like:
We can click Verify on IPFS
to verify our website on IPFS.
This is url likes https://ipfs.fleek.co/ipfs/QmcNoHXxrpaxyxKhLhpUoFDzzycvx7o2fUh9mXiG83Xph4/
The QmcNoHXxrpaxyxKhLhpUoFDzzycvx7o2fUh9mXiG83Xph4
is your unique token.
We can replace the URL to https://ipfs.io/ipfs/QmcNoHXxrpaxyxKhLhpUoFDzzycvx7o2fUh9mXiG83Xph4/
for 100% verification on IPFS.
Everything looks great.
Summary So exciting, We build a real 100% decentralized application from 0 to 1.
We used all modern tech stack:
NextJS
TailwindCSS
Solidity
Foundry
IPFS
We deploy a smart contract on Goerli test network and deploy a website on IPFS.
You can find the code on github and visit the website on custom domain or IPFS domain
P.S. This article is very subjective. If you do not feel comfortable viewing it, please close it as soon as possible. If you think my article can help you, you can subscribe to this site by using RSS .
Referrals Photo by GuerrillaBuzz Crypto PR on Unsplash
https://blog.fleek.co/posts/fleek-nextJS
https://github.com/Velenir/nextjs-ipfs-example