Truffle – 以太坊Solidity程式語言開發框架

NO IMAGE
  1. 構建應用
    原文地址:http://truffleframework.com/docs/getting_started/build

預設構建
Truffle整合了預設的構建來方便使用。但也許不適合每個專案,所以你也許需要其它的來打包你的應用。在3. 構建流程裡檢視更多資訊。預設的構造目標是web應用,但也可以很容易的轉變為其它的構造流程,比如適用於命令列或庫的流程。

特性
預設構建有一些特性來幫助你快速的開始:

在瀏覽器內自動的初始化你的應用,包括引入你編譯的合約,部署的合約資訊,和以太坊客戶端資訊配置。
包含常見的依賴,如web3和Ether Pudding
內建支援ES6和JSX
SASS支援
Uglifyjs支援
配置
你可以隨間的修改預設的構建內容,原始的構建內容目錄如下:

app/
– javascripts/
– app.js
– stylesheets/
– app.css
– images/
– index.html
在1. 配置檔案中的構建配置檔案如下:

{
“build”: {
// Copy ./app/index.html (right hand side) to ./build/index.html (left hand side).
“index.html”: “index.html”,

// Process all files in the array, concatenating them together
// to create a resultant app.js
"app.js": [
"javascripts/app.js"
],
// Process all files in the array, concatenating them together
// to create a resultant app.css
"app.css": [
"stylesheets/app.scss"
],
// Copy over the whole directory to the build destination.
"images/": "images/"

}
}
配置檔案中的配置鍵描述了最終的打包目標名稱,右邊的配置目錄或檔案陣列則是要打包的目錄的內容。打包過程根據檔案擴充套件,將檔案連線形成一個結果檔案,並放到構建的目標位置。如果指定的是一個字串而不是一個陣列,這個字串代指的檔案如果需要會直接拷到對應的構建目錄。如果字串以“/”結尾,則會被識別為一個目錄,整個目錄會不經調整直接拷貝到對應的目錄。所以的指定值都是預設相對於/app目錄來指定的。

你可以在任何時間改變配置和目錄結構。並不強制要求需要javascript和css檔案目錄,所以刪除構建配置檔案中的對應配置就可以了。

特別注意:如果你想預設構建在前端初始化你的應用,務必保證有一個構造目標app.js,因為預設構建會將相關程式碼附加到這個檔案,而不是其它檔案。

命令
要建立你的前端工程,執行:

truffle build
構建結果
構建結果存在./build目錄。所以合約檔案則在對應的位置./build/contracts。

注意事項
預設構建雖簡單易用,但它仍有一些缺點:

當前不支援import,require等。所以不能提供browserify,Webpack和CommonJS這樣的工具。由此讓依賴管理變得有些困難。

這是一套自定義的構建系統,與其它流行構建系統不相容。

它可以擴充套件,但是自定義的方法和API。

預設構建在將來可能會被取代,但在較長時間裡,都將會是預設的以支援之前構建的DAPP.Truffle提供了許多方式來切換到不同的構建流程,可以在3. 構建流程這裡找到更多的例子。

如果任何問題,歡迎留言批評指正。
7. 合約互動
原文地址:http://truffleframework.com/docs/getting_started/contracts

背景
標準的與以太坊網路互動的方法是通過以太坊官方構建的Web3庫。儘管這個庫非常有用,但使用其提供介面與合約互動有些困難,特別是以太坊的新手。為降低學習曲線,Truffle使用Ether Pudding庫,它也是基於Web3的基礎之上,目的是為了讓互動更簡單。

讀寫資料
以太坊網路把在網路上讀與寫資料進行了區分,這個區分對於如何寫程式影響很大。通常來說,寫資料被稱作交易(transaction),讀資料被稱作呼叫(call)。對於交易與呼叫,他們分別有如下特性:

交易(Transaction)
交易本質上改變了整個以太坊網路的資料狀態。一個交易可以是向另一個帳戶傳送ether(以太坊網路代幣)這樣的簡單行為,也可以是執行合約函式,新增一個新合約到以太坊網路這樣的複雜行為。交易的典型特徵是寫入(或修改)資料。交易需要花費ether,也被稱作gas,交易的執行需要時間。當你通過交易執行一個合約的函式時,你並不能立即得到執行結果,因為交易並不是立即執行的。大多婁情況下,通過執行交易不會返回值;它會返回一個交易的ID.總的來說,交易具有如下特徵:

需要gas(Ether)
改變網路的狀態
不會立即執行
不會暴露返回結果(僅有交易ID)
呼叫
呼叫,則與上述的交易非常不同。呼叫可以在網路上執行程式碼,但沒有資料會被改變(也許僅僅是些臨時變數被改變)。呼叫的執行是免費的,典型的行為就是讀取資料。通過呼叫執行一個合約函式,你會立即得到結果。總的來說,呼叫具有如下特徵:

免費(不花費gas)
不改變網路狀態
立即執行
有返回結果。
如果選擇,取決於你想幹什麼,或者說想寫資料,還是讀資料。

介面(abstract)
為了來體驗一下合約介面的作用,我們使用框架自帶的預設metacoin的合約例子。

