第一行代碼:以太坊(1)-建立本身的私有區塊鏈

本文會利用以太坊客戶端(geth)搭建一個私有區塊鏈,並在這個私有區塊鏈上挖礦,經過本文的案例,讀者能夠更深刻理解區塊鏈、以太坊、挖礦的理論。css

經過閱讀本文,您能夠:linux

  • 掌握搭建以太坊開發環境的方法
  • 掌握geth的基本使用方法
  • 瞭解如何啓動JavaScript控制檯
  • 掌握創建一個私有區塊鏈的步驟
  • 掌握如何在私有區塊鏈上挖礦

1. 以太坊(Ethereum)開發環境搭建

在玩以太坊以前,首先要搭建以太坊的開發環境。第一步就是安裝geth。那麼geth是什麼呢?geth(或稱爲go-ethereum)是以太坊節點的一個實現。也就是說,geth是一個客戶端,用於鏈接以太坊網絡。從geth的名 字能夠看出,geth是用go語言實現的一個以太坊節點。那麼爲何須要這個節點呢?android

這是由於以太坊網絡由多個節點組成,這些節點多是用不一樣技術實現的。如geth就是官方的以太坊節點。經過這些節點能夠用命令行方式直接訪問區塊鏈網絡,如廣播交易,發佈智能合約等,但對於大多數用戶來講,都是非程序員出身,讓他們經過命令行方式去操做以太坊網絡是不可能的,因此就要求有圖形化的操做界面來操做以太坊網絡。但geth這樣的節點是作不到的,所以,就須要像web3.js,web3.py這樣的程序庫,再配合JavaScript、Python實現可視化的以太坊客戶端,但這些庫是沒法直接鏈接進以太坊網絡的,他們只能鏈接像geth這樣的以太坊節點,而後經過一塔發節點訪問以太坊網絡,因此geth其實同時起到客戶端和服務端的做用。也就是說,geth是以太坊網絡的客戶端,是web3.js的服務端。nginx

安裝geth也很是容易,能夠直接到下面的官網下載不一樣平臺的geth安裝程序。git

https://ethereum.github.io/go-ethereum/downloads程序員

訪問上面的Url,會看到頁面上面顯示以下圖所示的下載按鈕。github

image.png

目前geth的最新版本是1.8.3,支持Linux、Mac OS X和Windows平臺,讀者能夠根據實際狀況下載相應平臺的geth安裝程序,也能夠直接下載源代碼(最後一個按鈕),而後編譯和安裝geth,不過這種方式只適合於專業人員,對於初學者,並不推薦使用這種方式。web

(1)安裝Windows版geth

Windows版安裝程序是一個exe文件(geth-windows-amd64-1.8.3-329ac18e.exe或相似的文件名),直接雙擊安裝便可。雙擊該文件會顯示以下圖所示的安裝界面。apache

image.png

單擊「I Agree」按鈕會顯示以下圖所示的選擇組件界面。json

image.png

建議讀者將Geth和Development tools都選上,不然在用到相關工具時還須要安裝。而後單擊「Next」按鈕進入下一個安裝界面。該界面主要用於指定geth的安裝目錄,默認安裝目錄是「C:\Program Files\Geth」,若是讀者不想將geth安裝到這個目錄,能夠修改爲其餘目錄,如「D:\geth」效果以下圖所示。

image.png

接下來單擊「Install」按鈕開始安裝geth。安裝的過程會顯示當前安裝進度的百分比,直到最後顯示「Completed」,表示已經安裝成功,以下圖所示。最後單擊「Close」按鈕關閉安裝界面。

image.png

Windows版的geth其實就是一些exe文件,以下圖所示。其中geth.exe是本書主要使用的工具。

image.png

安裝完geth後,最好將geth.exe文件所在的目錄加到PATH環境變量中,這樣在任何目錄下就均可以使用geth.exe文件。

(2)安裝Mac OS X版geth

Mac OS X版安裝程序是一個壓縮文件(geth-darwin-amd64-1.8.3-329ac18e.tar.gz或相似的名字),將該壓縮文件解壓,會發現只有一個geth可執行文件,以下圖所示。

