# DApp建立: 智能合約的互動 ## 智能合約的互動 **"智能合約的互動"** 是 **"DApp(去中心應用程序)"** 變為更多可能性的契機 為甚麼這麼說呢? 其實早在比特幣出現時就有人提出DApp(去中心應用程序) 其實根本原因 **"區塊鏈就是一種資料庫"**(在實踐區塊鏈時應能理解) ### 在傳統的 主從式架構應用程序(App、Website) ![](https://hackmd.io/_uploads/BkMxwFrZa.png) * 傳統應用程序(根據客戶不同請求 查詢資料庫後回答) ### 去中心化應用程序架構(未有智能合約) 那既然 **區塊鏈就是一種資料庫(公開的)** 完全沒必要依賴 中心化後端給予的回覆 **自己查詢即可** ![](https://hackmd.io/_uploads/SJVeeFSW6.png) * 是能擺脫中心化後端的需求 不過略顯無聊 ### 去中心化應用程序架構(有智能合約) 而 智能合約 本質上就是程序 根據不同選擇有不同回應 這樣的特性導致 **智能合約就類似傳統後端功能** (不過在區塊鏈上且公開的) ![](https://hackmd.io/_uploads/HJTHPKrWa.png) * 增加互動的環節(可以根據不同的請求有不同的回覆) --- 理解對於智能合約 如何讓 DApp(去中心應用程序) 變得更趣味後 接下來這篇將以下重點進行敘述: 1. 專案規劃 2. 合約互動的函式 3. 最終呈現畫面 4. 合約的互動 **另外可參考 GitHub 專案位置:** https://github.com/weiawesome/dapp_website ## 專案規劃 ### 佈局規劃 ![](https://hackmd.io/_uploads/H1jvgur-a.png) * 標題 ```寫下本頁面的目標``` * 合約地址 與 合約 ABI 文件 ```分別得知合約的位置 與 內容輸入輸出``` * 執行合約互動區塊 ```執行交易的按鈕``` * 函式、事件 選擇 ```選擇觀察事件或是執行函式``` * 輸入參數 ```根據該筆事件或函數有不同的參數``` * 是否轉帳金額 ```當函式可以付款時 詢問付款金額``` * 執行結果 ```即與合約的互動結果``` * 新增執行區塊 ```可新增與上方相同的新一個區塊``` ```方便同時執行不同函式或觀察事件``` ### 架構規劃 ``` ├── src │ ├── app │ ├── pages │ │ ├── interact_contract.tsx │ ├── style │ │ ├── interact_contract.css │ ``` "src/app/pages/interact_contract.tsx" 邏輯與基本布局 "src/app/style/interact_contract.css" 對上述畫面的修飾 **因此 最後畫面會顯示在 /interact_contract 這個路由下** ### 執行合約互動的內容 ```typescript // 合約方法或事件的資訊 class ContractMethod{ // 合約執行結果 Result:string; // 種類 (函式或事件) Type:string; // 方法名稱 或 事件名稱 Method:string; // 執行方法的參數 Parameters:string[]; // 執行方法或事件的序列 Index:number; // 是否可付款 Payable:boolean; // 金額 Amount:number; } ``` ## 合約互動的函式 ```typescript // 合約互動的方法 const ContractInteraction=async (index) => { // 檢查是否安裝 MetaMask if (typeof window.ethereum !== 'undefined') { // 定義 合約地址 與 ABI const contractAddress = addressRef.current!.value; const contractAbi = abiContent; await window.ethereum.request({method: 'eth_requestAccounts'}); // 連線 MetaMask const provider=new ethers.BrowserProvider(window.ethereum); const signer = await provider.getSigner(); // 建立合約實體 const contract = new ethers.Contract(contractAddress, contractAbi, signer); // 對於觀察事件的處理方式 其他則為函式 if (workers[index].Type==="event"){ const filter = contract.filters[workers[index].Method](); const events = await contract.queryFilter(filter); let tmp=[...workers] let ans=[]; for (let i = 0; i < events.length; i++) { // @ts-ignore ans.push({"index":i,"Value":events[i].args.toString()}) } tmp[index].Result=JSON.stringify(ans); setWorkers(tmp); } else{ // 對於函式可以付款的方式 其他則為非付款 if (workers[index].Payable===true){ const basicFoundation = ethers.parseEther(workers[index].Amount.toString()); await contract[workers[index].Method](...workers[index].Parameters,{value:basicFoundation}).then((result)=>{ console.log("Result: ",result.toString()); let tmp=[...workers]; tmp[index].Result=result.toString(); setWorkers(tmp); }).catch((e)=>{ alert(e); }) } else{ await contract[workers[index].Method](...workers[index].Parameters).then((result)=>{ console.log("Result: ",result); let tmp=[...workers]; tmp[index].Result=result.toString(); setWorkers(tmp); }).catch((e)=>{ alert(e); }) } } } else { alert('請安裝 MetaMask 錢包並連接到網絡'); } } ``` 1. 載入對於合約的各種基本資訊 包含 地址、ABI 2. 連線 MetaMask 錢包 並且獲得許可 3. 根據內容執行函式 或 觀察事件 4. 將結果寫進目標結果的位置 ## 最終呈現畫面 ![](https://hackmd.io/_uploads/SJxnEdBW6.png) * UI 與上方規劃相同 * 可以根據不同的合約選擇不同的函式或事件 ## 合約的互動 (詳細部署與撰寫智能合約的方式請詳見 **智能合約開發** 章節) ### 公平、公正投票 #### 1. 部署智能合約 ![](https://hackmd.io/_uploads/rJPlL_BWT.png) * 基礎資金為 10 ETH 投票、開票時間 與 合約地址 #### 2. 填充合約資訊 ![](https://hackmd.io/_uploads/rkekIuBWT.png) * 填入上方合約地址 與 選擇 ABI 檔案 #### 3. 函示範例 ![](https://hackmd.io/_uploads/Bk8mUdrZp.png) * 此為註冊為候選人之函式 #### 4. MetaMask 確認畫面(如果需要付款才會出現) ![](https://hackmd.io/_uploads/B1v8U_SZT.png) * 確認轉款金額 與 目標地址 #### 5. 事件範例 ![](https://hackmd.io/_uploads/SkI5UOSW6.png) * 確實為剛才所登記參選的資料 ### 群眾募資 #### 1. 部署智能合約 ![](https://hackmd.io/_uploads/r1WLPOSbp.png) * 顯示合約部署的地址 #### 2. 填充合約資訊 ![](https://hackmd.io/_uploads/rJomPOSZa.png) * 填入上方合約地址 與 選擇 ABI 檔案 #### 3. 函示範例 ![](https://hackmd.io/_uploads/Sk1ZdOBWp.png) * 此為向平台提案的函示 #### 4. MetaMask 確認畫面(如果需要付款才會出現) ![](https://hackmd.io/_uploads/BJu2wuSb6.png) * 確認轉款金額 與 目標地址 #### 5. 事件範例 ![](https://hackmd.io/_uploads/SJwuO_HW6.png) * 確實新增一筆剛才的提案 (可以看見子合約的地址) ## 結言 由於**篇幅有限** 最後在示範與合約互動時 僅挑出幾個進行示例 若是有興趣可以**下載專案** 並且來**嘗試與智能合約的互**動 真心蠻有趣的 希望透過這篇能理解 1. 如何與智能合約互動 2. 智能合約 為 DApp(去中心化應用程序) 帶來的變化 ## 下回預告 感覺程序瞬間變得超有趣 對吧~~~ 也瞬間增加了許多可能性 既能**以此做為投票** 還能**建立群眾募資** 等等等等 這一切都多虧與智能合約的互動 使許多功能都成為了可能 只能說瞬間感到一身輕 擺脫了傳統的後端限制 **寫完前端 是時候來處理後端** 等等等!!! 甚麼不是才剛擺脫(後端)的需求嗎? 為甚麼還要使用後端呢? 這樣**還算是去中心化**嗎 這不是**完全違背了核心理念**嗎? 鐵定有很多疑問吧! ### 下回 "DApp建立: 後端服務尬上來"