搭建一個私有區塊鏈環境

最近在研究區塊鏈。打算先搭建一個測試環境開始運行。這裏記錄整個搭建過程,供後來人參考。 整體上,分爲三個步驟,安裝相關軟件,初始化系統,建立集羣,以及最後一步,挖礦。 我們採用的是以太坊,相對其他區塊鏈,這是一個成熟的環境。 雖然近期有硬分支的事件,對企業應用來說,功能上還算是比較完善的。

安裝部署

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 [::]:30303Welcome 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

配置第二臺私鏈服務器

第二臺私鏈服務器,需要把第一臺的步驟基本都要重複一遍。兩臺服務器配置一樣纔可以通訊。 需要改變的地方是:

  1. 第三步創建genesis.json的時候,完全使用第一臺服務器的配置,不要用新建的account來創建。

  2. 需要將第一臺服務器添加到靜態節點列表中。

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章