衆所周知的位元幣以及其它基於PoW的加密貨幣,最大的缺陷之一就是會遭遇51%攻擊(雖然難度較大),雖然區塊鏈是不可變的,並且記錄無法更改,但是攻擊者可能會實施其它攻擊,如拒絕服務攻擊,從而導致應用癱瘓。
另外,PoW的計算消耗了大量的電力資源,以太坊一直致力研究PoW的替代方案,例如PoS,這解決了電力問題,但它更多地針對的是公鏈。
對於私鏈,工作證明根本沒有意義。
以太坊很快過渡到了PoS演算法,此演算法解決了公鏈工作證是且的問題,想要成爲礦工的人會將一些以太幣存入智慧合約中,如果礦工被認爲是惡意的,那麼這部分以太幣將會被鎖定。
因爲沒有競爭來解決難以解決的數學問題,所以不必總是發行新幣,礦工將從交易中獲得回報。
這種演算法確實解決了過度用電的問題,並確實在一定程度上可以防止51%攻擊。
對於私鏈,PoS可能比Pow更 好,但它仍然沒有爲我們提供所需的控制和安全級別,因爲如果他們提交了足夠的以太幣做爲押金,那麼公鏈上的任何人都可以成爲礦工。
PoA是區塊鏈世界中的一個新概念,在這個概念中,您擁有許多預先批準的授權節點(稱爲審查者,即通常意義上的礦工)。
您要新增任何新節點,必須由當前已有的審查者投票,這使您可以完全控制哪一些節點可以做爲審查者。
以太坊的PoA協定稱爲Clique,它適用於私鏈,但不適用於公鏈。
因此本次搭建的智子鏈是基於POA共識機制 機製。
推薦:ubuntu16.04 4核8G 500G硬碟
最低:ubuntu16.04 2核4G 500G硬碟
git clone https://github.com/ethereum/go-ethereum
cd go-ethereum && make geth
執行完成後在build/bin的目錄下會生成可執行檔案geth,建立四個
資料夾n1,n2,s1,s2,n 用作普通節點,用於後期節點間發起交易,s作爲授權節點,s1 設定爲創世塊指定的授權節點;s2作爲後期加入信任名單授權節點。
爲每個節點建立一個智子鏈賬戶。指令geth --datadir ./data account new是指使用當前目錄下的data目錄當作geth存放資料的地方,並且創一個新的Account。在剛剛建立的n1, n2, s1, s2 目錄下分別執行相同指令來建立一個賬戶,如下圖所示:
n2,s1,s2以同樣的方法建立賬戶,注意:一定要記住自己的密碼和各個賬號的Public address of the key,後面會用到。
Clique 是將授權節點的相關資訊放在Block Header中,必須設定創世塊纔可以讓授權機制 機製生效。
在 1.6 之後的以太坊中提供了初始化創世塊的工具:puppeth, 請選擇含有 Geth & Tools 的版本下載,下載地址:https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.9.8-d62e9b28.tar.gz。
puppeth 是個互動式的程式,直接啓動照着指示輸入相關資訊。設定 Private chain 名稱(名稱裡不允許有-,空格),假定爲 poatest,如下:
設定新的創世塊,選擇2->1:
選擇共識機制 機製,選2:
設定生產出一個Block的時間,在這裏設5 秒,可自行選擇,如下圖:
指定授權節點,使用上面的s1的address,如下圖:
給賬戶設定一些ether。我選了node1和signer1的address,可自行選擇,如下圖:
Network Id,直接用random隨機生成即可,如下圖:
導出初始塊,如下圖:
ctrl+c退出,可以看到當前目錄有一個poatest.json檔案,如下圖:
創世塊poatets.json檔案裡參數的意義,如下:
參數 | 解釋 |
---|---|
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 | 附加資訊,在 POA 挖礦中。 |
gasLimit | 該值設定對 GAS 的消耗總量限制,用來限制區塊能包含的交易資訊總和,因爲我 們是私有鏈,所以填最大。 |
使用 geth init 指令,分別初始化 4 個節點的 datadir
geth --datadir n1/data/ init geth-alltools/poatest.json
geth --datadir n2/data/ init geth-alltools/poatest.json
geth --datadir s1/data/ init geth-alltools/poatest.json
geth --datadir s2/data/ init geth-alltools/poatest.json
初始化完成之後,在每個資料夾中會生成兩個子資料夾
geth 用來儲存區塊鏈的數據資訊,keystore 用來儲存賬戶資訊。
啓動各個節點:
以控制檯形式啓動:geth --datadir n1/data --networkid 66300 --port 3000 console
執行在後台:nohup geth --datadir n1/data --networkid 66300 --port 3000 &
連線控制檯:geth attach --datadir n1/data
注意:s1爲挖礦節點啓動時需要解鎖,–password指定密碼檔案 ,–unlock解鎖賬戶
datadir先前的步驟已經在每個節點各自的目錄下都建立了data目錄,networkid geths之間一定都要用同一個值纔可以互相通訊,比如實驗中的66300. Portgeths 之間通訊時,監聽的一個port,由於四個節點都在本機,所以這裏必須指定不同的值,使用 n1 對應 3000, n2 對應 3002, s1 對應 3003, s2 對應 3004.
geth參數含義如下:
參數 | 解釋 |
---|---|
identity | 區塊鏈的標示,隨便填寫,用於標示目前網路的名字 |
init | 指定創世塊檔案的位置,並建立初始塊 |
datadir | 設定當前區塊鏈網路數據存放的位置 |
port | 網路監聽埠 |
rpc | 啓動 rpc 通訊,可以進行智慧合約的部署和偵錯 |
rpcapi | 設定允許連線的 rpc 的用戶端,一般爲 db,eth,net,web3 |
networkid | 設定當前區塊鏈的網路 ID,用於區分不同的網路,是一個數字 |
console | 啓動命令列模式,可以在 Geth 中執行命令 |
啓動節點時,資訊中的enode需要記錄,後面建立節點間的通訊需要用到。
目前各個節點雖然已經啓動,但是各個節點之間仍然處於孤立狀態。各節點啓動後無法相互通訊的,所以geth要連上對方的節點就必須先設定好enode://@:,複製剛剛啓動node1時出現的enode資訊,將[::]替換爲127.0.0.1,這樣就可以讓其他節點加入。如上面提示的的紅色提示所見, n1 的 enode 爲:enode://498d3960afb904231c54044b0ed5c6c19a3241460ba06a46170dd5a22f00009735b6515008c6a87c164e41d24446801a523d83050d3bc4da16150bbc91ebb0fa@127.0.0.1:3000
在n2,s1,s2的geth console介面下分別執行如下指令建立節點間的通訊:admin.addPeer(「enode://498d3960afb904231c54044b0ed5c6c19a3241460ba06a46170dd5a22f00009735b6515008c6a87c164e41d24446801a523d83050d3bc4da16150bbc91ebb0fa@127.0.0.1:3000」)
完成後,在 node1 的 geth console 輸入 admin.peers 應該要看到三個節點資訊,如下:(每個id 對應其他節點的 encode 欄位資訊)
按照實驗的設計,在本實驗中 s1 爲挖礦節點,我們下面 下麪開始進行模擬挖礦,在 s1 的console 介面,鍵入 miner.start(),geth 就會開始挖礦了,在 s1 的 輸出日誌nohup.out 會出現正在mining 的資訊,如下圖:
由上圖可看出挖礦節點每5秒出一個塊。
按照我們的預設,在 n1 和 s1 上是已經初始化了餘額的。查詢如下圖:
預設賬戶是Locked狀態,需要先解鎖爲unlock狀態,纔可以進行賬戶間的轉賬,解鎖過程如下圖:
轉賬後查詢賬戶餘額:
s2 是一開始未設定在創世塊中信任列表的節點,如果這時候讓它啓動miner,會遇到一個未授權的錯誤,如下:
回到已經在授權名單內的節點的console介面下,將新的節點加入,如下:
重新啓動s1,s2兩個節點,進入控制檯執行miner.start()發現兩節點均提示Signed recently, must wait for others(由於兩節點沒有建立通訊),因此在signer1中通過admin.addPeer()新增signer2,使二者可以通訊,如下:
最後在s1,s2上執行miner.start(),兩節點開始交替挖礦。如下:
加入第三個信任節點:
啓動節點後,首先跟其他節點建立連線admin.addPeer(enode://7267113574d0c7f9c2d0859e5f552f172d2add8e4d31c76861494b7815baea170058b01b35c97dcb638dc57f8b0395127e77f25469d75092eb5abcca497cb57c@172.31.33.187:3000)
然後在s1,s2上分別多新加入的s3進行授權:clique.propose(「0x3f9a3A33884FF903c0924EDD384A2AF1657f926B」,true)
重新啓動s3節點,重新連線後將s3與s1,s2建立連線,在s1,s2上分別執行admin.addPeer(「enode://cd1226502cf4805b2bec5766290717db8ae941b7629aac08668014a32bc1996fd31801fb7f6ce4504593a5a505310379156b47689f33a77df9c5ac426db79e47@127.0.0.1:3004」)
最後在s3節點執行miner.start()開始挖礦,此時s1,s2,s3三個節點交替挖礦。
加入普通節點,先生成一個新賬戶,再初始化私有鏈,然後啓動該節點,在該節點裏與其他節點建立連線即可,截圖如下:
clique命令及其意義:
list sealers clique.getSigners()
list propositions: clique.proposals
discard a proposition: clique.discard(「0x1234234234234」)
add a new sealer: clique.propose(「0x1234243214312」, true)
remove a sealer: clique.propose(「0x1234243214312」, false)
刪除一個信任節點時,先remove a sealer,再discard a proposition
Tips:在終端不關閉的情況下,重新啓動geth進入console介面,通過admin.peers檢視鏈接資訊,發現之前新增的節點資訊都存在;但是,關閉終端後,重新開啓一個新的終端,啓動geth進入console介面,通過admin.peers檢視鏈接資訊,會發現是空的,需要重新執行admin.addPeer()新增,這一點一定要注意!!!
通過clique.discard(signer_address)刪除信任節點。通過clique.propose(signer_address,true)新增信任節點,通過實驗發現,無法立即生效,需要一半以上的信任節點的投票。一般要在當前所有的信任節點的終端中都執行clique.propose(),並且在各信任節點的終端都同時挖礦,各自挖出幾個塊後,新新增的信任節點就可已挖礦了。
參照:
https://blog.csdn.net/shangsongwww/article/details/89063564