使用 Solidity 和 Hardhat 在 Ethereum 區塊鏈開發智能合約(一):開發與部署智能合約

前言

本文參考 Alchemy 的範例進行實作,Alchemy 是一個區塊鏈開發者平台,能夠讓開發者訪問以太坊區塊鏈上的 API 端點,並且可以讀寫交易。

本文採用的區塊鏈測試網路與範例文章不同,使用的是 rinkeby 測試網路。

前置作業

  1. 首先,在 Alchemy 註冊,並新建應用程式,選擇 Rinkeby 測試網路。
  2. 下載 MetaMask 到擴充套件,創建錢包後,將「Show test networks」選項開啟。
  3. Alchemy Rinkeby faucet 充值 Rinkeby 測試網路的 ETH 幣到自己的錢包地址。

開發

建立專案。

1
2
mkdir smart-contract-example
cd smart-contract-example

初始化專案。

1
npm init

安裝 hardhat 套件。Hardhat 是一個自動化構建智能合約的環境和工具。

1
npm install --save-dev hardhat

使用 npx 執行 hardhat 指令,並選擇「Create an empty hardhat.config.js」選項。

1
npx hardhat

新增 contracts 資料夾,用來放置智能合約。

1
mkdir contracts

新增 scripts 資料夾,用來放置部署腳本,以及與智能合約互動的腳本。

1
mkdir scripts

contracts 資料夾新增 HelloWorld.sol 檔。需要使用 Solidity 語言撰寫。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.3;

// 定義一個合約,合約是各種方法和資料的集合,一旦合約被部署,就會被放置到區塊鏈上的特定地址
contract HelloWorld {
// 定義一個事件,在某些情況下被觸發,可以用來讓客戶端監聽並採取一些行動
event UpdatedMessages(string oldStr, string newStr);

// 定義一個型別為字串的變數,此變數會被永久儲存在合約裡,公開的變數可以被外部的合約或客戶端存取
string public message;

// 定義一個建構子,在合約被創建時觸發,用來初始化合約的資料
constructor(string memory initMsg) {
// 修改 message 變數
message = initMsg;
}

// 定義一個公開方法,接受一個字串來修改 message 變數
function update(string memory newMsg) public {
string memory oldMsg = message;
message = newMsg;
emit UpdatedMessages(oldMsg, newMsg);
}
}

安裝 dot-env 套件。

1
npm install dotenv --save

新增 .env 檔。

1
2
API_URL=https://eth-rinkeby.alchemyapi.io/v2/your-api-key
PRIVATE_KEY=your-private-key

安裝 @nomiclabs/hardhat-ethersethers 套件。

1
npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"

hardhat.config.js 檔修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
solidity: "0.7.3",
defaultNetwork: "rinkeby",
networks: {
hardhat: {},
rinkeby: {
url: API_URL,
accounts: [PRIVATE_KEY],
},
},
};

使用以下指令編譯智能合約。

1
npx hardhat compile

scripts 資料夾新增 deploy.js 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
async function main() {
// 實例化一個 HelloWorld 合約工廠
const HelloWorld = await ethers.getContractFactory('HelloWorld');

// 使用合約工廠的 deploy 方法來進行部署
const hello_world = await HelloWorld.deploy('Hello World!');

// 印出合約地址
console.log('Contract deployed to address:', hello_world.address);
};

main()
.then(() => process.exit(0))
.catch((err) => {
console.error(err);
process.exit(1);
});

部署

使用以下指令,將智能合約部署在 rinkeby 測試網路。

1
npx hardhat run scripts/deploy.js --network rinkeby

顯示結果如下:

1
Contract deployed to address: 0x6839691078Ef669589F65Fca9968f6430D509812

到 Rinkeby 測試網路的 Etherscan 查看合約

程式碼

參考資料