openwrt web認證(Web3系列教程之進階篇——3. ETH域名服務(ENS))
背景
當網絡最初開始時,你在網上探索信息的唯一方法是輸入IP地址。此后,DNS的概念被引入,幫助我們將域名與IP地址聯系起來。
因此,只要你輸入hicoldcat.com,DNS就會負責將其翻譯成相應的IP,這就是計算機最終理解的內容。
什么是 ENS?
ENS 即The Ethereum Name Service,它與DNS在web2空間的行為非常相似。
我們都知道,以太坊的地址很長,很難記住或輸入。
ENS通過將這些錢包地址、哈希值等翻譯成可讀域,然后保存在以太坊區塊鏈上,解決了這個問題
ENS最好的部分是,與集中式的DNS服務器不同,ENS在智能合約的幫助下工作,具有抗審查能力。
因此,現在當你向某人發送你的錢包地址,看起來像0x1234huiahi....,你實際上可以向他們發送tom.eth,ENS會發現tom.eth實際上等于你的錢包地址(0x1234huiahi....)。
要求
是時候使用ENS開發一些東西了。
我們將開發一個網站,如果一個地址有ENS,它可以顯示這個地址的ENS。
開始吧!
設置
首先讓我們為你的地址取一個 ENS 名稱,從打開https://app.ens.domains/開始
當你打開網站的時候,確保你的 MetaMask 已經連接到 Rinkeby 測試網絡,并且它有一些 Rinkeby Ether
搜索一個 ENS 域名,任何你喜歡的名稱,只要它是可用的!
點擊 Available
然后點擊Request To Register 申請注冊
當進度條進入第三步時,點擊Register注冊
然后在進度條完成后,點擊Set As Primary ENS Name設置為主要ENS名稱。
然后從下拉列表中選擇您剛剛創建的 ENS 名稱
點擊save保存
現在你在Rinkeby的地址上注冊了一個ENS系統
牛逼,你做到了!
網站
為了開發網站,我們將使用 React 和 Next Js。React 是一個用于創建網站的 javascript 框架,而 Next.js 是一個 React 框架,它也允許編寫后端 API 代碼以及前端,所以你不需要兩個獨立的前端和后端服務。
首先,您需要創建一個新的next應用程序。您的文件夾結構應該類似于
- ENS - my-app
要創建這個next-app應用程序,在終端指向ENS文件夾并輸入
npx create-next-app@latest
然后按回車鍵確認所有問題
現在運行應用程序,在終端中執行這些命令
cd my-appnpm run dev
現在進入 http://localhost:3000,你的應用程序應該正在運行
現在讓我們安裝 Web3Modal 庫[1]。Web3Modal 是一個易于使用的庫,可以幫助開發人員輕松地允許用戶使用各種不同的錢包連接到 dApps。默認情況下,Web3Modal Library 支持注入式提供者(Metamask、 Dapper、 Gnosis Safe、 Frame、 Web3 Browser 等)和 WalletConnect,你也可以輕松配置該庫以支持 Portis、 Fortmatic、 Squarelink、 Torus、 Autherum、 D’cENT Wallet 和 Arkane。打開一個指向 my-app 目錄的終端并執行以下命令
npm install web3modal
在同一終端中還要安裝ethers.js
npm install ethers
在 my-app/public 文件夾中,下載該圖像[2]并將其重命名為 Learnweb3Punks.png
現在轉到 style 文件夾,用下面的代碼替換 Home.modules.css 文件的所有內容,這會給你的 dapp 添加一些樣式:
.main { min-height: 90vh; display: flex; flex-direction: row; justify-content: center; align-items: center; font-family: "Courier New", Courier, monospace;}.footer { display: flex; padding: 2rem 0; border-top: 1px solid #eaeaea; justify-content: center; align-items: center;}.image { width: 70%; height: 50%; margin-left: 20%;}.title { font-size: 2rem; margin: 2rem 0;}.description { line-height: 1; margin: 2rem 0; font-size: 1.2rem;}.button { border-radius: 4px; background-color: blue; border: none; color: #ffffff; font-size: 15px; padding: 20px; width: 200px; cursor: pointer; margin-bottom: 2%;}@media (max-width: 1000px) { .main { width: 100%; flex-direction: column; justify-content: center; align-items: center; }}
在 page 文件夾下打開 index.js 文件并粘貼以下代碼,代碼說明可以在注釋中找到。
import Head from "next/head";import styles from "../styles/Home.module.css";import Web3Modal from "web3modal";import { ethers, providers } from "ethers";import { useEffect, useRef, useState } from "react";export default function Home() { // walletConnected keep track of whether the user's wallet is connected or not const [walletConnected, setWalletConnected] = useState(false); // Create a reference to the Web3 Modal (used for connecting to Metamask) which persists as long as the page is open const web3ModalRef = useRef(); // ENS const [ens, setENS] = useState(""); // Save the address of the currently connected account const [address, setAddress] = useState(""); /** * Sets the ENS, if the current connected address has an associated ENS or else it sets * the address of the connected account */ const setENSOrAddress = async (address, web3Provider) => { // Lookup the ENS related to the given address var _ens = await web3Provider.lookupAddress(address); // If the address has an ENS set the ENS or else just set the address if (_ens) { setENS(_ens); } else { setAddress(address); } }; /** * A `Provider` is needed to interact with the blockchain - reading transactions, reading balances, reading state, etc. * * A `Signer` is a special type of Provider used in case a `write` transaction needs to be made to the blockchain, which involves the connected account * needing to make a digital signature to authorize the transaction being sent. Metamask exposes a Signer API to allow your website to * request signatures from the user using Signer functions. */ const getProviderOrSigner = async () => { // Connect to Metamask // Since we store `web3Modal` as a reference, we need to access the `current` value to get access to the underlying object const provider = await web3ModalRef.current.connect(); const web3Provider = new providers.Web3Provider(provider); // If user is not connected to the Rinkeby network, let them know and throw an error const { chainId } = await web3Provider.getNetwork(); if (chainId !== 4) { window.alert("Change the network to Rinkeby"); throw new Error("Change network to Rinkeby"); } const signer = web3Provider.getSigner(); // Get the address associated to the signer which is connected to MetaMask const address = await signer.getAddress(); // Calls the function to set the ENS or Address await setENSOrAddress(address, web3Provider); return signer; }; /* connectWallet: Connects the MetaMask wallet */ const connectWallet = async () => { try { // Get the provider from web3Modal, which in our case is MetaMask // When used for the first time, it prompts the user to connect their wallet await getProviderOrSigner(true); setWalletConnected(true); } catch (err) { console.error(err); } }; /* renderButton: Returns a button based on the state of the dapp */ const renderButton = () => { if (walletConnected) { <div>Wallet connected</div>; } else { return ( <button onClick={connectWallet} className={styles.button}> Connect your wallet </button> ); } }; // useEffects are used to react to changes in state of the website // The array at the end of function call represents what state changes will trigger this effect // In this case, whenever the value of `walletConnected` changes - this effect will be called useEffect(() => { // if wallet is not connected, create a new instance of Web3Modal and connect the MetaMask wallet if (!walletConnected) { // Assign the Web3Modal class to the reference object by setting it's `current` value // The `current` value is persisted throughout as long as this page is open web3ModalRef.current = new Web3Modal({ network: "rinkeby", providerOptions: {}, disableInjectedProvider: false, }); connectWallet(); } }, [walletConnected]); return ( <div> <Head> <title>ENS Dapp</title> <meta name="description" content="ENS-Dapp" /> <link rel="icon" href="/favicon.ico" /> </Head> <div className={styles.main}> <div> <h1 className={styles.title}> Welcome to LearnWeb3 Punks {ens ? ens : address}! </h1> <div className={styles.description}> Its an NFT collection for LearnWeb3 Punks. </div> {renderButton()} </div> <div> <img className={styles.image} src="./learnweb3punks.png" /> </div> </div> <footer className={styles.footer}> Made with ? by LearnWeb3 Punks </footer> </div> );}
現在在指向 my-app 文件夾的終端中,執行
npm run dev
ENS 應用程序現在應該可以正常工作了
推到 Github
在繼續之前,請確保已將所有代碼推送到 github :)
部署 dApp
我們現在將部署您的 dApp,這樣每個人都可以看到您的網站,您可以與您所有的 LearnWeb3DAO 朋友分享它。
進入Vercel[3],用你的GitHub登錄
然后點擊新建項目按鈕,然后選擇您的ENS dApp repo
在配置你的新項目時,Vercel將允許你定制你的根目錄
點擊根目錄旁邊的編輯,并將其設置為我的應用程序
選擇框架為Next.js
單擊 "部署"。
現在,你可以通過進入你的儀表板,選擇你的項目,并從那里復制URL,看到你部署的網站
引用鏈接
[1] Web3Modal 庫: https://github.com/Web3Modal/web3modal
[2] 該圖像: https://github.com/LearnWeb3DAO/ENS/blob/main/my-app/public/learnweb3punks.png
[3] Vercel: https://vercel.com/