以太坊搭建聯盟鏈教程
Quorum是一種基於以太坊的分散式分類賬協議,具有交易/合同隱私和新的共識機制。
Quorum是go-ethereum的一個分支,並根據go-ethereum釋出進行更新。
go-ethereum的關鍵改進:
- 隱私 - 仲裁通過公共/私有分離和利用Constellation支援私人交易和私人合同,Constellation是一種點對點加密訊息交換,用於將私人資料定向傳輸給網路參與者
- 替代共識機制 - 在許可網路中不需要POW / POS,Quorum提供了多種更適合聯盟鏈的共識機制:
- 基於Raft的共識 - 一種更快的阻塞時間,事務完成性和按需塊建立的共識模型
- Istanbul BFT
- 對等許可權 - 使用智慧合約進行節點/對等許可權,確保只有已知方才能加入網路
- 更高的效能 - Quorum提供比公共geth更高的效能
1. 首先,從github上下載Quorum
git clone https://github.com/jpmorganchase/quorum.git
下載成功後進入quorum資料夾在進行編譯
make all
編譯完成後會在bulid/bin檔案下發現abigen bootnode evm examples faucet geth p2psim puppeth rlpdump swarm wnode幾個可執行檔案 將它們新增到環境變數中即可 如export PATH=xxx/xxx/xxx/abigen:$PATH
注意:如果電腦中已經安裝了geth 再將上面的geth加入環境變數的話會出現衝突 可以改改名稱(如geth1)或者把檔案拷到需要執行的目錄,然後把geth改成./geth就行了
2. 下載constellation-node
wget https://github.com/jpmorganchase/constellation/releases/download/v0.3.1/constellation-0.3.1-ubuntu1604.tar.xz
我這裡用的是0.3.1,版本不同可能會有一些不一樣的地方,建議用我這個版本(用0.3.2之後的話不適用於本教程)
3. 下載用例教程
這是官方提供的樣例,部署七個節點。
git clone https://github.com/jpmorganchase/quorum-examples
4.基於raft機制搭建聯盟鏈
(1)首先進行初始化,可以找到raft-init.sh這個指令碼
#!/bin/bash
set -u
set -e
echo "[*] Cleaning up temporary data directories"
rm -rf qdata
mkdir -p qdata/logs
echo "[*] Configuring node 1 (permissioned)"
mkdir -p qdata/dd1/{keystore,geth}
cp permissioned-nodes.json qdata/dd1/static-nodes.json
cp permissioned-nodes.json qdata/dd1/
cp keys/key1 qdata/dd1/keystore
cp raft/nodekey1 qdata/dd1/geth/nodekey
geth --datadir qdata/dd1 init genesis.json
echo "[*] Configuring node 2 (permissioned)"
mkdir -p qdata/dd2/{keystore,geth}
cp permissioned-nodes.json qdata/dd2/static-nodes.json
cp permissioned-nodes.json qdata/dd2/
cp keys/key2 qdata/dd2/keystore
cp raft/nodekey2 qdata/dd2/geth/nodekey
geth --datadir qdata/dd2 init genesis.json
echo "[*] Configuring node 3 (permissioned)"
mkdir -p qdata/dd3/{keystore,geth}
cp permissioned-nodes.json qdata/dd3/static-nodes.json
cp permissioned-nodes.json qdata/dd3/
cp keys/key6 qdata/dd3/keystore
cp keys/key3 qdata/dd3/keystore
cp raft/nodekey3 qdata/dd3/geth/nodekey
geth --datadir qdata/dd3 init genesis.json
echo "[*] Configuring node 4 (permissioned)"
mkdir -p qdata/dd4/{keystore,geth}
cp permissioned-nodes.json qdata/dd4/static-nodes.json
cp permissioned-nodes.json qdata/dd4/
cp keys/key4 qdata/dd4/keystore
cp raft/nodekey4 qdata/dd4/geth/nodekey
geth --datadir qdata/dd4 init genesis.json
echo "[*] Configuring node 5"
mkdir -p qdata/dd5/{keystore,geth}
cp permissioned-nodes.json qdata/dd5/static-nodes.json
cp keys/key5 qdata/dd5/keystore
cp raft/nodekey5 qdata/dd5/geth/nodekey
geth --datadir qdata/dd5 init genesis.json
echo "[*] Configuring node 6"
mkdir -p qdata/dd6/{keystore,geth}
cp permissioned-nodes.json qdata/dd6/static-nodes.json
cp raft/nodekey6 qdata/dd6/geth/nodekey
cp keys/key7 qdata/dd6/keystore
geth --datadir qdata/dd6 init genesis.json
echo "[*] Configuring node 7"
mkdir -p qdata/dd7/{keystore,geth}
cp permissioned-nodes.json qdata/dd7/static-nodes.json
cp raft/nodekey7 qdata/dd7/geth/nodekey
cp keys/key8 qdata/dd7/keystore
geth --datadir qdata/dd7 init genesis.json
這個指令碼沒啥坑 直接執行即可。
(2)啟動聯盟鏈,執行raft-start.sh這個指令碼
#!/bin/bash
set -u
set -e
mkdir -p qdata/logs
echo "[*] Starting Constellation nodes"
./constellation-start.sh
echo "[*] Starting Ethereum nodes"
set -v
ARGS="--nodiscover --raft --rpc --rpcaddr 0.0.0.0 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum --emitcheckpoints"
PRIVATE_CONFIG=qdata/c1/tm.ipc nohup geth --datadir qdata/dd1 $ARGS --permissioned --raftport 50401 --rpcport 22000 --port 21000 --unlock 0 --password passwords.txt 2>>qdata/logs/1.log &
PRIVATE_CONFIG=qdata/c2/tm.ipc nohup geth --datadir qdata/dd2 $ARGS --permissioned --raftport 50402 --rpcport 22001 --port 21001 --unlock 0 --password passwords.txt 2>>qdata/logs/2.log &
PRIVATE_CONFIG=qdata/c3/tm.ipc nohup geth --datadir qdata/dd3 $ARGS --permissioned --raftport 50403 --rpcport 22002 --port 21002 --unlock 0 --password passwords.txt 2>>qdata/logs/3.log &
PRIVATE_CONFIG=qdata/c4/tm.ipc nohup geth --datadir qdata/dd4 $ARGS --permissioned --raftport 50404 --rpcport 22003 --port 21003 --unlock 0 --password passwords.txt 2>>qdata/logs/4.log &
PRIVATE_CONFIG=qdata/c5/tm.ipc nohup geth --datadir qdata/dd5 $ARGS --raftport 50405 --rpcport 22004 --port 21004 --unlock 0 --password passwords.txt 2>>qdata/logs/5.log &
PRIVATE_CONFIG=qdata/c6/tm.ipc nohup geth --datadir qdata/dd6 $ARGS --raftport 50406 --rpcport 22005 --port 21005 --unlock 0 --password passwords.txt 2>>qdata/logs/6.log &
PRIVATE_CONFIG=qdata/c7/tm.ipc nohup geth --datadir qdata/dd7 $ARGS --raftport 50407 --rpcport 22006 --port 21006 --unlock 0 --password passwords.txt 2>>qdata/logs/7.log &
set +v
echo
echo "All nodes configured. See 'qdata/logs' for logs, and run e.g. 'geth attach qdata/dd1/geth.ipc' to attach to the first Geth node."
echo "To test sending a private transaction from Node 1 to Node 7, run './runscript.sh private-contract.js'"
注意到這個指令碼中有constellation-start.sh這個指令碼,不知道為什麼我把constellation-node加入環境變數後也無法執行(可能是我電腦的原因?),如果你也遇到這個問題,就把之前下載的constellation-node拷到這個目錄下,然後把下面指令碼中的constellation-node改成./constellation-node就可以了。如果執行上面的raft-start.sh陷入死迴圈跳不出來的話,可以檢視qdata/logs中的日誌資訊來尋找原因。正常執行成功的話是會輸出最後那部分提示的(如下圖)
constellation-start.sh:
#!/bin/bash
set -u
set -e
for i in {1..7}
do
DDIR="qdata/c$i"
mkdir -p $DDIR
mkdir -p qdata/logs
cp "keys/tm$i.pub" "$DDIR/tm.pub"
cp "keys/tm$i.key" "$DDIR/tm.key"
rm -f "$DDIR/tm.ipc"
CMD="constellation-node --url=https://127.0.0.$i:900$i/ --port=900$i --workdir=$DDIR --socket=tm.ipc --publickeys=tm.pub --privatekeys=tm.key --othernodes=https://127.0.0.1:9001/"
echo "$CMD >> qdata/logs/constellation$i.log 2>&1 &"
$CMD >> "qdata/logs/constellation$i.log" 2>&1 &
done
DOWN=true
while $DOWN; do
sleep 0.1
DOWN=false
for i in {1..7}
do
if [ ! -S "qdata/c$i/tm.ipc" ]; then
DOWN=true
fi
done
done
不出意外的話,到這裡就基本上大功告成了,可以通過以下指令檢視七個節點是否順利執行,如果發現有七個程序在執行就證明已經成功了!只有一個的話就是失敗了,得回去找問題。
ps -ef | grep constellation-node
ps -ef | grep geth
5.操作某個節點
geth attach qdata/dd1/geth.ipc
即可進入1號節點的控制檯,基本操作跟geth是一樣的,eth.accounts可以檢視賬號,錢包檔案儲存在7nodes/qdata/下的dd開頭的七個資料夾中的keystore,然後再qdata/logs檔案下會有1.log 到7.log ,1.log是主節點的挖礦資訊,後面幾個是1節點同步過去的資訊,可以通過log來觀察聯盟鏈的事件。
至此,基本的七個節點就搭建起來了,下一節將結合具體專案來呼叫web3j!