以太坊本地私有鏈開發環境搭建!透過本文所述方法和專案中的指令碼,我們可以快速的搭建好自己的私鏈進行開發測試。
倉庫中包含的工具有:
一個測試賬戶匯入指令碼,在首次部署時將五個測試賬戶私鑰匯入以太坊節點。
一個genesis.json配置檔案,為對應的五個測試賬戶提供初始資金(以太幣),方便開發測試。
一個快速啟動私有鏈節點並進入互動模式的指令碼。
一個合約樣例:contracts/Token.sol。這是一個使用合約語言Solidity編寫的智慧合約。Token合約的功能是發行一種token(可以理解為貨幣,積分等等),只有合約的建立者有發行權,token的擁有者有使用權,並且可以自由轉賬。
測試賬戶私鑰是放在Github上的公開資料,千萬不要用於正式環境中或者公有鏈上。如果在測試環境之外的地方使用這些私鑰,你的資金將會被竊取!
準備
在本地安裝好go-ethereum和solc, 可以執行geth和solc命令。如果作業系統是ubuntu, 安裝官方的ethereum安裝包即可。
將本倉庫透過git clone命令下載到本地。
安裝expect,工具指令碼用它來自動化一些過程。例如在ubuntu上: sudo apt-get install expect
啟動geth
進入本倉庫目錄: cd ethereum-bootstrap
匯入測試賬戶私鑰: ./bin/import_keys.sh
啟動私有鏈節點: ./bin/private_Blockchain.sh. 啟動成功後可以看到類似如下輸出:
此時以太坊互動式控制檯已經啟動,我們可以開始測試和開發了。
注意:工具指令碼假設你的geth安裝在預設位置, 可以直接透過geth執行。如果geth命令安裝在非標準的位置,可以設定GETH環境變數指定geth可執行檔案的路徑。例如:
GETH=/some/weird/dir/geth ./bin/import_keys.sh
使用以太坊控制檯編譯和部署智慧合約
在contracts目錄下有一個智慧合約樣例檔案Token.sol, 透過Solidity語言實現了基本的代幣功能, 合約持有者可以發行代幣, 使用者可以互相轉賬.
我們可以使用以太坊控制檯來編譯部署這個合約.以太坊控制檯是最基本的工具,使用會比較繁瑣.社羣也提供了其他更加方便的部署工具,此處不做討論.
第一步,我們先把合約程式碼壓縮為一行.新建一個ssh session, 切換到geth使用者環境su - geth, 然後輸入:cat contracts/Token.sol | tr '\n' ' '.
切換到以太坊控制檯,把合約程式碼儲存為一個變數:
var tokenSource = 'contract Token { address issuer; mapping (address => uint) balances; event Issue(address account, uint amount); event Transfer(address from, address to, uint amount); function Token() { issuer = msg.sender; } function issue(address account, uint amount) { if (msg.sender != issuer) throw; balances[account] += amount; } function transfer(address to, uint amount) { if (balances[msg.sender] < amount) throw; balances[msg.sender] -= amount; balances[to] += amount; Transfer(msg.sender, to, amount); } function getBalance(address account) constant returns (uint) { return balances[account]; } }';
然後編譯合約程式碼:
var tokenCompiled = web3.eth.compile.solidity(tokenSource);
透過tokenCompiled.Token.code可以看到編譯好的二進位制程式碼,透過tokenCompiled.Token.info.abiDefinition可以看到合約的ABI.
接下來我們要把編譯好的合約部署到網路上去.
首先我們用ABI來建立一個javascript環境中的合約物件:
var contract = web3.eth.contract(tokenCompiled.Token.info.abiDefinition);
我們透過合約物件來部署合約:
var initializer = {from: web3.eth.accounts[0], data: tokenCompiled.Token.code, gas: 300000};
var callback = function(e, contract){
if(!e) {
if(!contract.address) {
console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined!");
console.log(contract);
}
}
};
var token = contract.new(initializer, callback);
contract.new方法的第一個引數設定了這個新合約的建立者地址from, 這個新合約的程式碼data, 和用於建立新合約的費用gas.gas是一個估計值,只要比所需要的gas多就可以,合約建立完成後剩下的gas會退還給合約建立者.
contract.new方法的第二個引數設定了一個回撥函式,可以告訴我們部署是否成功.
contract.new執行時會提示輸入錢包密碼.執行成功後,我們的合約Token就已經廣播到網路上了.此時只要等待礦工把我們的合約打包儲存到以太坊區塊鏈上,部署就完成了.
在公有鏈上,礦工打包平均需要15秒,在私有鏈上,我們需要自己來做這件事情.首先開啟挖礦:
miner.start(1)
此時需要等待一段時間,以太坊節點會生成挖礦必須的資料,這些資料都會放到記憶體裡面.在資料生成好之後,挖礦就會開始,稍後就能在控制檯輸出中看到類似:
:hammer:Mined block
的資訊,這說明挖到了一個塊,合約已經部署到以太坊網路上了!此時我們可以把挖礦關閉:
miner.stop(1)
接下來我們就可以呼叫合約了.先透過token.address獲得合約部署到的地址, 以後新建合約物件時可以使用.這裡我們直接使用原來的contract物件:
// 本地錢包的第一個地址所持有的token數量
> token.getBalance(web3.eth.accounts[0])
0
// 發行100個token給本地錢包的第一個地址
> token.issue.sendTransaction(web3.eth.accounts[0], 100. {from: web3.eth.accounts[0]});
I1221 11:48:30.512296 11155 xeth.go:1055] Tx(0xc0712460a826bfea67d58a30f584e4bebdbb6138e7e6bc1dbd6880d2fce3a8ef) to: 0x37dc85ae239ec39556ae7cc35a129698152afe3c
"0xc0712460a826bfea67d58a30f584e4bebdbb6138e7e6bc1dbd6880d2fce3a8ef"
// 發行token是一個transaction, 因此需要挖礦使之生效
> miner.start(1)
:hammer:Mined block
> miner.stop(1)
// 再次查詢本地錢包第一個地址的token數量
> token.getBalance(web3.eth.accounts[0])
100
// 從第一個地址轉30個token給本地錢包的第二個地址
> token.transfer.sendTransaction(web3.eth.accounts[1], 30. {from: web3.eth.accounts[0]})
I1221 11:53:31.852541 11155 xeth.go:1055] Tx(0x1d209cef921dea5592d8604ac0da680348987b131235943e372f8df35fd43d1b) to: 0x37dc85ae239ec39556ae7cc35a129698152afe3c
"0x1d209cef921dea5592d8604ac0da680348987b131235943e372f8df35fd43d1b"
> miner.start(1)
> miner.stop(2)
> token.getBalance(web3.eth.accounts[0])
70
> token.getBalance(web3.eth.accounts[1])
30
其他
私有鏈的所有資料都會放在倉庫根目錄下的data目錄中,刪除這個目錄可以清除所有資料,重新啟動新環境。
做完這些之後你應該對在以太坊私有鏈上進行開發有了一個大概的瞭解吧,如果還想學習更多知識,一可以看一看上面執行的指令碼程式碼,到底幹了些什麼,用了哪些命令列引數,二可以閱讀正在ethfans上更新的solidity文件中文版。