框架
框架可以用于簡化Ethereum智能合約的開發(fā)。通過自己做所有的事情,你就能更好地理解每件事是如何組合在一起的,但這是一項非常繁瑣、重復(fù)性的工作。下面列出的框架可以自動執(zhí)行某些任務(wù)并使開發(fā)變得輕而易舉。
Truffle
- Github鏈接:https://github.com/trufflesuite/truffle
- 網(wǎng)站鏈接:https://truffleframework.com
- 文檔鏈接:https://truffleframework.com/docs
- Truffle Boxes鏈接:http://truffleframework.com/boxes/
- npm package repository鏈接:https://www.npmjs.com/package/truffle
安裝truffle框架
truffle框架由幾個NodeJS包組成。在安裝truffle之前,我們需要安裝最新的NodeJS和node包管理器(npm)。
安裝NodeJS和npm的推薦方法是使用節(jié)點版本管理器NVM。一旦我們安裝了nvm,它將為我們處理所有的依賴項和更新。我們將遵循在http://nvm.sh中的說明。
一旦nvm安裝在您的操作系統(tǒng)上,安裝node.js就很簡單了。我們使用-lts標(biāo)志來告訴nvm,我們需要最新的NodeJS“長期支持(Long Term Support, lts)”版本
$ nvm install --lts
確認(rèn)已安裝node和npm:
$ node -v
v8.9.4
$ npm -v
5.6.0
創(chuàng)建一個DApp支持的包含Node.js版本的隱藏文件.nvmrc,因此開發(fā)人員只需在項目目錄的根目錄中運行nvm安裝,它就會自動安裝并切換到使用該版本。
$ node -v > .nvmrc
$ nvm install
看上去不錯?,F(xiàn)在安裝truffle:
$ npm -g install truffle
+ truffle@4.0.6
installed 1 package in 37.508s
集成預(yù)構(gòu)建的Truffle項目(Truffle Box)
如果我們想使用或創(chuàng)建一個基于預(yù)先構(gòu)建的樣板文件的DApp,那么在Truffle Boxes鏈接中我們可以選擇一個現(xiàn)有的Truffle項目,然后運行以下程序來下載和提取:
$ truffle unbox <BOX_NAME>
創(chuàng)建一個truffle項目目錄
對于使用truffle的每個項目,我們都創(chuàng)建一個項目目錄并在該目錄中初始化truffle。truffle將在我們的項目目錄中創(chuàng)建必要的目錄結(jié)構(gòu)。通常,我們給項目目錄一個描述項目的名稱。對于本例,我們將使用truffle來從[simple_contract_example]部署水龍頭合約,因此我們將命名項目文件夾Faucet。
$ mkdir Faucet
$ cd Faucet
Faucet $
一旦進入Faucet目錄,我們初始化truffle:
Faucet $ truffle init
Truffle創(chuàng)建了一個目錄結(jié)構(gòu)和一些默認(rèn)文件:
Faucet
├── contracts
│ └── Migrations.sol
├── migrations
│ └── 1_initial_migration.js
├── test
├── truffle-config.js
└── truffle.js
除了truffle本身,我們還將使用一些JavaScript (nodeJS)支持包。我們可以用npm安裝這些。我們初始化npm目錄結(jié)構(gòu)并接受npm建議的默認(rèn)值:
$ npm init
package name: (faucet)
version: (1.0.0)
description:
entry point: (truffle-config.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to Faucet/package.json:
{
"name": "faucet",
"version": "1.0.0",
"description": "",
"main": "truffle-config.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes)
現(xiàn)在,我們可以安裝與truffle一起使用的依賴項:
$ npm install dotenv truffle-wallet-provider ethereumjs-wallet
現(xiàn)在,在您的Faucet目錄中,有一個包含數(shù)千個文件的node_modules目錄。
在將DApp部署到云生產(chǎn)或持續(xù)集成環(huán)境之前,有必要指定“engines”字段,以便使用正確的Node.js版本構(gòu)建DApp及安裝其相關(guān)的依賴項。
Package.json中“engines”字段配置參考鏈接:https://docs.npmjs.com/files/package.json#engines
配置truffle
Truffle創(chuàng)建一些空的配置文件,truffle.js和truffle-config.js。在Windows系統(tǒng)上truffle.js名稱可能會引起沖突,當(dāng)您嘗試運行命令truffle時,Windows嘗試運行truffle.js代替。為了避免這種情況,我們將刪除truffle.js和使用truffle-config.js支持Windows用戶,老實說,他們已經(jīng)受夠了。
$ rm truffle.js
現(xiàn)在我們編輯truffle-config.js,內(nèi)容替換為:
truffle-config.js:truffle配置,讓我們開始
module.exports = {
networks: {
localnode: { // Whatever network our local node connects to
network_id: "*", // Match any network id
host: "localhost",
port: 8545,
}
}
};
上面的配置是一個很好的起點。它設(shè)置一個默認(rèn)的Ethereum網(wǎng)絡(luò)(名為localnode),該網(wǎng)絡(luò)假定您正在運行一個Ethereum客戶機(如parity),要么作為一個完整的節(jié)點,要么作為一個輕量級客戶機。此配置將指示truffle通過端口8545上的RPC與本地節(jié)點通信。Truffle將使用本地節(jié)點連接到的任何Ethereum網(wǎng)絡(luò),比如Ethereum主網(wǎng)絡(luò),或者像Ropsten這樣的測試網(wǎng)絡(luò)。本地節(jié)點也將提供錢包功能。
在接下來的小節(jié)中,我們將為truffle配置其他網(wǎng)絡(luò),例如ganache test-RPC區(qū)塊鏈和托管網(wǎng)絡(luò)提供商Infura。隨著我們添加更多的網(wǎng)絡(luò),配置文件將變得更加復(fù)雜,但它也將為我們的測試和開發(fā)工作流提供更多的選項。
使用truffle部署合約
現(xiàn)在,我們有了一個用于我們的水龍頭項目的基本工作目錄,并配置了truffle和它的依賴項。合約進入我們項目的合約子目錄。該目錄已經(jīng)包含了一個“helper”合約,Migrations.sol為我們管理合約升級。我們將檢查Migrations.sol的使用在后面的部分。
讓我們復(fù)制Faucet.sol合同(從[solid _faucet_example])到contract子目錄,因此項目目錄如下所示:
Faucet
├── contracts
│ ├── Faucet.sol
│ └── Migrations.sol
...
現(xiàn)在我們可以要求truffle為我們編譯合同:
$ truffle compile
Compiling ./contracts/Faucet.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts
Truffle遷移——理解部署腳本
Truffle提供了一個名為migration的部署系統(tǒng)。如果您在其他框架中工作過,您可能會看到類似的東西:Ruby on Rails、Python Django和許多其他語言和框架都有migrate命令。
在所有這些框架中,遷移的目的是處理不同版本的軟件之間的數(shù)據(jù)模式的變化。以太坊的遷移目的略有不同。因為以太坊合約是不可變的,并且成本高昂,因此truffle提供了一種遷移機制來跟蹤哪些合約(以及哪些版本)已經(jīng)被部署。在一個包含數(shù)十個合約和復(fù)雜依賴項的復(fù)雜項目中,您不希望必須花錢重新部署沒有更改的合約。您也不希望手動跟蹤已經(jīng)部署了哪些合約版本。truffle遷移機制通過部署智能合約Migrations.sol完成了這一切,然后跟蹤所有其他合約部署。
我們只有一個合同,F(xiàn)aucet.sol,至少可以說,遷移系統(tǒng)是過度的。不幸的是,我們不得不使用它。但是,通過學(xué)習(xí)如何在一個合約中使用它,我們可以開始為我們的開發(fā)工作流實踐一些好習(xí)慣。隨著事情變得越來越復(fù)雜,這種努力將會得到回報。
Truffle的migrations目錄是找到遷移腳本的地方?,F(xiàn)在,只有一個腳本1_initial_migration。它部署Migrations.sol合約本身:
include::code/Faucet/migrations/1_initial_migration.js
我們需要第二個遷移腳本,以部署Faucet.sol。我們叫它2_deploy_contracts.js。它非常簡單,就像1_initial_migration.js,只有幾個小的改變。事實上,您可以復(fù)制1_initial_migration.js的內(nèi)容。用Faucet替換所有Migrations的實例:
include::code/Faucet/migrations/2_deploy_contracts.js
腳本初始化變量Faucet,標(biāo)識Faucet.sol的Solidity源代碼是定義Faucet的工件。然后,它調(diào)用部署函數(shù)來部署這個合約。
我們都準(zhǔn)備好了。讓我們使用truffle migrate來部署合約。我們必須使用——network參數(shù)來指定部署合約的網(wǎng)絡(luò)。配置文件中只指定了一個網(wǎng)絡(luò),我們將其命名為localnode。確保您的本地Ethereum客戶端正在運行,然后輸入:
Faucet $ truffle migrate --network localnode
因為我們正在使用一個本地節(jié)點連接到Ethereum網(wǎng)絡(luò)并管理我們的錢包,所以我們必須授權(quán)truffle創(chuàng)建的事務(wù)。我正在運行連接到Ropsten測試區(qū)塊鏈的奇偶校驗,因此在truffle遷移期間,我將在奇偶校驗的web控制臺看到一個彈出:

您將看到總共四筆交易。一個用于部署遷移,一個用于將部署計數(shù)器更新為1,一個用于部署Faucet,另一個用于將部署計數(shù)器更新為2。
truffle將顯示遷移完成,顯示每個交易并顯示合同地址:
$ truffle migrate --network localnode
Using network 'localnode'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xfa090db179d023d2abae543b4a21a1479e70ca7d35a469a5d1a98bfc6bd80fe8
Migrations: 0x8861c27715550bed8362c0345add158489df6db0
Saving successful migration to network...
... 0x985c4a32716826ddbe4eae284104bef8bc69e959899f62246a1b27c9dfcd6c03
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Faucet...
... 0xecdbeef77f0558edc689440e34b7bba0a3ba7a45e4b680b071b47c30a930e9d6
Faucet: 0xd01cd8e7bd29e4bff8c1693f59eee46137a9f300
Saving successful migration to network...
... 0x11f376bd7307edddfd40dc4a14c3f7cb84b6c921ac2465602060b67d08f9fd8a
Saving artifacts...
使用truffle控制臺
Truffle提供了一個JavaScript控制臺,我們可以使用它與以太坊網(wǎng)絡(luò)(通過本地節(jié)點)進行交互,與已部署的合同進行交互,并與錢包提供商進行交互。在我們當(dāng)前的配置(localnode)中,節(jié)點和錢包提供程序是我們的本地奇偶校驗客戶端。
讓我們啟動松露控制臺并嘗試一些命令: