近期在區塊鏈的熱潮推動下,我開始研究區塊鏈技術,尤其是智能合約。可編程式的智能合約龍頭老大非以太坊莫屬了,其他的合約平台如 hyperledger,EOS 相對來說沒以太坊成熟,以后陸續在研究。好了,廢話不多說了,開始以太坊私有鏈搭建。
一.geth,mist 客戶端下載
1.這里我給大家介紹下,以太坊客戶端,以太坊客戶端主要分成兩類。一個是后台命令行客戶端,如:geth(go語言),parity(Rust語言),他們是一個與以太坊網絡交互的命令行客戶端。
其余的命令行客戶還有 ethereumjs-lib(javascript),pyethapp(python),ruby-ethereum(ruby) ....主要 geth 使用的比較普遍,這里我就使用geth作為命令行客戶端。
2.mist 是屬於可視化錢包,這么說吧,你在geth 客戶端中生成的用戶,以太坊幣數量可以通過mist 錢包可視化展示。當然mist 不只有這些簡單的功能,最重要的是能部署智能合約,發布,調用。其他還有很多輕錢包,如 lightWallet,metamask...
下面是geth和mist下載地址,這里我使用的是windows系統安裝。
Geth : https://geth.ethereum.org/downloads/ ## 本篇使用1.8.2,免安裝zip
Mist : https://github.com/ethereum/mist/releases ## 本篇使用0.10.0,免安裝zip
二.創建以太坊初始區塊文件 genesis.json
{ "config": { "chainId": 101, "homesteadBlock": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc": {}, "coinbase": "0x0000000000000000000000000000000000000000", "difficulty": "0x400", "extraData": "", "gasLimit": "0xffffffff", "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x00" }
chainId : 以太坊區塊鏈網絡Id,ethereum主鏈是1,私有鏈只用不要與主鏈沖突即可。 alloc : 預留賬戶,如下 "alloc":{ "0x0000000000000000000000000000000000000001":{"balance":"121312321"}, "0x0000000000000000000000000000000000000002":{"balance":"121312321"}, } Coinbase: 曠工賬戶 Difficulty: 挖礦難度,0x400,這個是簡單。 extraData:相當於備注 gasLimit:最小消耗gas nonce : 64位隨機數,用於挖礦,注意他和mixhash的設置需要滿足以太坊黃皮書中的要求 parentHash : 上一個區塊的Hash值,因為是創世塊,石頭里蹦出來的,沒有在它前面的,所以是0 Timestamp : 時間戳
三.初始化區塊節點
geth --datadir data0 init genesis.json
data0 是當前文件夾存儲節點數據,注意:不要使用其他文章介紹的“%cd%\chain”目錄
四.啟動geth客戶端節點
注意:在geth安裝目錄下執行
geth --identity "TestNode1" --datadir "data0" --rpc --rpcapi "db,eth,net,web3" --rpcaddr "127.0.0.1" --rpcport "8486" --port "30304" --networkid "29382" console
使用命令 geth -h 可以查看geth 相關的幫助文檔。這里我說幾個常用的屬性。
--Identity : 節點身份標識,起個名字
--datadir : 指定節點存在位置,“data0”
--rpc : 啟用http-rpc服務器
--rpcapi : 基於http-rpc提供的api接口。eth,net,web3,db...
--rpcaddr : http-rpc服務器接口地址:默認“127.0.0.1”
--rpcport : http-rpc 端口(多節點時,不要重復)
--port : 節點端口號(多節點時,不要重復)
--networkid : 網絡標識符 隨便指定一個id(確保多節點是統一網絡,保持一致)
下圖啟動配置信息說明:
五. geth 常用命令
#創建賬戶
personal.newAccount("123456")
#獲取賬戶數組
eth.accounts
#解鎖賬戶,轉賬時可使用
personal.unlockAccount(eth.accounts[0], "123456")
#節點主賬戶
eth.coinbase
#查看賬戶余額
eth.getBalance(eth.accounts[0])
#啟動,結束挖礦,寫區塊
miner.start(), miner.stop()
下面是運行miner.start() 開始挖礦的運行示意圖。
六.配置多節點服務
單個節點運行太霸道,不能成為中心化,咱們給私有的以太坊網絡在添加一個節點
1.再初始化一個節點
geth --datadir data1 init genesis.json
“data1”作為新節點的存儲目錄,同樣使用 genesis.json作為初始化文件
2. 啟動新節點
geth --identity "TestNode2" --datadir "data1" --rpc --rpcapi "db,eth,net,web3" --rpcaddr "127.0.0.1" --ipcpath "data1\geth\geth.ipc" --rpcport "8487" --port "30305" --networkid "29382" console
3. 給新節點創建一個賬戶,否則無法啟動挖礦
personal.newAccout(“123”)
4.查看:新節點enode信息,使用你本機ip替換[::]
5.重要:主節點添加新節點,使兩節點連上同一個私有鏈上
admin.addpeer("enode://d4f64272de882d2e2ccefc6466c6580ddecd253f5c9d87f977ac3881cbea7b141c07681ea605c53af5815cbfc25b5138b9ddb07be61b757850a55b7197939ba4@192.168.1.175:30304")
這里"enode://......." 填寫你節點 admin.nodeInfo.enode 的信息
6. 如何確保兩節點已連接
首先使用命令admin.nodeInfo,查看結果是否為空[],另外在其中一個節點啟動挖礦命令 miner.start()
如果出現如下圖所示,則兩節點則已經連通
至此我們的節點錢包里有不少eth,可惜是私有鏈上的。下面就用可視化工具mist錢包查看,並使用mist錢包發布合約。
七. 啟動mist錢包
首先默認啟動主節點錢包,若是mist錢包不能打開。用命令啟動, 進入mist錢包目錄,用git Bash 在此啟動。使用windows powershell啟動很卡,沒有安裝git 客戶端的,請先安裝git 客戶端。
啟動mist 你可以看到右上腳有個net-private 說明啟動的是私鏈錢包
2. 打開第二個節點錢包
由於我使用的mist錢包,不能導入第二個節點錢包數據,所以我打算啟動第二個節點的錢包,這里有個大坑!!!
mist.exe --rpc ipc http://127.0.0.1:8545 ## 帶ipc都是錯的,很多網站,包括Ethereum github issue問答區都給出的錯誤要加ipc (注意:這是錯誤的打開方式)
有兩種方式打開多個節點錢包方式
(1)只讀的http 方式打開錢包。不能轉賬,不能部署合約
mist.exe --rpc http://127.0.0.1:8545
(2)以rpc方式打開訪問ipc接口方式打開mist錢包
mist.exe --rpc \\\\.\\pipe\\data1\\geth\\geth.ipc ##這是節點二指定的ipcpath路徑, 可以看下我啟動節點二的配置 --ipcpath
至此,我們可以將第二個節點的錢包打開,進行節點可視化轉賬交易。
八. mist錢包部署合約
下面是寫的簡單的合約案例

pragma solidity ^0.4.18; contract Token { mapping (address => uint) public balancesOf; address public owner; event LogownerWitidras(address addr,uint amount); function Token() public { owner = msg.sender; balancesOf[msg.sender] = 10000; } function transfer(address _to, uint _value) public { if(balancesOf[msg.sender] < _value) revert(); //避免轉移出去的代幣超過當前的存貨 if(balancesOf[_to] + _value < balancesOf[_to]) revert();//避免自己調用自己,或者遞歸調用 balancesOf[msg.sender] -= _value; balancesOf[_to] += _value; } function mint(uint _amount) public { balancesOf[owner] += _amount; } //向當前合約存款 function deposit() payable public returns(address addr, uint amount){ //msg.sender 全局變量,調用合約的發起方 //msg.value 全局變量,調用合約的發起方轉發的貨幣量,以wei為單位。 return (msg.sender, msg.value * 1 ether); } modifier onlyOwner{ if(msg.sender!=owner){ revert(); } _; } function getContractAddrees() public constant returns (address){ return this; } function withdrawFromContract(address _toAddr,uint amount) public onlyOwner{ _toAddr.transfer(amount * 1 ether); emit LogownerWitidras(_toAddr,amount * 1 ether); } //獲取合約賬戶余額 function getContractBalance() public constant returns (uint){ return getContractAddrees().balance; } function getAddressBalance(address addr) public constant returns(uint){ return addr.balance; } }
點擊部署,在礦池中產生一個待開采區塊。啟動miner.start() 挖礦。
待確認完畢,則合約部署完畢。具體的合約調用,我就不在本篇文章贅述了。
好了初步的以太坊客戶端應用搭建完畢,之后還會陸續更新solidity 合約代碼類文章,歡迎小伙伴們繼續關注。
~~~轉載請注明出處~~~
----------------------------------------請關注微信公眾號“刻意鏈習”,持續帶你理解更多的區塊鏈技術------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
更多參考文案
https://learnblockchain.cn/2017/11/29/geth_cmd_options/
https://g2ex.github.io/2017/09/12/ethereum-guidance/
https://medium.com/mercuryprotocol/how-to-create-your-own-private-ethereum-blockchain-dad6af82fc9f
https://souptacular.gitbooks.io/ethereum-tutorials-and-tips-by-hudson/content/private-chain.html