以太坊 DApp 應用程式架構實戰指南:客戶端、伺服器端與區塊鏈落地方案

·

想要親手打造一款真正能上線運行的 以太坊 DApp,不僅得懂智能合約,更要釐清「整體應用程式架構」。本文將帶你在不超過 15 分鐘的閱讀時間裡,迅速建立 去中心化應用 的完整思維模型,並給出可落地的設計範例與程式碼片段。


為什麼傳統架構無法直接套用?

在傳統 Web2 世界,後端伺服器一手掌握資料庫與商業邏輯,前端僅需透過 API 請求即可。而 以太坊 DApp 加入了「區塊鏈」這條不可變的共用資料層,逼迫我們重新劃分前端、後端、鏈上三者的權責邊界。
👉 全方位 Ethereum 開發資源一次打包,30 天進階為 DApp 架構師。


核心概念:分層拆分

  1. 鏈上層(On-chain)
    智能合約負責資產邏輯與關鍵狀態。
    關鍵詞:智能合約、部署、gas 優化、升級代理。
  2. 中間層(Off-chain Service)
    有時仍需中心化伺服器:補足鏈上無法完成的密集計算、大量儲存或隱私需求。
    關鍵詞:索引服務、預言機、批次程式、自動化調度。
  3. 表現層(Client)
    瀏覽器或手機端,透過 Web3 函式庫與錢包互動。
    關鍵詞:web3.js、ethers.js、簽章授權、離線交易。

第一種方案:無伺服器 DApp(純前端 + 鏈上)

這是最純粹的 去中心化應用 形態:

常見程式碼片段(查詢交易)

import Web3 from 'web3';
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_KEY');

(async () => {
  const block = await web3.eth.getBlock('latest');
  console.log('最新區塊包含的交易數:', block.transactions.length);

  const tx = await web3.eth.getTransactionReceipt(block.transactions[0]);
  console.log('交易 receipt:', tx);
})();

第二種方案:輕量後端補足

若需「大量圖片」或「機器學習運算」,仍建議部署小型後端:

自動監聽事件(索引伺服器)

伺服器端透過 web3.eth.subscribe('logs') 監控事件:

contract.events.Transfer({
  filter: { from: '0xTargetAddress' },
  fromBlock: 'latest'
}, (err, event) => {
  if (err) return console.error(err);
  saveToLocalDB(event.returnValues);
});
關鍵詞:索引伺服器、事件監聽、topics 篩選器、重組鏈檢查
一筆交易被「挖出」不等於最終確認,需等待 12 區塊(≈ 3 分鐘) 以防鏈重組。

第三種方案:批次任務(Cron Job)

import Tx from 'ethereumjs-tx';
const tx = new Tx(txParams);
tx.sign(Buffer.from(PRIVATE_KEY, 'hex'));
const serialized = '0x' + tx.serialize().toString('hex');
web3.eth.sendSignedTransaction(serialized)
  .on('receipt', r => console.log('已上鏈', r.transactionHash));

常見問題 FAQ

Q1:前端錢包與 Infura 通訊不穩怎麼辦?
A:可於前端內建「後備 RPC 節點」陣列;當 Infura 逾時就自動切換至 Alchemy、自建節點或 Pocket Network,降低單點故障。

Q2:合約事件撈不到資料?
A:檢查 indexed 欄位。若事件 Transfer(address indexed from, address indexed to, uint value)fromto 會寫進 topics,其餘值存在 data,請分開解析。

Q3:重組鏈導致交易失效如何處理?
A:後台 API 須實作二次確認邏輯:交易初次回傳「接受」,等到鏈上區塊高度 >= tx.blockNumber + 12 再改狀態為「最終成功」。

Q4:大量圖片儲存成本太高?
A:採「鏈下儲存 + 鏈上證明」混合模式:圖片先存 IPFS,再在 NFT 合約內只保留 CID;若需防篡改,可在鏈下先算 Merkle Root 再上鏈。

Q5:測試網切換麻煩?
A:使用 chainId + hardhat.config.js 多網路開關 + 前端讀取 window.ethereum.chainId,可在 UI 提示用戶「請將網路切換至 Goerli」等。

Q6:如何估算 Gas?
A:呼叫 web3.eth.estimateGas({to, data, value}),再乘 1.1 安全係數;或使用 EIP-1559 時線上查 baseFee 並再加上優先費用(maxPriorityFeePerGas)。


結語:隨場景壘出最佳架構

沒有一種萬能公式可以套用所有 DApp 架構;小規模 NFT mint 可用無伺服器模式,鏈上胖、鏈下瘦;而需要 AI 推薦的 GameFi 便得中心化伺服器介入。靈活迭代、在不損去中心化核心精神的前提下,隨業務場景壘出自己的架構,才是「Web3 工程師」的終極修煉。

最後,記得不斷回頭檢視:「用戶真的需要鏈上執行這步驟嗎?」—— 只要反問三次,就能大幅壓低使用門檻與 gas 成本。祝你一鏈到底,專案早日落地。