[區塊鏈] 利用 Hardhat + React 開發/部署一個簡易的打賞 DApp

在開發區塊鏈 DApp 時,常常需要對智能合約做測試,但大班哥之前都是把合約上鏈到以太鏈測試網 Rinkeby / Reopen ,然後直接測試,雖然不會真的花到以太幣,但還是希望能在 local 端就可以直接測試跟智能合約的互動,而 Hardhat 就可以解決這個問題,它可以快速搭建一個以太坊開發的 local 環境,以下是大班哥使用的過程跟心得。

DApp 名詞解釋: DApp 全名是去中心化應用程式 (Decentralized Application),相對於過往運行在中心化服務器的App/Web DApp 的程式部署在分散式的網絡上,例如以太坊上。

透過製作打賞 DApp 來學習 Hardhat

大班哥想透過實際開發一款 DApp 來學習使用 Hardhat ,

於是便想到「打賞」這個結合虛擬貨幣支付部落格受益相關的主題,

這個 DApp 的使用情境是:

讀者在逛部落格時,認為內容有所幫助,

可以透過打賞 APP的介面使用以太幣打賞來支持我持續創作

這邊的打賞就是支付 0.01 ETH 比太幣,

預計是要做成一個小部件 widget 可以放在網站的側邊,

最終完成流程顯示如下:

最終完成預計顯示

DEMO 連結 – 大班哥打賞箱 https://donate-me.vercel.app/ ,歡迎大家前往打賞贊助 🤩

可能獲得的打賞福利

大班哥也有在想,收到打賞後,除了單純支持,能不能有更多的價值回饋使用者,

先來市場調查,問看看大家:

打賞後,希望大班哥能提供你/妳什麼回饋呢?

只是先調查唷,不一定會做,大家不要太有得失心,還是希望大家用有能力範圍內的錢來打賞,單純支持我繼續創作下去

以下開始正式介紹 Hardhat,

Hardhat 的用處

看完 Demo 大家應該很好奇, Hardhat 在開發之中是到底是扮演什麼角色吧,

最主要是解決,在開發以太坊時能夠快速搭建一個開發環境,也能讓開發人員方便測試智能約,大班哥列出主要以下功能:

  • 建立 Solidity 智能合約的基礎環境
  • 使用 Hardhat 的測試網 Debug 智能合約
  • 可以編譯 (Compile) 跟 部署 (Deploy) 智能合約到 Hardhat 測試網 / 以太主網 / 以太測試網
  • 搭配用 Ethers.js 跟 Waffle 實現自動化/單元測試

安裝 Hardhat

在安裝 hardhat 前要先用 homebrew 安裝 NodeJS

brew install node

▼ 安裝 hardhat 套件

npm init --yes
npm install --save-dev hardhat

安裝後,因為 nodeJS 預設內建 npx 命令,所以可以直接使用 npx 啟動

(npx 跟 npm 的差別只在 npx 安裝是只在當下專案,不會全局安裝)

▼ 初始化 hardhat 開發環境,以下指令

npx hardhat

大班哥是選擇 Create a basic sample project ,開始基本的開發

Hardhat 的運行

hardhat 是圍繞著 任務 (Task) 外掛 (Plugins) 來運行的,

▼ 可以透過以下指令來查看可用的 Task

npx hardhat help
可使用的 Task
可使用的 plugin

撰寫並編譯智能合約

要完成打賞這個動作,合約的內容就很重要,其實就是「轉帳」,只要能讓使用者同意,願意轉帳錢包中的 0.01 顆以太幣,就可以完成這個網站的核心功能,

▼ 下方為大班哥打賞功能的合約 Solidity 程式碼

//SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

contract DonateBigBen {

    address payable public owner;

    event BigBenEvent(
        address indexed from,
        uint256 timestamp
    );

    constructor() payable {
        owner = payable(msg.sender);
    }

    function donateMe(uint256 pay) public payable {

        uint256 lowerBound = 0.0009 ether;
        require(pay > lowerBound, "Insufficient donate amount");

        (bool success, ) = owner.call{value: pay}("");
        require(success, "Donate failed");

        emit BigBenEvent(msg.sender, block.timestamp);
    }
}

安裝 Waffle ,測試智能合約

Waffle 是專門用在智能合約上的一個測試套件,搭配 Mocha + Chai 專門跑 BDD 單元測試的套件,