import “ConvertLib.sol”;

contract MetaCoin {
mapping (address => uint) balances;

event Transfer(address indexed _from, address indexed _to, uint256 _value);
function MetaCoin() {
balances[tx.origin] = 10000;
}
function sendCoin(address receiver, uint amount) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver]  = amount;
Transfer(msg.sender, receiver, amount);
return true;
}
function getBalanceInEth(address addr) returns(uint){
return ConvertLib.convert(getBalance(addr),2);
}
function getBalance(address addr) returns(uint) {
return balances[addr];
}

}
合約有三個方法和一個構造方法。所有三個方法可以被執行為交易或呼叫。

現在我們來看看Truffle和Ether Pudding為我們提供的叫MetaCoin的Javascript物件,可以在前端中使用:

// Print the deployed version of MetaCoin
console.log(MetaCoin.deployed());

// outputs:
//
// Contract
// – address: “0xa9f441a487754e6b27ba044a5a8eb2eec77f6b92”
// – allEvents: ()
// – getBalance: ()
// – getBalanceInEth: ()
// – sendCoin: ()
介面層提供了合約中以應的函式名。它還包含一個地址,指向到MetaCoin合約的部署版本。

執行合約函式
通過這套框架為我們提供的介面,我們可以簡單的在以太坊網路上執行合約函式。

執行交易
在上述例子MetaCoin合約中,我們有三個可以執行的函式。如果你對這三個函式稍加分析就會發現,只有sendCoin會對網路造成更改。sendCoin函式的目標將Meta Coin從一個帳戶傳送到另一些帳戶,這些更改需要被永久存下來。

當呼叫sendCoin,我們將把他們作為一個交易來執行。下面的例子我們來演示下把10個幣,從一個帳戶發到另一個帳戶,改變要永久的儲存在網路上:

var account_one = “0x1234…”; // an address
var account_two = “0xabcd…”; // another address

var meta = MetaCoin.deployed();
meta.sendCoin(account_two, 10, {from: account_one}).then(function(tx_id) {
// If this callback is called, the transaction was successfully processed.
// Note that Ether Pudding takes care of watching the network and triggering
// this callback.
alert(“Transaction successful!”)
}).catch(function(e) {
// There was an error! Handle it.
})
上述程式碼有一些有趣點,我們來了解一下:

我們直接呼叫介面的sendCoin函式。最終是預設以交易的方式來執行的。
交易被成功執行時,回撥函式會直到交易被執行時才真正被觸發。這樣帶來的一個好處是你不用一直去檢查交易的狀態。
我們對sendCoin函式傳遞了第三個引數,需要注意的是原始合約函式的定義中並沒有第三個引數。這裡你看到的是一個特殊的物件,用於編輯一些交易中的指定細節,它可以總是做為第三個引數傳進。這裡,我們設定from的地址為account_one.
執行呼叫
繼續用MetaCoin的例子。其中的getBalance函式就是一個很好的從網路中讀取資料的例子。它壓根不需要進行任何資料上的變更,它只是返回傳入的地址的帳戶餘額,我們來簡單看一下:

var account_one = “0x1234…”; // an address

var meta = MetaCoin.deployed();
meta.getBalance.call(account_one, {from: account_one}).then(function(balance) {
// If this callback is called, the call was successfully executed.
// Note that this returns immediately without any waiting.
// Let’s print the return value.
console.log(balance.toNumber());
}).catch(function(e) {
// There was an error! Handle it.
})
一些有意思的地方如下:

我們必須通過.call()來顯示的向以太坊網路表明,我們並不會持久化一些資料變化。
我們得到了返回結果,而不是一個交易ID。這裡有個需要注意的是,以太坊網網路可以處理非常大的數字,我們被返回了一個BigNumber物件,框架再將這個物件轉化了一個number型別。
警告:我們在上述的例子中將返回值轉成了一個number型別,是因為例子中的返回值比較小,如果將一個BigNumber轉換為比javascript支援的number最大整數都大,你將會出現錯誤或不可預期的行為。

捕捉事件(Catching Events)
你的合約可以觸發事件,你可以進行捕捉以進行更多的控制。事件API與Web3一樣。可以參考Web3 documentation來了解更多。

