開啟第二階段,主要學習合約部署、測試和預言機。
CryptoZombies的教程是用Truffle,現在主流是Hardhat,但學一學思想也有益無害。
----------------------------
update 5.3 學完了Truffle部署合約,後面幾節是部署到它們的Loom網路,就不寫這幾節的筆記了
- 啟動一個新的終端視窗,建立專案目錄並
cd
進入該目錄,執行npm install truffle -g
安裝 Truffle 並使其全域性可用。安裝Truffle後,執行truffle init
來初始化我們的新專案。它建立一組具有以下結構的資料夾和配置檔案:
├── contracts
├── Migrations.sol
├── migrations
├── 1_initial_migration.js
└── test
truffle-config.js
truffle.js
- contracts 是 Truffle 期望找到我們所有智慧合約的地方。為了保持程式碼的組織性,我們還可以建立巢狀資料夾,例如
contracts/tokens
。truffle init
會自動建立一個名為Migrations.sol
的合約以及相應的遷移檔案,用於跟蹤您對程式碼所做的更改,它的工作方式是將更改歷史記錄儲存在鏈上。因此,您不可能將相同的程式碼部署兩次。 - migrations 目錄下的一個 migration 就是一個 JavaScript 檔案,告訴 Truffle 如何部署智慧合約。
- test 目錄放置單元測試,可以是JavaScript 或 Solidity 檔案。合約一旦部署就無法更改,因此我們必須在部署智慧合約之前對其進行測試。
- truffle.js 和 truffle-config.js 是配置檔案,用於儲存部署的網路設定。 Truffle 需要兩個配置檔案,因為在Windows上將
truffle.js
和truffle.exe
放在同一個資料夾中可能會導致衝突。如果您執行的是 Windows,建議刪除truffle.js
並使用truffle-config.js
作為預設配置檔案。 - 我們將使用 Infura 將程式碼部署到以太坊,但是Infura 不管理私鑰,也就是它無法代表我們簽署交易。由於部署智慧合約需要 Truffle 簽署交易,我們需要一個名為
truffle-hdwallet-provider
的工具,它的唯一目的是處理交易簽名。由於truffle init
命令期望找到一個空目錄,我們在執行truffle init
之後安裝truffle-hdwallet-provider
。 - 以太坊虛擬機器無法直接理解我們編寫的 Solidity 原始碼,編譯器將我們的智慧合約“翻譯”為機器可讀的位元組碼,然後虛擬機器執行位元組碼,並完成我們的智慧合約所需的操作。我們將遊戲專案的所有智慧合約複製到
./contracts
資料夾中,執行truffle compile
進行編譯。此命令應建立構建工件(artifacts)並將它們放置在./build/contracts
目錄中。構建工件由智慧合約的“位元組碼”版本、ABI 以及 Truffle 用於正確部署程式碼的一些內部資料組成。避免編輯這些檔案,否則 Truffle 可能會停止正常工作。 - 如果要部署多個合約,則必須為每個合約建立單獨的migration檔案,Migrations 始終按順序執行 - 1、2、3 等。從建立好的
./contracts/1_initial_migration.js
開始,首先指令碼告訴 Truffle 我們想要與Migrations
合約進行互動,然後匯出一個函式,該函式接受deployer
物件作為引數,該物件充當您(開發人員)和 Truffle 部署引擎之間的介面。我們建立一個新的遷移檔案./contracts/2_crypto_zombies.js
來部署我們自己的合約。
var CryptoZombies = artifacts.require("./CryptoZombies.sol");
module.exports = function(deployer) {
deployer.deploy(CryptoZombies);
};
- 有幾個公共以太坊測試網可讓您在將合約部署到主網之前免費測試您的合約(請記住,一旦將合約部署到主網,就無法更改)。這些測試網路使用與主網不同的共識演算法(通常是 PoA),並且以太幣是免費的。我們將使用 Rinkeby,由以太坊基金會建立的公共測試網路。在部署之前,我們必須編輯配置檔案來告訴 Truffle 我們想要部署到的網路。正常情況下,為了避免洩露您的助記詞(或您的私鑰),您應該從檔案中讀取它並將該檔案新增到
.gitignore
。此處僅為演示方便。
// Initialize HDWalletProvider
const HDWalletProvider = require("truffle-hdwallet-provider");
// Set your own mnemonic here
const mnemonic = "YOUR_MNEMONIC";
// Module exports to make this configuration available to Truffle itself
module.exports = {
// Object with configuration for each network
networks: {
// Configuration for mainnet
mainnet: {
provider: function () {
// Setting the provider with the Infura Mainnet address and Token
return new HDWalletProvider(mnemonic, "https://mainnet.infura.io/v3/YOUR_TOKEN")
},
network_id: "1"
},
// Configuration for rinkeby network
rinkeby: {
// Special function to setup the provider
provider: function () {
// Setting the provider with the Infura Rinkeby address and Token
return new HDWalletProvider(mnemonic, "https://rinkeby.infura.io/v3/YOUR_TOKEN")
},
// Network id is 4 for Rinkeby
network_id: 4
}
}
};
- 在進行部署之前,請確保您的帳戶中有足夠的以太幣。獲取以太幣用於測試目的的最簡單方法是透過名為
faucet
的服務。我們推薦在 Rinkeby 上執行的Authenticated Faucet。在終端中執行truffle migrate --network rinkeby
以把合約部署到 Rinkeby。如果是部署到主網,在測試合約後執行truffle migrate --network mainnet
。 - 為了防止私鑰檔案被推送到 GitHub,我們建立一個名為
.gitignore
的新檔案,然後透過以下命令告訴GitHub,我們希望它忽略儲存私鑰的檔案。我們還需要編輯truffle.js
配置檔案,定義一個從檔案中讀取私鑰並初始化新的HDWalletProvider
的函式。
touch .gitignore
echo mainnet_private_key >> .gitignore
----------------------------