#去中心化應用
【區塊鏈】去中心化應用(DApp)開發——DApp 前端開發
一、DApp 前端開發基礎概念1、 什麼是 DApp 前端?DApp(去中心化應用)前端是與區塊鏈網路互動的使用者介面層,主要特點包括: • 使用 Web3.js 或 Ethers.js 等庫連接區塊鏈• 通過錢包外掛(如 MetaMask)實現身份驗證• 直接與智能合約互動而非傳統後端 API2、推薦技術組合:1. 框架:React/Vue2. 區塊鏈互動:Ethers.js(比Web3.js更輕量)3. 狀態管理:Redux/Zustand4. UI庫:Material UI/TailwindCSS5. 開發工具:Hardhat/Truffle二、開發環境搭建1、 初始化項目# 使用Vite建立React項目(推薦)npm create vite@latest dapp-frontend --template reactcd dapp-frontend# 安裝核心依賴npm install ethers @web3-react/core @web3-react/injected-connector2、項目結構規範/src|-- /components    # 可復用元件|-- /contracts     # 合約ABI和地址配置|-- /hooks         # 自訂Hook|-- /pages         # 頁面元件|-- /styles        # 全域樣式|-- /utils         # 工具函數三、錢包連接實現(最佳實踐)1、 錢包連接器配置// src/utils/walletConnectors.jsimport { InjectedConnector } from '@web3-react/injected-connector'/** * 配置支援的區塊鏈網路 * @constant * @type {object} * @default * @property {number[]} supportedChainIds - 支援的鏈ID列表 */export const injected = new InjectedConnector({  supportedChainIds: [1, 5, 56] // 主網/Goerli/BSC})2、 錢包連接上下文// src/contexts/Web3Context.jsximport { createContext, useContext } from'react'import { useWeb3React } from'@web3-react/core'/** * Web3上下文提供者 * @component * @param {object} props - 元件屬性 * @returns {JSX.Element} 上下文提供者 */const Web3Context = createContext()exportfunction Web3Provider({ children }) {const { activate, deactivate, ...web3Data } = useWeb3React()return (    <Web3Context.Provider value={{ activate, deactivate, ...web3Data }}>      {children}    </Web3Context.Provider>  )}/** * 自訂Hook:訪問Web3上下文 * @hook * @returns {object} Web3上下文值 */exportfunction useWeb3() {return useContext(Web3Context)}四、智能合約互動封裝1、 合約Hook封裝// src/hooks/useContract.jsimport { useMemo } from'react'import { Contract } from'ethers'/** * 合約實例化Hook * @hook * @param {string} address - 合約地址 * @param {Array} abi - 合約ABI * @returns {Contract|null} 合約實例 */exportdefaultfunction useContract(address, abi) {const { library, account } = useWeb3()return useMemo(() => {    if (!address || !abi || !library) returnnull        try {      returnnew Contract(        address,        abi,        account ? library.getSigner(account) : library      )    } catch (error) {      console.error('合約實例化失敗', error)      returnnull    }  }, [address, abi, library, account])}2、 帶重試機制的合約呼叫// src/utils/contractCall.js/** * 帶重試機制的合約呼叫 * @async * @function * @param {function} callFn - 合約呼叫函數 * @param {number} [retries=3] - 最大重試次數 * @param {number} [delay=1000] - 重試間隔(ms) * @returns {Promise} 呼叫結果 */exportasyncfunction contractCallWithRetry(callFn, retries = 3, delay = 1000) {for (let i = 0; i < retries; i++) {    try {      returnawait callFn()    } catch (err) {      if (i === retries - 1) throw err      awaitnewPromise(res => setTimeout(res, delay))    }  }}五、交易狀態管理方案1、 交易狀態列舉// src/constants/transactionState.js/** * 交易狀態列舉 * @enum {string} */export const TX_STATE = {  IDLE: 'idle',  SIGNING: 'signing',  MINING: 'mining',  SUCCESS: 'success',  ERROR: 'error'}2、 交易狀態跟蹤Hook// src/hooks/useTransaction.jsimport { useState } from'react'import { TX_STATE } from'../constants/transactionState'/** * 交易狀態管理Hook * @hook * @returns {Array} [txState, handleTransaction] */exportfunction useTransaction() {const [txState, setTxState] = useState(TX_STATE.IDLE)/**   * 執行交易並跟蹤狀態   * @async   * @function   * @param {function} txFn - 交易執行函數   * @param {object} [options] - 配置選項   * @param {function} [options.onSuccess] - 成功回呼   * @param {function} [options.onError] - 失敗回呼   */asyncfunction handleTransaction(txFn, { onSuccess, onError } = {}) {    try {      setTxState(TX_STATE.SIGNING)      const tx = await txFn()            setTxState(TX_STATE.MINING)      const receipt = await tx.wait()            setTxState(TX_STATE.SUCCESS)      onSuccess?.(receipt)    } catch (err) {      setTxState(TX_STATE.ERROR)      onError?.(err)    } finally {      setTimeout(() => setTxState(TX_STATE.IDLE), 3000)    }  }return [txState, handleTransaction]}六、最佳實踐建議1、 錯誤處理原則• 所有區塊鏈呼叫必須包含try/catch• 區分使用者拒絕簽名和真實錯誤• 提供友好的錯誤提示2、 性能最佳化方案// 使用Promise.all平行查詢const [balance, allowance] = await Promise.all([  contract.balanceOf(account),  contract.allowance(account, spender)])3、安全注意事項• 永遠不要在前端硬編碼私鑰• 合約地址應該可配置(不同環境不同地址)• 對使用者輸入進行嚴格驗證4、 測試策略- 單元測試:Jest測試工具函數- 整合測試:測試合約互動元件- E2E測試:使用Cypress模擬使用者流程 (技術探索驛站)