開啓第二階段,主要學習合約部署、測試和預言機。
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
----------------------------