image.png

若是要想下載Mac OS X版的geth相關工具,能夠到圖2-1所示頁面下方選擇相應的操做系統,下載Tools壓縮包或安裝程序(點擊Geth&Tools 1.8.3便可下載相應操做系統的Tools),以下圖所示。爲了使用方便,能夠將geth所在的路徑加到/etc/profile文件的PATH變量中,而後執行source /etc/profile命令,讓配置當即生效。這樣在任何目錄下均可以使用geth。

image.png

在Mac OS X下還可使用brew命令安裝以太坊開發環境。

brew tap ethereum/ethereum brew install ethereum 

讀者能夠選擇本身喜歡的方式在Mac OS X下安裝以太坊開發環境。

(3)安裝Linux版geth

Linux版的geth與Mac OS X版的geth差很少,安裝程序一樣是一個壓縮文件(geth-linux-amd64-1.8.3-329ac18e.tar.gz或相似的文件名),將該壓縮文件複製到Linux的某個目錄,而後在Console中進入該目錄,執行以下的命令對該文件解壓。

tar zxvf geth-linux-amd64-1.8.3-329ac18e.tar.gz

解壓後,仍然只有一個geth可執行文件,這個可執行文件是靜態編譯的,在任何Linux發行版上均可以獨立執行。

在Linux下安裝完geth後,最好將geth文件所在的路徑添加到PATH變量中,設置的方法與Mac OS X相似。

2. 使用geth命令建立以太坊帳戶

安裝完geth,須要測試一下,能夠在控制檯輸入geth version命令(用於查看geth的版本信息),若是輸出相似下圖所示的信息,表示geth已經安裝成功。

image.png

在Windows下執行geth version命令,也會獲得與圖2-9相似的版本信息,只是部分信息稍有差別,以下圖所示。

image.png

使用geth的第一步就是建立帳戶。以太坊的帳戶用40位十六進制的地址表示,以下面的十六進制數就是一個標準的以太坊帳戶地址(前面的0x表示十六進制)。

0x24924f33a9c49d312a8d885ade76ece76b315982

第一次使用geth時,geth中沒有任何帳戶,因此首先須要使用geth命令建立以太坊帳戶。在建立以太坊帳戶以前,可使用下面的命令查看以太坊當前的帳戶。

geth account list

執行上面的命令,會顯示以下圖所示的信息,很明顯,沒有任何帳戶。

image.png

如今使用geth account new命令建立以太坊帳戶,在建立的過程當中要求輸入帳戶的密碼。若是最後輸出了一個以太坊地址,就說明帳戶建立成功了,以下圖所示。該地址就是以太坊帳戶。

image.png

可使用一樣的方法多建立幾個以太坊帳戶。而後使用geth account list命令查看以太坊當前的帳戶,會獲得以下圖所示的查詢結果。根據查詢結果顯示,以太坊當前有3個帳戶。

image.png

3. 刪除以太坊帳戶

geth並無直接提供刪除以太坊帳戶的命令,不過能夠經過刪除帳戶本地文件的方式刪除以太坊帳戶(由於每個以太坊帳戶對應一個文件)。根據上圖所示的以太坊帳戶信息,能夠得知帳戶文件的存儲路徑以下:

/Users/lining/Library/Ethereum/keystore

進入該目錄,會看到以下圖所示的3個文件,分別對應上一節創建的3個以太坊帳戶。若是要刪除某個以太坊帳戶,只須要刪除對應的文件便可,而後再次執行geth account
list命令,會發現與文件對應的以太坊帳戶消失了。

image.png

在Windows中的操做與Mac OS X相同,只是保存帳戶文件的路徑不一樣。在Windows下使用一樣的方式建立3個以太坊帳戶,而後使用geth account list命令列出全部的帳戶,以下圖所示。

image.png

從上圖所示的帳戶信息可知,保存帳戶文件的路徑以下:

C:\Users\androidguy\AppData\Roaming\Ethereum\keystore

其中androidguy是Windows用戶名,請將其改爲本身機器的用戶名。

4. geth JavaScript控制檯