var meta = MetaCoin.deployed();
var transfers = meta.Transfer({fromBlock: “latest”});
transfers.watch(function(error, result) {
// This will catch all Transfer events, regardless of how they originated.
if (error == null) {
console.log(result.args);
}
}
METHOD:DEPLOYED()
每一個抽象出來的合約介面都有一個deployed()方法,上述例子中,你已經見到過。呼叫這個函式返回一個例項,這個例項代表的是之前部署到網路的合約所對應的抽象介面的例項。

var meta = MetaCoin.deployed();
警告:這僅對使用truffle deploy部署的合約,且一定是在project configuration中配置釋出的才有效。如果不是這樣,這個函式執行時會丟擲異常。

METHOD:AT()
類似於deployed(),你可以通過一個地址來得到一個代表合約的抽象介面例項。當然這個地址一定是這個合約的部署地址。

var meta = MetaCoin.at(“0x1234…”)
警告:當你的地址不正確,或地址對應的合約不正確時,這個函式並不會丟擲異常。但呼叫介面時會報錯。請保證在使用at()時輸入正確的地址。

METHOD:NEW()
你可以通過這個方法來部署一個完全全新的合約到網路中。

MetaCoin.new().then(function(instance) {
// instance is a new instance of the abstraction.
// If this callback is called, the deployment was successful.
console.log(instance.address);
}).catch(function(e) {
// There was an error! Handle it.
});
需要注意的是這是一個交易,會改變網路的狀態。

如果任何問題,歡迎留言批評指正。
8. 測試合約
原文地址:http://truffleframework.com/docs/getting_started/testing

框架
Truffle使用Mocha測試框架來做自動化測試,使用Chai來做斷言。這兩個庫的結合可能讓人耳目一新,我們基於這兩者之上,提供一種方式來編譯簡單和可管理的合約自動化測試用例。

位置
測試檔案應置於./tests目錄。Truffle只會執行以.js,.es,.es6和.jsx結尾的測試檔案,其它的都會被忽略。

測試用例
每個測試檔案至少應該包含至少一個對Mocha的describe()函式的呼叫,詳情見Mochajs Documentation。另一種方式是使用Truffle自定義的contract()函式,作用型別describe()函式,但額外新增了一些特性:

在每一個contract()函式執行前,你的合約都會重部署到以太坊客戶端中,這樣測試用例會在一個乾淨狀態下執行。
contract()函式支援傳入多個可用的帳戶做為第二個引數傳入,你可以用此來進行測試。
當你需要與你寫的合約進行互動時,使用contract(),否則使用describe()函式。

測試用例示例
truffle init命令為我們提供了一個簡單的測試用例例子。它會先部署你的合約,然後執行在it()塊中指定的測試用例。

contract(‘MetaCoin’, function(accounts) {
it(“should put 10000 MetaCoin in the first account”, function() {
// Get a reference to the deployed MetaCoin contract, as a JS object.
var meta = MetaCoin.deployed();

// Get the MetaCoin balance of the first account and assert that it's 10000.
return meta.getBalance.call(accounts[0]).then(function(balance) {
assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account");
});

});
});
需要注意的是在contract()函式的傳入的MetaCoin僅僅因為用來展示,說明它是MetaCoin相關的測試,並無本質作用。

合約
Truffle提供了介面抽象,方便你與合約進行便捷互動。通過var meta = MetaCoin.deployed()這行。Truffle設法保證了,你可以在測試用例,前端,移植(Migration)中都能用這種方式與你自己寫的合約進行互動。可以在7. 合約互動章節瞭解更多。

命令
要執行測試,執行下面的命令:

truffle test
你也可以對單個檔案執行測試:

truffle test ./path/to/test/file.js
注意事項
EthereumJS TestRPC在進行自動化測試時相比其它客戶端會快非常多。而且,TestRPC包含了一些,Truffle可以用來加速測試的特性。作為一個能用流程,我們建議你在開發和測試環節使用TestRPC。當你籌備好要釋出到現上時,才使用Geth或其它官方以太坊客戶端來進行一次測試。

更多
Truffle提供了操作Mocha的配置檔案的入口。參見1. 配置檔案章節來了解更多。

如果任何問題,歡迎留言批評指正。
9. 控制檯
原文:http://truffleframework.com/docs/getting_started/console

背景
有時在進行測試和debug時,或手動執行交易時與合約進行直接互動是需要的。Truffle提供了一種更加簡單的方式,通過互動式控制檯來與你的那些準備好的合約進行互動。

命令
啟動控制檯,使用:

truffle console
這會使用預設網路來調起一個控制檯,會自動連線到一個執行中的以太坊客戶端。你可以使用選項–network來修改這個特性,更多細節參見2. 網路與APP部署和4. Truffle命令指南。

當你載入了控制檯,你會看到下面的輸出:

$ truffle console
truffle(default)>
default的意思是說,你當前連線到的是預設網路。

特性
控制檯支援Truffle命令列支援的命令,比如,你可以在控制檯中執行migrate –reset,其效果與在命令列中執行truffle migrate –reset的效果一致。Truffle的控制檯額外增加如下特性:

所有已經編譯的合約都可用。就像在開發測試,前端程式碼中,或者移植程式碼中那樣使用。
在每個命令後,你的合約會被重新載入。如使用migrate –reset命令後,你可以立即使用新分配的地址和二進位制。
web3庫也可以使用,且也連到你了的以太坊客戶端。
所有命令返回的promise,會自動解析,直接列印出結果,你可以不用輸入then(),簡化了命令。如下:
truffle(default)> MyContract.deployed().getValue.call(); //
5
如果任何問題,歡迎留言批評指正。
10. 外部指令碼
原文:http://truffleframework.com/docs/getting_started/scripts

背景
你也許會經常的執行外部指令碼來與你的合約進行互動。Truffle提供了一個簡單的方式來進行這個。首先,啟動你的合約,連上你想要的網路,通過1. 配置檔案

命令
要執行外部(external)指令碼,執行下述命令:

$ truffle exec