Table of Contents

在上一篇文章中,我們已經在localhost部屬好合約,以及取得了合約的地址。合約只存在在測試環境中,所以如果我們中斷了localhost,則需要按照上一篇 開發你的第一個DApp (四) 的說明重新部屬一次,才能在localhost找到這份合約。

使用 React App 來存取合約

有合約後,我們便可以對它進行存取,這次的sample project中也已經自動準備好了一個app示例檔案。打開 src/App.js,可以看到基本架構是:先import一些所需的元素後,再開始定義一個名為App的function。function執行後會return出來一些html code,最後會將執行結果導出。

App.js 裡面的基本架構

看出來了嗎?我們終於來到與實做網頁相關的環節了,大致了解裡面在做甚麼之後,接下來我們將對這個檔案進行修改。

開始修改App.js

首先匯入react、ethers (一個web3 library)、css檔、以及前篇有提到的Greeter合約

import { useState } from 'react';
import { ethers } from 'ethers
import './App.css';
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'

再來寫上我們的合約地址 (請把地址替換成 開發你的第一個DApp (四) 中產生出來的地址)

const greeterAddress = "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512"

接下來定義function App,{ }中的內容要填什麼後面會詳述

function App() { }

最後,匯出執行結果

export default App;

App function 的內容

首先設定要在browser的local存什麼內容

const [greeting, setGreetingValue] = useState()

接下來我們要設定幾個function,分別是連接錢包(requestAccount)、讀取greeting的值(fetchGreeting)、以及修改greeting的值(setGreeting)。

  async function requestAccount() {                  
   await window.ethereum.request({ method: 'eth_requestAccounts' });
 }

 async function fetchGreeting() {
   if (typeof window.ethereum !== 'undefined') {
     const provider = new ethers.providers.Web3Provider(window.ethereum)
     const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
     try {
       const data = await contract.greet()
       console.log('data: ', data)
     } catch (err) {
       console.log("Error: ", err)
     }
   }
 }

 async function setGreeting() {
   if (!greeting) return
   if (typeof window.ethereum !== 'undefined') {
     await requestAccount()
     const provider = new ethers.providers.Web3Provider(window.ethereum);
     const signer = provider.getSigner()
     const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
     const transaction = await contract.setGreeting(greeting)
     await transaction.wait()
     fetchGreeting()
   }
 }

最後,在return()內寫上網頁要顯示的html

return (
   <div className="App">
     <header className="App-header">
       <button onClick={fetchGreeting}>Fetch Greeting</button>
       <button onClick={setGreeting}>Set Greeting</button>
       <input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />
     </header>
   </div>
 );

修改過後的App.js

完整修改過的檔案內容會是以下這樣(圖中我也增加了一些註解):

Run!

完成App.js的編輯後,就可以compile我們的第一個dapp了!輸入以下指令:

npm start

執行後,畫面會出現compiled successfully的字樣,瀏覽器也會自動跳出網址是http://localhost:3000的網頁

compile成功後會出現這個畫面
緊接著瀏覽器會跳出可供使用者操作的ui介面

實際操作看看我們的第一個Dapp吧

按下Fetch Greeting的按鈕,再打開F12 console,會出現 "Hello, Hardhat!" 字樣


在網頁的輸入框隨意輸入字串,例如 "Hello! Bonnie is here!",按下Set Greeting按鈕,metamask會跳出視窗請求連接帳戶,並會請求簽署合約。選到我們的測試帳戶後進行簽署。

簽署完成後console會出現修改過的字串。紀錄視窗也會顯示出簽署或的合約內容。