最近在研究區塊鏈。打算先搭建一個測試環境開始運行。這裏記錄整個搭建過程,供後來人參考。 整體上,分爲三個步驟,安裝相關軟件,初始化系統,建立集羣,以及最後一步,挖礦。 我們採用的是以太坊,相對其他區塊鏈,這是一個成熟的環境。 雖然近期有硬分支的事件,對企業應用來說,功能上還算是比較完善的。
安裝部署
1.安裝 Go 環境
如果機器無法上外網,還得配置一下代理。 Ubuntu配置代理的方式網上很多,這裏不介紹。
curl -O https://storage.googleapis.com/golang/go1.5.1.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.5.1.linux-amd64.tar.gz
mkdir -p ~/go; echo "export GOPATH=$HOME/go" >> ~/.bashrc
echo "export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
2.安裝 ethereum
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum
在執行 sudo add-apt-repository -y ppa:ethereum/ethereum
的時候碰到這個問題:
root@ubuntu-KVM:~# sudo add-apt-repository -y ppa:ethereum/ethereum
Cannot add PPA: 'ppa:ethereum/ethereum'.
Please check that the PPA name or format is correct.
按照Ask Ubuntu 的意見,修改爲:
sudo apt-get install software-properties-common
sudo -E add-apt-repository -y ppa:ethereum/ethereum
sudo -E add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum
3.安裝 solc 編譯器
sudo add-apt-repository ppa:ethereum/ethereum-qt
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install cpp-ethereum
同樣的,如果碰到PPA Name錯誤的警示,則執行如下操作:
sudo -E add-apt-repository ppa:ethereum/ethereum-qt
sudo -E add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install cpp-ethereum
這樣相關軟件已經安裝完畢。
搭建私鏈
1.啓動geth服務
geth --datadir "/root/chain" console
其中 datadir用於指定數據目錄。這個目錄不能夠預先創建,否則命令會失敗。 執行結果如下:
2.創建賬號
執行之後,進入geth
的交互模式。 接着建立一個賬號,然後退出。 這個賬號用於執行創世操作。 然後exit
退出
> personal.newAccount("密碼");
"0xea5c99831c2e4a0e094facdbac1befcf6c92e543"
> exit
3.創建創世區塊
編譯創建創世區塊所需要的腳本, 注意alloc下的key需要和上述的賬號保持一致。
{
"alloc": {
"0xea5c99831c2e4a0e094facdbac1befcf6c92e543": {
"balance": "1000"
}
},
"nonce": "0x0000000000000042",
"difficulty": "0x020000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "CNNMoney Jack Ma interview: Wars start when trade stops, 20160902",
"gasLimit": "0xffffffff"
}
各個參數的含義如下:
mixhash:與nonce配合用於挖礦,由上一個區塊的一部分生成的hash。注意他和nonce的設置需要滿足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。.
nonce: nonce就是一個64位隨機數,用於挖礦,注意他和mixhash的設置需要滿足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章節所描述的條件。
difficulty: 設置當前區塊的難度,如果難度過大,cpu挖礦就很難,這裏設置較小難度
alloc: 用來預置賬號以及賬號的以太幣數量,因爲私有鏈挖礦比較容易,所以我們不需要預置有幣的賬號,需要的時候自己創建即可以。
coinbase: 礦工的賬號,隨便填
timestamp: 設置創世塊的時間戳
parentHash: 上一個區塊的hash值,因爲是創世塊,所以這個值是0
extraData: 附加信息,隨便填,可以填你的個性信息
gasLimit: 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,因爲我們是私有鏈,所以填最大。
創建數據存放地址並初始化創世塊
geth --datadir "/root/chain" init genesis.json
4.啓動私鏈
執行如下腳本
geth --identity "phoenix" --rpc --rpccorsdomain "*" --datadir "/root/chain" --port "30303" --rpcapi "db,eth,net,web3" --networkid 98888 console
各參數說明如下:
identity :區塊鏈的標示,隨便填寫,用於標示目前網絡的名字
init :指定創世塊文件的位置,並創建初始塊
datadir :設置當前區塊鏈網絡數據存放的位置
port:網絡監聽端口,默認是8080
rpc:啓動rpc通信,可以進行智能合約的部署和調試。它在geth中通常被默認激活。
rpcapi: 設置允許連接的rpc的客戶端,一般爲db,eth,net,web3
networkid: 設置當前區塊鏈的網絡ID,用於區分不同的網絡,是一個數字
console:啓動命令行模式,可以在Geth中執行命令
此外,還可以使用如下參數:
nodiscover : 使用這個命令可以確保你的節點不會被非手動添加你的人發現。否則,你的節點可能被陌生人的區塊鏈無意添加,如果他和你有相同的初始文件和網絡ID。
maxpeers : 如果你不希望其他人連接到你的測試鏈,可以使用maxpeers 0。反之,如果你確切知道希望多少人連接到你的節點,你也可以通過調整數字來實現。
rpcapi : 這個命令可以決定允許什麼API通過RPC進入。在默認情況下,geth可以在RPC激活web3界面。請注意在RPC/IPC界面提供API,會使每個可以進入這個界面(例如dapp’s)的人都有權限訪問這個API。注意你激活的是哪個API。Geth會默認激活IPC界面上所有的API,以及RPC界面上的db,eth,net和web3 API。
rpccorsdomain : 這個可以指示什麼URL能連接到你的節點來執行RPC定製端任務。務必謹慎,輸入一個特定的URL而不是wildcard ( * ),後者會使所有的URL都能連接到你的RPC實例。
啓動後界面如下,光標停留在最後的命令行上,可以執行以太坊命令。 可以看到Listening on [::]:30303
和Welcome to the Geth JavaScript console!
的提示,說明已經啓動成功
注意:如果想將Ubuntu作爲永久區塊鏈節點使用,當使用
nohup
命令時,Geth啓動參數console
必須去掉,否則Geth會自動停止。
5.查看節點信息
常用命令:
- net.listening:查看網絡是否在監聽;
- admin.peers: 查看當前連接的節點。 目前還是空的。
- admin.nodeInfo:查看當前節點的信息。
執行:
> admin.nodeInfo
得到當前節點信息如下:
{
enode: "enode://dfd047d64a3d8c9d9c2834bc8c3bbf41a79e6797956fa99469b872d97a7978e4e7a6d9605ec6e77164515f6f09d979999ca3ef91eebcd2a6c91ebdfe167de094@[::]:30303",
id: "dfd047d64a3d8c9d9c2834bc8c3bbf41a79e6797956fa99469b872d97a7978e4e7a6d9605ec6e77164515f6f09d979999ca3ef91eebcd2a6c91ebdfe167de094",
ip: "::",
listenAddr: "[::]:30303",
name: "Geth/v1.5.0-unstable/linux/go1.5.1/phoenix",
ports: {
discovery: 30303,
listener: 30303
},
protocols: {
eth: {
difficulty: 131072,
genesis: "0xaab381212b8108c488c8d21c06042a9081b94bfb87665110520d3c295626e79b",
head: "0xaab381212b8108c488c8d21c06042a9081b94bfb87665110520d3c295626e79b",
network: 98888
}
}
}
注意enode節點,這是當前節點的標識。 後續會用到這個值。
6.查看賬戶信息
在創建創世節點時,我們創建了個默認賬戶。可以通過如下命令查看賬戶餘額。
> eth.accounts
["0x4b691e86c622127ed8e1d49899ad8c1d19834327"]
> primary=eth.accounts[0]
"0x4b691e86c622127ed8e1d49899ad8c1d19834327"
> balance = web3.fromWei(eth.getBalance(primary), "ether");
20
配置第二臺私鏈服務器
第二臺私鏈服務器,需要把第一臺的步驟基本都要重複一遍。兩臺服務器配置一樣纔可以通訊。 需要改變的地方是:
第三步創建genesis.json的時候,完全使用第一臺服務器的配置,不要用新建的account來創建。
需要將第一臺服務器添加到靜態節點列表中。
7.添加靜態節點列表
在{datadir}下添加文件 static-nodes.json,內容如下:
[
"enode://dfd047d64a3d8c9d9c2834bc8c3bbf41a79e6797956fa99469b872d97a7978e4e7a6d9605ec6e77164515f6f09d979999ca3ef91eebcd2a6c91ebdfe167de094@第一個節點的IP地址:30303"
]
執行如下腳本啓動節點:
geth --identity "phoenix" --rpc --rpccorsdomain "*" --datadir "/root/chain" --port "30303" --rpcapi "db,eth,net,web3" --networkid 98888 console
啓動成功後,查看當前連接的節點:
> admin.peers
[{
caps: ["eth/62", "eth/63"],
id: "dfd047d64a3d8c9d9c2834bc8c3bbf41a79e6797956fa99469b872d97a7978e4e7a6d9605ec6e77164515f6f09d979999ca3ef91eebcd2a6c91ebdfe167de094",
name: "Geth/v1.5.0-unstable/linux/go1.5.1/phoenix",
network: {
localAddress: "10.15.244.204:56808",
remoteAddress: "10.15.244.203:30303"
},
protocols: {
eth: {
difficulty: 131072,
head: "0xaab381212b8108c488c8d21c06042a9081b94bfb87665110520d3c295626e79b",
version: 63
}
}
}]
挖礦
激動人心的時刻到了。 作爲一個僞金融圈人士,最大的夢想,古時候叫擁有一個聚寶盆,現在叫擁有一個印鈔權,在數字貨幣時代,叫擁有一個挖礦機。 自己搭建的區塊鏈,想怎麼挖就怎麼挖吧。
私鏈啓動起來之後,挖礦其實很簡單了。 首先必須保證的有一個賬號:
> eth.accounts
["0x1b39aa2446de648dd6928a759c542690cc32757b"]
> eth.getBalance(eth.accounts[0]).toNumber();
0
賬號裏沒錢。 那就開始挖吧。挖礦其實很簡單,一個命令就開始了。默認的,挖到的錢,都放在當前賬號中。如果有多個賬號,默認的放到第一個賬號中。 在geth環境下,運行:
> miner.start();
或者運行命令行:
geth --mine --minerthreads=4
minerthreads用來指定運行的線程數。默認爲當前CPU的核數。 如果有多個賬號,可以指定挖礦收入放到第幾個賬號,注意編號是從0開始的:
miner.setEtherbase(eth.accounts[0])
或者命令行執行:
geth --etherbase 0 --mine 2>> geth.log // 0 is index: first account by creation order OR
geth --etherbase '0x1b39aa2446de648dd6928a759c542690cc32757b' --mine 2>> geth.log
半小時後,查看下賬戶餘額:
> eth.getBalance(eth.accounts[0]).toNumber();
1.5971875e+21