geth能夠經過JavaScript控制檯和JavaScript代碼訪問以太坊網絡。只須要執行geth console命令,就能夠啓動JavaScript控制檯,在該控制檯能夠直接輸入JavaScript代碼,按Enter鍵會執行輸入的JavaScript代碼,不過有一個問題,就是geth命令同時也負責同步區塊,以及其餘工做,這樣會產生大量的日誌信息,這些日誌信息會與JavaScript代碼交替出現,很是煩人。效果以下圖所示。

image.png

爲了避免讓日誌信息在JavaScript控制檯輸出,可使用下面的命令啓動JavaScript控制檯,其中2表示日誌管道,也就是將日誌信息直接輸出到geth.log文件。

geth console 2>>geth.log

執行上面的命令,會進入JavaScript控制檯,在控制檯中,除了輸入的JavaScript代碼和執行結果外,什麼都不會輸出,效果以下圖所示。

image.png

在Windows下使用一樣的操做會獲得與Mac OS X下徹底同樣的效果,以下圖所示。

image.png

JavaScript控制檯並非簡簡單單用來執行JavaScript代碼的,其實這個控制檯能夠經過web3.js API直接訪問以太坊網絡。web3.js就是一套API,支持Web和Node.js。可能不少讀者看到這些估計有些懵,一下拋出這麼多概念,又是web3.js,又是Node.js。這些技術會在本書後面詳細介紹,本節只要知道在JavaScript控制檯可使用JavaScript代碼訪問以太坊網絡就能夠了。若是使用geth console命令進入JavaScript控制檯,並不須要單獨安裝web3.js,直接就可使用web3.js的API。

在JavaScript控制檯中內置了不少JavaScript對象,其中web3就是其中最重要的對象。當啓動JavaScript控制檯後,這些對象會自動建立,能夠直接使用。例如,能夠直接在JavaScript控制檯中執行下面的JavaScript代碼。

str = web3.fromAscii('ethereum') // 將'ethereum'按ASCII轉換爲十六進制數 web3.toDecimal('0xa') // 將十六進制數(0xa)轉換爲十進制數 // 判斷地址是否有效 isAddress = web3.isAddress("0x8888f1f195afa192cfee860698584c030f4c9db1");

這些命令執行的效果以下圖所示。在Windows中的JavaScript控制檯也會獲得徹底相同的效果。

image.png

使用web3.js API的方式有不少,除了在JavaScript控制檯中使用web3.js API外,至少還能夠在下面的環境中使用web3.js。

• 瀏覽器

• Node.js

• IPython

• Jupyter Notebook

5. 創建私有區塊鏈與挖礦

本節會利用geth命令建立一個私有區塊鏈,而後本身挖礦,能夠經過這個操做過程更深刻理解以太坊和區塊鏈的概念。

建立私有區塊鏈的步驟以下:

(1)創建創世塊

區塊鏈是由若干個區塊組成的。在私有鏈啓動後,須要爲區塊鏈建立第一個區塊(創世塊),至關於數據結構中鏈表的頭節點。不過以太坊並不知道如何建立這個創世塊,須要咱們告訴以太坊如何建立,所以,首先須要創建一個創世塊的描述文件,這個描述文件是JSON格式的,本例起名爲block.json,代碼以下:

block.json文件

文件位置:src/chapter2/block.json

{
    "config": { "chainId":15, "homesteadBlock":0 }, "difficulty":"20", "gasLimit":"2100000", "alloc":{ "7df9a875a174b3bc565e6424a0050ebc1b2d1d82":{"balance":"300000"}, "f41c74c9ae680c1aa78f42e5647a62f353b7bdde":{"balance":"400000"} } }

一個完整的區塊描述文件很是複雜,本例只對區塊進行了一些基本設置,這些設置項的描述以下:

• chainId:指定了獨立的區塊鏈網絡 ID。網絡 ID
在鏈接到其餘節點的時候會用到,以太坊公網的網絡 ID 是 1,爲了避免與公有鏈網絡衝突,運行私有鏈節點的時候要指定本身的網絡 ID。不一樣 ID 網絡的節點沒法相互鏈接。