讓測試智能合約時能更方便,撰寫測試也能讓可讀性更高,測試更容易,

▼ 配合 hardhat 使用時,可用以下指令安裝 Waffle 跟 Chai

install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai 

▼ 開始撰寫測試,這邊測試大班哥的合約裡,call DonateBigBen() 的結果,

如果成功,就會發射(emit) BigBenEvent 出來

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("DonateBigBen contract", function () {
  it("it should emit success event after donate complete", async function () {

    const Token = await ethers.getContractFactory("DonateBigBen");
    const hardhatToken = await Token.deploy();
    let amount = ethers.utils.parseEther("0.001");
    await expect(hardhatToken.donateMe(amount,{
      value:amount,
      gasLimit: 100000,     
    }))
    .to.emit(hardhatToken, "BigBenEvent")
  });
});

▼開始跑測試

npx hardhat test

▼ 顯示 1 passing ,表示上面撰寫的測試通過囉

把合約部署到區塊鏈上

在智能合約撰寫完後,就可以開始部署到區塊了,

以部署到 Hardhat 測試網為例,

▼ 需要先去 hardhat.config.js 設定 networks

module.exports = {
  solidity: "0.8.4",
  networks: {
    hardhat: {
      chainId: 31337
    }
  }
};

▼ 利用 Deploy.js 來把合約部署

async function main() {
  // This is just a convenience check
  if (network.name === "hardhat") {
    console.warn(
      "You are trying to deploy a contract to the Hardhat Network, which" +
      "gets automatically created and destroyed every time. Use the Hardhat" +
      " option '--network localhost'"
    );
  }

  // ethers is available in the global scope
  const Token = await ethers.getContractFactory("DonateBigBen");
  const token = await Token.deploy();
  await token.deployed();
}

▼ 開始跑 script 就可以部署了

npx hardhat run scripts/deploy.js --network localhost

▼如果想要部署到以太鏈測試網 Rinkeby,可以利用 infura 這樣的服務,

到 hardhat.config.js 裡的 networks 加上 rinkeby 的設定

把 infura 申請好的API Key 填入 url ,

加上測試 Wallet 的 private key,大班哥是另外再申請一個 Metamsk 錢包並導出私鑰專門測試用

const RINKEBY_PRIVATE_KEY = "Private Key";

networks: {
    rinkeby: {
      url: "API Key",
      accounts: [`${RINKEBY_PRIVATE_KEY}`]
    }
  }

使用 React + Ethers.js 製作 DApp

大班哥是用 React 這個前端框架來打造 DApp,

▼ 可以安裝/初始化專案

npx create-react-app my-app

▼ 跟以太鏈溝通是用到 Ethers.js 套件

install --save-dev @nomiclabs/hardhat-ethers ethers

▼React 加入後,跟 Hardhat 的整合,大班哥用一個測試小專案,目錄架構最後長這樣,

  • /fe: 表示 front-end,即 React 專案
  • /contracts:智能合約 Solidity 檔案,可能是 xxxxx.sol
  • /scripts:hardhat 要跑的客製化 script,例如 deploy.js
  • /test:hardhat 跑單元測試
  • package.config.js:設定 hardhat 環境參數,例如要跑什麼鏈

使用 Metamask 通過 Hardhat Network 來測試 DApp

▼ 以下指令,會運行一個 WebSocket server 開啟 Hardhat Network ,

讓外部可以透過 JSON-RPC 來使用,例如 Metamask 或是其他 script

npx hardhat node

可以看到會有好幾組可以使用的測試錢包

如果要讓 Metamask 可以用,要先去設定

Step 1.顯示測試網:到 Metamsk -> 「設定」-> 「進階」-> 「Show tests networks」

Step 2.網路點選: 選擇 Localhost:8545,並確認 port 是 31337 跟 hardhat.config.js 設定要一樣

跑 npx hardhat node 時記得加上 --network localhost.

小結

在這次製作網站 DApp 的過程中,Hardhat 真的是比想像中的方便使用,特別是在智能合約的測試,而且還能寫單元測試來跑,在開發中需要快速驗證合約內容時,算是有幫助到,蠻推薦有在開發以太坊智能合約跟 DApp 的開發者使用,在部署合約前可以更有信心,以上分享。



尚未有留言,成為第一個留言的人吧!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Google reCAPTCHA 保護機制,這項服務遵循 Google 隱私權政策服務條款