Hardhat 部署合約到外部網路

林俊宇的學習筆記
8 min readApr 20, 2022

--

Hardhat 在部署時預設部署在本機的 Hardhat 網路,本文說明如何部署到外部網路 Rinkeby

建立專案

先建立專案,為了示範從無到有的建置過程,執行 npx hardhat 時,選擇 “Create an empty hardhat.config.js”

mkdir <project_directory>
cd <project_directory>
npm init -y
npm install --save-dev hardhat
# create sample project, 這邊選 "Create an empty hardhat.config.js"
npx hardhat
# install package
npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers

建立合約

建立 contracts 目錄,並新增 Greeter.sol,constructor 需傳入參數,在 deploy 時會說明如何設定參數內容。

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
contract Greeter {
string private greeting;
constructor(string memory _greeting) {
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
}

修改 hardhat.config.js

設定 solidity 版本

依據合約使用的 solidity 版本,要調整 hardhat.config.js 的 solidity 版本設定,這邊指定 0.8.0 版

module.exports = {
solidity: "0.8.0", // 這邊填上 solidity 的版本
};

設定 plugin

在 Deploy 或 Test 時會用到 Hardhat 的 plugin,需將 plugin 加入到 Hardhat Runtime Environment(HRE) 中,HRE 的說明可參考 這裡 ,可在 hardhat.config.js 定義所需的 plugin。

在 Deploy 合約時會用到 @nomiclabs/hardhat-ethers plugin 的 getContractFactory(),因此需在 config 加上 require(“@nomiclabs/hardhat-ethers”); 另外 Test 時會用到 @nomiclabs/hardhat-waffle plugin,而此 plugin 有用到 hardhat-ethers,它會自動將 ethers 注入到 HRE 中,因此我們只需加入 waffle plugin

solidity 版本及 plugin 設定後的 hardhat.config.js 內容如下

require("@nomiclabs/hardhat-waffle");module.exports = {
solidity: "0.8.0", // 這邊填上 solidity 的版本
};

Alchemy 建立部署的網路設定

要將合約部署到鏈上可透過 Provider 的 API 部署,可以使用 Alchemy 或是 Infura,這邊使用 Alchemy 做為示範,首先到 Alchemy 註冊,註冊後到 Create App 功能建立要部署的網路,下例設定 Rinkeby 網路

建立網路後到 Dashboard 可看到剛建立的 rinkeby 設定

點選 rinkeby 項目最右邊的 View Key ,在彈出的小視窗按下 HTTP 項目的 Copy,這個內容之後會填到 Hardhat 的設定檔

Config 檔設定部署的 network

hardhat.config.js 部署網路的設定寫在 networks 項目,詳細的設定可參考 這裡,以 rinkeby 網路為例,加上 rinkeby 項目及 url 及 accounts,url 填入上面在 Alchemy 複製的 HTTP url,accounts 填入要部署到 rinkeby 的錢包 private key,這邊要特別注意的是填 「private key」,不是錢包地址,如果是用 metamask 可以到導出私鑰的功能取得 private key

require("@nomiclabs/hardhat-waffle");module.exports = {
networks: {
rinkeby: {
url: "<https://eth-rinkeby.alchemyapi.io/v2/<your alchemyapi key>",
accounts: ['your private key']
}
},
solidity: "0.8.0", // 這邊填上 solidity 的版本
};

metamask 導出私鑰的作法

  • 選選帳戶右方3個小點,再選擇帳戶詳情
  • 導出私鑰
  • 輸入 metamask 密碼再按確認
  • 複製私鑰

Deploy 合約

建立 scripts 目錄,新增 deploy.js

const hre = require("hardhat");async function main() {
// We get the contract to deploy
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");

console.log("Greeter deployed to:", greeter.address);
}

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

ethers.getContractFactory(“Greeter”) 會取得 Greeter 的 ContractFactory,然後再呼叫 deploy() 部署合約, 若合約的 constructor 有需要參數則可在 deploy()中填入參數內容,這邊填入 “Hello, Hardhat!”

deploy() 後可用 greeter.address 取得合約部署的地址,再將地址印出方便確認部署的結果

執行 npx hardhat run <script file>- -network <network name> 部署合約,參數說明如下

  • <script file>:要部署的檔案,也就是上面提到的 deploy.js
  • <network name>: 部署的網路名稱,需 hardhat.config.js 中 networks 項目中有定義,這邊使用 rinkeby

執行指令如下

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

執行後的輸出為 “Greeter deployed to: 0xcAF8f43cCd24E2a5ed93B027DDf2f3F7961F3114”,最後面那一串文字就是部署的地址,接下來到 etherscan 查詢部署結果https://rinkeby.etherscan.io/address/0xcAF8f43cCd24E2a5ed93B027DDf2f3F7961F3114

--

--