# DApp建立: 執行交易
## 交易的執行
**交易** 當然也是 **去中心化應用** 極為重要的一環
那要如何執行交易呢?
如果一個**程序能直接控制資產**不是很恐怖嗎?
要是**金額瞬間被轉走**怎麼辦呢?
因此我們要透過 錢包(MetaMask)
程序本身只是**提供建議交易** 再由使用者同意
**最後的同意權 仍舊落在使用者身上**
這篇將以下重點進行敘述:
1. 專案規劃
2. 透過 web3.js 進行交易
3. 透過 ethers.js 進行交易
4. 最終呈現畫面
**另外可參考 GitHub 專案位置:**
https://github.com/weiawesome/dapp_website
## 專案規劃
### 佈局規劃
![](https://hackmd.io/_uploads/BkJAu-N-6.png)
* 標題
```寫下本頁面的目標```
* 交易目標地址 與 交易金額
```要傳送給的帳戶地址與金額```
* 交易按鈕
```執行交易的按鈕```
* 關於交易資訊
```顯示該筆交易資訊```
* 交易查詢區域
```顯示該筆交易所在的區塊的區塊資訊```
### 架構規劃
```
├── src
│ ├── app
│ ├── pages
│ │ ├── build_transaction.tsx
│ ├── style
│ │ ├── build_transaction.css
│
```
"src/app/pages/build_transaction.tsx" 邏輯與基本布局
"src/app/style/build_transaction.css" 對上述畫面的修飾
**因此 最後畫面會顯示在 /build_transaction 這個路由下**
### 交易收據呈現
```typescript
// 交易結果物件
class Receipt{
// 交易哈希
TransactionHash:string;
// 交易發起人
From:string;
// 交易接收人
To:string | null;
// 交易所在的區塊 的 區塊哈希
BlockHash:string;
// 交易所在的區塊 的 區塊高度
BlockHeight:number| null
}
```
## 透過 web3.js 進行交易
```typescript
// 建立並執行交易 透過 web3.js
const BuildTransactionWeb3=async () => {
try {
if (!window.ethereum || !window.ethereum.isConnected()) {
throw new Error('請安裝 MetaMask 並連接到一個 Ethereum 網路');
}
const provider = window.ethereum;
const web3 = new Web3(provider);
const toAddress = addrRef.current?.value;
const amountToSend = web3.utils.toWei(valueRef.current!.value, 'ether');
const accounts = await window.ethereum.request({method: 'eth_requestAccounts'});
const account = accounts[0];
const transactionObject = {
from: account.toString(),
to: toAddress,
value: amountToSend,
};
web3.eth.sendTransaction(transactionObject)
.on('transactionHash', hash => {
console.log('交易哈希:', hash);
})
.on('receipt', transactionReceipt => {
console.log('交易收據:', transactionReceipt);
let tmp = new Receipt();
tmp.BlockHeight = Number(transactionReceipt!.blockNumber);
tmp.BlockHash = transactionReceipt!.blockHash;
tmp.TransactionHash = transactionReceipt!.transactionHash;
tmp.From = transactionReceipt!.from;
tmp.To = transactionReceipt!.to;
setR(tmp);
})
.on('error', error => {
})
} catch (error) {
console.log(error);
}
}
```
* 首先先連線 MetaMask 帳戶
* 填充交易資訊
* 執行交易並且記錄資訊
## 透過 ethers.js 進行交易
```typescript
// 建立並執行交易 透過 ethers.js
const BuildTransactionEthers=async () => {
try {
if (!window.ethereum || !window.ethereum.isConnected()) {
throw new Error('請安裝 MetaMask 並連接到一個 Ethereum 網路');
}
let provider = new ethers.BrowserProvider(window["ethereum"]);
const signer =await provider.getSigner();
const tx = {
to: addrRef.current!.value,
value: parseEther(valueRef.current!.value),
};
const transactionResponse = await signer.sendTransaction(tx);
console.log(transactionResponse);
const transactionReceipt = await transactionResponse.wait();
let tmp=new Receipt();
tmp.BlockHeight=transactionReceipt!.blockNumber;
tmp.BlockHash=transactionReceipt!.blockHash;
tmp.TransactionHash=transactionReceipt!.hash;
tmp.From=transactionReceipt!.from;
tmp.To=transactionReceipt!.to;
setR(tmp);
console.log(transactionReceipt);
} catch (error) {
console.error('提交交易時發生錯誤:', error);
}
}
```
* 首先先連線 MetaMask 帳戶
* 填充交易資訊
* 執行交易並且記錄資訊
## 最終呈現畫面
### 初始網頁畫面
![](https://hackmd.io/_uploads/B1a3xbVWa.png)
### 匯入帳戶 與 轉帳資訊
#### Ganache 畫面
![](https://hackmd.io/_uploads/BygRqcZEWp.png)
由於 現實資金轉移 需要手續費
可是我沒有 Money~Money(嗚嗚嗚)
因此使用 Ganache 做為模擬 OKKKKK~~~
接下來 就把 **第一個帳戶 轉金額給 第二個帳戶**
#### 匯入帳戶到 MetaMask
##### 1. 複製私鑰
![](https://hackmd.io/_uploads/ryCg2-4Wp.png)
* 首先帳戶右方鑰匙圖示 並且複製私鑰
##### 2. 匯入帳戶
![](https://hackmd.io/_uploads/S1lDnW4Za.png)
* 點選匯入帳戶 並且貼上 剛複製的私鑰
##### 3. 調整區塊鏈網路
![](https://hackmd.io/_uploads/rJCTFMN-a.png)
* 點擊設定並選擇新增網路(確保 Ganache 保持開啟)
##### 4. 成功匯入帳戶
![](https://hackmd.io/_uploads/ByPyTWNbT.png)
* 登入成功(記得選擇網路 本地的 Ganache)
#### 填充交易資訊
![](https://hackmd.io/_uploads/BkwDaWNbp.png)
* 複製上處第二個帳戶的地址 並且輸入轉帳金額
### 透過 web3.js 進行交易
#### 取得帳戶權限
![](https://hackmd.io/_uploads/S1o7ZfVbp.png)
* 首先必須獲得帳戶允許對於這個網站的操作
#### 確認交易
![](https://hackmd.io/_uploads/HJQERbNZT.png)
* 由本人再進行確認交易的內容
#### 察看交易結果
![](https://hackmd.io/_uploads/HyFPR-EZp.png)
* 結果包含 交易資訊 與 區塊資訊
#### 透過 Ganache 檢查
![](https://hackmd.io/_uploads/rkhhAbEWp.png)
* 與上圖對應 不論是區塊資訊或是交易資訊都相符
### 透過 ethers.js 進行交易
#### 取得帳戶權限
![](https://hackmd.io/_uploads/SJSIxGN-p.png)
* 首先必須獲得帳戶允許對於這個網站的操作
#### 確認交易
![](https://hackmd.io/_uploads/ByU6lGV-6.png)
* 由本人再進行確認交易的內容
#### 察看交易結果
![](https://hackmd.io/_uploads/HyTtWzVWp.png)
* 結果包含 交易資訊 與 區塊資訊
#### 透過 Ganache 檢查
![](https://hackmd.io/_uploads/BJxjWME-p.png)
* 與上圖對應 不論是區塊資訊或是交易資訊都相符
### 最後觀察 Ganache 帳戶狀態
![](https://hackmd.io/_uploads/rJRUzzVWp.png)
藉由上方兩筆交易:
* 區塊上增加兩塊
* 第二個帳戶多 20 ETH 第一個帳戶少 20 ETH
## 結言
透過撰寫前端程序 並配合 MetaMask 完成交易
儘管完成了轉帳 但會發現很大程度**需要使用者的互動**
而無法完全自動化 這是為何呢?
在區塊鏈中 虛擬貨幣的轉移
尤其又與資產有關 **因此對於控制性與安全性就非常重要**
透過一定程度的與使用者互動 確保了它的安全性
當然 DApp(去中心化應用程序)
也是有許多功能會自動化 而無須手動授權
不過仍是要在 **安全性** 與 **便利性** 中取得平衡
希望透過這篇能理解
1. 透過 web3.js 配合 MetaMask 執行交易
2. 透過 ethers.js 配合 MetaMask 執行交易
## 下回預告
現在透過程序還能轉帳了呢!!!
很有趣吧! 感覺好像很有樣子對嗎?
不過知道 **去中心化應用程序(DApp) 的起源**嗎?
早在 比特幣 出現時 就有類似的概念了
不過直到 **"智能合約"** 的出現
讓人發現 **去中心化應用程序(DApp)** 不必再侷限於**單純的資金轉移**
更多的想法與應用也隨之而生!!!
### 下回 "DApp建立: 智能合約的互動"