• homesteadBlock:以太坊推出的第2個主要的區塊發行版本,Frontier是第1個推出的區塊發行版本(也是測試版本)。建議使用homesteadBlock,這裏的0表示有效。

• difficulty:挖礦的難易程度,該值越小,挖礦越容易。也就是說,該值越小,挖礦須要的算力越小,在測試時,建議設置一個比較小的值,不然挖礦會須要很長時間。

• gasLimit:挖每一個區塊須要消耗資源的上限,gas與以太幣(ether)同樣,都是以太坊中的單位。之因此將gas與ether分開,是爲了防止ether的波動對挖每一個區塊消耗資源的影響。

• alloc:爲了測試挖礦,臨時分配的帳戶,其中balance表示當前帳戶的餘額,單位是Wei。

(2)初始化區塊鏈

這一步須要使用以下的命令對區塊鏈進行初始化。

geth init block.json --datadir test

其中test表示與區塊鏈相關數據保存的目錄,本例test與block.json文件在同一個目錄下。執行上面的命令後,會在當前block.json文件所在的目錄生成一個test子目錄。test子目錄的結構以下圖所示。

image.png

很明顯,在test目錄下面還有兩個子目錄:geth和keystore。其中geth目錄保存了同步區塊鏈以及相關的數據,keystore目錄保存了帳戶文件。因爲私有鏈剛建立,尚未建立帳戶,因此keystore目錄爲空。
若是在Windows下執行前面初始化區塊鏈的命令,會獲得與Mac OS X下徹底同樣的結果。讀者能夠本身在Windows作實驗。

(3)啓動以太坊客戶端(geth)

在這一步使用下面的命令啓動以太坊客戶端(進入JavaScript控制檯)。其中datadir命令行參數表示geth會使用test目錄保存相關文件。

geth --datadir test console

(4) 將帳戶與礦工綁定

負責挖礦的帳戶稱爲礦工。miner是JavaScript控制檯中內置的礦工對象,在Java可使用下面的命令將block.json文件中的兩個地址中的一個與miner對象綁定。

miner.setEtherbase("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") 

(5)開始挖礦

在開始挖礦以前,可使用下面的命令查一下兩個臨時帳號的餘額。

eth.getBalance("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") eth.getBalance("0xf41c74c9ae680c1aa78f42e5647a62f353b7bdde") 

查詢結果分別是300000和400000。如今礦工(miner)已經和餘額爲300000的帳戶綁定,接下來在JavaScript控制檯執行以下的代碼開始挖礦。

miner.start()

執行這行代碼後,就會開始挖礦,若是要中止挖礦,須要在JavaScript控制檯執行以下的代碼。

miner.stop()

中止挖礦後,能夠執行下面的代碼查詢當前區塊鏈中的區塊數,其中eth是JavaScript控制檯內建的對象。在本例中一共挖了36個區塊,也就是目前在網絡中有一條由36個區塊組成的區塊鏈。

eth.blockNumber

再次使用下面的代碼查詢兩個臨時帳戶的餘額。

eth.getBalance("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") eth.getBalance("0xf41c74c9ae680c1aa78f42e5647a62f353b7bdde")

咱們會發現與礦工(miner)綁定的帳戶的餘額變多了,多出的餘額就是挖礦的獎勵(以太幣),以下圖所示。

image.png

在Windows下執行一樣的命令會得到相同的結果(挖了30個區塊),以下圖所示。

image.png

(6)控制挖礦數量

有時須要控制挖礦數量,也就是說,挖到指定數量的區塊後自動終止挖礦,要達到這個目的,須要在JavaScript控制檯執行下面的命令。

miner.start(3); admin.sleepBlocks(10); miner.stop();

其中start方法的參數表示挖礦使用的線程,默認值是CPU內核的數量,如CPU是雙核的,那麼線程數就是2。sleepBlocks方法的參數表示要挖的區塊數,本例是10個區塊。若是尚未挖完10個區塊,那麼sleepBlocks方法會處於阻塞狀態,直到挖完10個區塊,會繼續執行下面的代碼,也就是miner.stop(),這時挖礦就會結束。

相關文章
相關標籤/搜索