前言
Metropolis階段的eth讓人看著揪心稽鞭,具體的區(qū)塊高度和分叉高度可以查詢https://fork.codetract.io/這個網(wǎng)站剑肯。不過通過現(xiàn)在的情況來看最欠,估計eth歸零只是時間問題了翠勉。本著學(xué)習(xí)的態(tài)度,讓我們來最后一次回顧一下eth這個技術(shù)吧。
由于eth主網(wǎng)的接入和合約部署還是很消耗rmb的药蜻,因此痢法,我們要做的第一件事情就是搭建一個屬于自己的私鏈。本文便是圍繞著如何搭建并使用eth私鏈展開的。
安裝與部署
環(huán)境
為了打造一個自己的私有鏈體系,我特地準(zhǔn)備了阿里云的高效服務(wù)器(每個月大概1300多的租金的那種配置)。如果是要鏈接到eth主網(wǎng)捏浊,那么還需要ssd高效云盤才行(月租金還會更高)。本文只介紹最快速的eth私有鏈搭建撞叨,因此金踪,一切從簡。當(dāng)然牵敷,如果是僅僅只是想試試以太坊胡岔,也可以在個人電腦上弄,步驟是一樣的(本文說的步驟都說基于linux的枷餐,win或者mac會有一些小的出入靶瘸,可以參考https://github.com/ethereum/go-ethereum/wiki提供的各個平臺的安裝步驟)。
我準(zhǔn)備的操作系統(tǒng)是ubuntu,參考的文章是https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Ubuntu怨咪。我沒有選擇基于編譯的方式去安裝屋剑,我是用的是PPA方案。(當(dāng)然诗眨,以后如果要定制自己的獨特服務(wù)或者功能唉匾,還是需要通過編譯的方式進(jìn)行安裝的)
步驟
1.Installing from PPA
PPA = Personal Package Archives for Ubuntu
我們需要執(zhí)行如下命令,執(zhí)行命令的行數(shù)很長匠楚,我就不再此處貼截圖了
sudo apt-get update
sudo apt-get upgrade
//以上兩項會執(zhí)行一段時間
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get install ethereum
經(jīng)過了一小段時間之后巍膘,eth所需要的程序都安裝完畢了。執(zhí)行geth -help
可以驗證是否安裝成功芋簿。并且峡懈,版本也是目前最新的。
上面的圖片展示了eth的基礎(chǔ)用法与斤、命令肪康、參數(shù)等信息。此部分內(nèi)容會在后邊詳細(xì)敘述撩穿。eth安裝完成后磷支,接下來就要部署私有鏈了。
2.準(zhǔn)備創(chuàng)世紀(jì)區(qū)塊
此步驟參考了https://github.com/ethereum/go-ethereum網(wǎng)站的相關(guān)文字冗锁。首先創(chuàng)建一個名為genesis.json的文件(genesis.json這個文件,是eth的作者仿效btc而起的嗤栓,當(dāng)然文件的名字您可以任意起冻河,只要程序能找到這個文件就行)
genesis.json的文件內(nèi)容,我們根據(jù)官網(wǎng)提供的文字進(jìn)行填寫茉帅,內(nèi)容如下:
{
"config": {
"chainId": 0,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
簡單說明一下這個配置文件的內(nèi)容都是什么意思:
內(nèi)容 | 說明 |
---|---|
chainId | 不同版本的eth的id叨叙,比較經(jīng)典有,1代表主網(wǎng)堪澎,2代表普通測試網(wǎng)絡(luò)擂错,3代表Ropsten測試網(wǎng)絡(luò),4代表Rinkeby測試網(wǎng)絡(luò)樱蛤,42代表Kovan測試網(wǎng)絡(luò)(其他的值代表哪些網(wǎng)絡(luò)钮呀,可以參考https://ethereum.stackexchange.com/questions/17051/how-to-select-a-network-id-or-is-there-a-list-of-network-ids/17101#17101),chainId的值要與在geth命令中的--networkid參數(shù)保持一致 |
homesteadBlock | Homestead 硬分叉區(qū)塊高度昨凡,填寫官網(wǎng)的默認(rèn)值即可爽醋,后續(xù)硬分叉時才需要調(diào)整 |
eip155Block | EIP 155 硬分叉高度,填寫官網(wǎng)的默認(rèn)值即可便脊,后續(xù)硬分叉時才需要調(diào)整 |
eip158Block | EIP 158 硬分叉高度蚂四,填寫官網(wǎng)的默認(rèn)值即可,后續(xù)硬分叉時才需要調(diào)整 |
alloc | 預(yù)設(shè)賬號以及賬號的以太幣數(shù)量,私有鏈挖礦比較容易可以不配置 |
coinbase | 礦工賬號 |
difficulty | 難度值遂赠,越大越難 |
extraData | 附加信息久妆,以0x開頭填寫,可以不填跷睦,我也選擇了不填 |
gasLimit | gas 的消耗總量限制筷弦,用來限制區(qū)塊能包含的交易信息總和,因為我們是私有鏈送讲,所以填的很大 |
nonce | 64 位隨機數(shù)奸笤,默認(rèn)即可 |
mixhash | 與 nonce 配合用于挖礦,由上一個區(qū)塊的一部分生成的 hash哼鬓,默認(rèn)即可监右。因為是第一個區(qū)塊,因此异希,默認(rèn)就是0了健盒。 |
parentHash | 上一個區(qū)塊的 hash 值,默認(rèn)即可称簿。因為是第一個區(qū)塊扣癣,因此,默認(rèn)就是0了憨降。 |
3.初始化創(chuàng)世紀(jì)區(qū)塊
上邊的步驟將準(zhǔn)備工作都做完了父虑,接下來是進(jìn)行創(chuàng)世紀(jì)區(qū)塊的初始化了(geth init
)
geth --datadir /privatePeer/bootOf init genesis.json
//--datadir 指定數(shù)據(jù)存放的目錄
4.啟動私鏈節(jié)點
啟動私鏈節(jié)點其實就是將控制臺掛接過去。通過執(zhí)行一條命令就可以做了授药,命令上的參數(shù)可以通過geth -h
來查看士嚎。另外,我們需要讓geth成為一個后臺運行的服務(wù)悔叽,因此莱衩,還要加上nohup命令。
nohup geth
--nodiscover
--maxpeers 300
--identity "yourEthName"
--rpc --rpccorsdomain "*" --rpcport 8545
--datadir "/home/yourpeer/"
--port "30303"
--allow-insecure-unlock
--rpcapi "db,eth,net,web3"
--networkid 123456
--cache 512
--verbosity 4
&
我們來簡單說明一下使用到的參數(shù)
參數(shù) | 說明 |
---|---|
nohup和& | 指定geth啟動為后臺服務(wù) |
nodiscover | 關(guān)閉節(jié)點自動發(fā)現(xiàn) |
maxpeers | 最大節(jié)點連接數(shù) |
identity | 設(shè)置節(jié)點名稱 |
rpc組 | --rpc --rpccorsdomain "" --rpcport 8545娇澎,這是一組參數(shù)笨蚁,rpc端口默認(rèn)就是8545,訪問域如果寫的話代表是任何域名都可以訪問趟庄,也可以指定特殊的域名訪問括细。 |
datadir | geth安裝的目錄,這個與初始化時候的路徑一樣即可 |
port | geth節(jié)點的端口戚啥,默認(rèn)也是30303 |
rpcapi | 允許rpc接入的方式 |
networkid | 網(wǎng)絡(luò)id勒极,該值與創(chuàng)世紀(jì)區(qū)塊中的chainId一致即可,否則就會連到別人的服務(wù)上去了 |
cache | 調(diào)整內(nèi)存分配 最小16MB虑鼎,默認(rèn)128MB |
verbosity | 日志等級:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3) |
nohup geth --nodiscover --maxpeers 300 --identity "privatepeer" --rpc --rpccorsdomain "*" --datadir /home/privatepeer/bootof --port "30303" --allow-insecure-unlock --rpcapi "db,eth,net,web3" --networkid 0 --cache 512 --verbosity 4 &
執(zhí)行完該命令后辱匿,就會生成對應(yīng)的文件一個是.ipc文件键痛,用于之后掛載控制臺的,一個.out文件匾七,這個是默認(rèn)的日志文件輸出
5.控制臺掛載到geth上
因為是后臺運行g(shù)eth絮短,因此,可以通過ipc方式進(jìn)入控制臺
geth attach ipc:/yourPeerDoc/geth.ipc
6.查看區(qū)塊的內(nèi)容
在沒有開始挖礦之前昨忆,我們只能看到創(chuàng)世紀(jì)區(qū)塊丁频,執(zhí)行命令eth.getBlock(0)
> eth.getBlock(0)
{
difficulty: 131072,
extraData: "0x",
gasLimit: 3141592,
gasUsed: 0,
hash: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000042",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 507,
stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
timestamp: 0,
totalDifficulty: 131072,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
雖然創(chuàng)世紀(jì)區(qū)塊是我們自己創(chuàng)建的,但是邑贴,通過geth初始化后席里,還是有些不一樣,我們來解釋一下這些參數(shù)
參數(shù) | 說明 |
---|---|
difficulty | 挖礦難度拢驾,這里轉(zhuǎn)化為 10 進(jìn)制奖磁,等于”0x2000”,后面區(qū)塊難度會隨著區(qū)塊高度升高而提高 |
extraData | 當(dāng)前區(qū)塊附加信息繁疤,若創(chuàng)世區(qū)塊該值為空咖为,在第二個區(qū)塊中會保存,創(chuàng)建該私有鏈時的 geth稠腊,go躁染,及操作系統(tǒng)版本,保存信息為第一個挖到該區(qū)塊的礦工信息架忌,例如:0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421 |
gasLimit | 十進(jìn)制的 gasLimit 值,會隨之區(qū)塊高度提高而提高 |
gasUsed | gas 花費吞彤,在以太坊中交易和部署智能合約會消耗 gas,暫時可以理解為以太幣 |
hash | 當(dāng)前區(qū)塊hash值 |
logsBloom | 保存當(dāng)前區(qū)塊日志 |
miner | 挖到該區(qū)塊的礦工地址叹放,當(dāng)前尚未分配礦工饰恕,因此,無挖礦礦工信息 |
mixHash | 與 nonce 配合用于挖礦许昨,由上一個區(qū)塊的一部分生成的 hash |
nonce | 工作量證明的隨機數(shù)懂盐,因為是第一塊褥赊,這個是由我們?nèi)斯?chuàng)建的 |
number | 當(dāng)前區(qū)塊高度 |
parentHash | 上一個區(qū)塊 hash 值 |
receiptsRoot | 塊的收益樹根結(jié)果 |
sha3Uncles | 對叔區(qū)塊進(jìn)行 hash 運算的結(jié)果 |
size | 區(qū)塊大小糕档,以字節(jié)為單位 |
stateRoot | 塊的狀態(tài)樹根結(jié)果 |
timestamp | 時間戳 |
totalDifficulty | 達(dá)到該區(qū)塊的難度總數(shù) |
transactions | 以數(shù)組的形式保存交易的 tx 值 |
transactionsRoot | 交易的默克爾樹根 |
uncles | 以數(shù)組表示數(shù)區(qū)塊的哈希 |
總結(jié)
至此,我們就完成了一個相對標(biāo)準(zhǔn)的eth私鏈的搭建拌喉,此處還差了如何加入新節(jié)點等文字的說明速那,此部分內(nèi)容我會后續(xù)更新。關(guān)于eth私鏈的使用尿背,我會再另外一篇文章《使用自己的eth私有鏈》中進(jìn)行詳細(xì)講解
附錄:win下的節(jié)點創(chuàng)建
nohup geth --nodiscover --maxpeers 300 --identity "privatepeer" --rpc --rpccorsdomain "*" --rpcport 8545 --datadir /home/ubuntu/pp_data --allow-insecure-unlock --port "30303" --rpcapi "db,eth,net,web3" --networkid 8945121267 --cache 512 --verbosity 4 &
關(guān)于節(jié)點安全
關(guān)于端口
一般不應(yīng)該把默認(rèn)的8545作為rpc端口端仰,我一般使用8991,ws使用8992
nohup geth --nodiscover --maxpeers 1024 --identity "han" --rpc --rpccorsdomain "" --datadir /home/ubuntu/gethnode --port 30303 --rpcaddr 0.0.0.0 --rpcport 8991 --ws --wsaddr 0.0.0.0 --wsport 8992 --wsorigins "" --allow-insecure-unlock --rpcapi "db,eth,net,web3" --networkid 1 --cache 4096 --verbosity 4 &
geth節(jié)點間連接并建立點對點網(wǎng)絡(luò)的端口30303需要開放田藐。
如果開發(fā)rpcport荔烧、wasport吱七,不建議在此節(jié)點上進(jìn)行賬戶管理
一般來說,生產(chǎn)環(huán)境應(yīng)用節(jié)點鹤竭,主要是查詢數(shù)據(jù)踊餐、廣播交易。賬戶管理臀稚,最好在去中心化錢包中去做吝岭。將簽名后的交易通過sendRawTransaction 發(fā)送到我們搭建的節(jié)點上。
當(dāng)這兩個參數(shù)的值設(shè)為 0.0.0.0 時吧寺,將允許來自任何機器的 http 和 web socket 連接窜管。
這個時候如果在自己搭的 geth 節(jié)點上創(chuàng)建或?qū)脲X包,并執(zhí)行 personal.unlockAccount 命令稚机,別人就可以通過開放的 http或 web socket 連接執(zhí)行 sendTransaction 調(diào)用將錢包中的以太幣資產(chǎn)轉(zhuǎn)出幕帆。
節(jié)點加固
SSH Tunnel,通過下面的命令將遠(yuǎn)程調(diào)用限制于本地連接抒钱,這里將 rpcaddr 和 wsaddr 參數(shù)的值都設(shè)為了 127.0.0.1
geth --datadir --cache 4096 data --rpc --rpcport 6666 --rpcaddr 127.0.0.1 --ws --wsaddr 127.0.0.1 --wsport 6667 --wsorigins "*"
其它機器要調(diào)用這個節(jié)點怎么辦呢蜓肆?可以通過 SSH Tunnel 建立該機器與節(jié)點機器間的可信連接。
Basic Auth
可以在節(jié)點服務(wù)器上搭建 nginx 服務(wù)器谋币,配置相應(yīng)的 basic auth仗扬,通過用戶名密碼來限制對 geth 節(jié)點 rpc 服務(wù)的調(diào)用。
full蕾额、fast早芭、ligth
full:從開始到結(jié)束,獲取區(qū)塊的header诅蝶,獲取區(qū)塊的body退个,從創(chuàng)始塊開始校驗每一個元素,需要下載所有區(qū)塊數(shù)據(jù)信息调炬。速度最慢语盈,但是能獲取到所有的歷史數(shù)據(jù)。geth –syncmode full(默認(rèn)是full)
fast:獲取區(qū)塊的header缰泡,獲取區(qū)塊的body刀荒,在同步到當(dāng)前塊之前不處理任何事務(wù)。下載的數(shù)據(jù)量較少棘钞。然后獲得一個快照缠借,此后,像full節(jié)點一樣進(jìn)行后面的同步操作宜猜。這種方法用得最多泼返,目的在不要在意歷史數(shù)據(jù),將歷史數(shù)據(jù)按照快照的方式姨拥,不逐一驗證绅喉,沿著區(qū)塊下載最近數(shù)據(jù)庫中的交易渠鸽,有可能丟失歷史數(shù)據(jù)。此方法可能會對歷史數(shù)據(jù)有部分丟失柴罐,但是不影響今后的使用拱绑。geth –syncmode fast
注意:默認(rèn)情況下full模式,在以太坊源碼中丽蝎,如果本地當(dāng)前塊是number 0 (創(chuàng)始區(qū)塊)猎拨,不管指定的哪種模式都默認(rèn)是 --fast模式,當(dāng)geth第二次啟動的時候屠阻,默認(rèn)情況下full模式同步红省。
因此很多小伙伴在沒有指定同步模式的時候,在同步區(qū)塊的前期非彻酰快吧恃,當(dāng)再次重啟機器或者斷掉geth再啟動發(fā)現(xiàn)更新區(qū)塊速度非常慢,就是這個原因
handler.go 代碼中 新建以太坊子協(xié)議管理器func NewProtocolManager()
// Figure out whether to allow fast sync or not
if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() > 0 {
log.Warn("Blockchain not empty, fast sync disabled")
mode = downloader.FullSync
}
if mode == downloader.FastSync {
manager.fastSync = uint32(1)
}
主網(wǎng)節(jié)點
nohup geth --syncmode fast --maxpeers 1024 --rpc --rpccorsdomain "" --datadir /home/ubuntu/datageth --rpcaddr 0.0.0.0 --rpcport 8991 --ws --wsaddr 0.0.0.0 --wsport 8992 --wsorigins "" --allow-insecure-unlock --rpcapi "db,eth,net,web3" --networkid 1 --cache 4096 --verbosity 4 &
–identity:指定節(jié)點 ID麻诀;
–rpc:表示開啟 HTTP-RPC 服務(wù)痕寓;
–rpcaddr:HTTP-RPC 服務(wù)ip地址;
–rpcport:指定 HTTP-RPC 服務(wù)監(jiān)聽端口號(默認(rèn)為 8545)蝇闭;
–datadir:指定區(qū)塊鏈數(shù)據(jù)的存儲位置呻率;
–port:指定和其他節(jié)點連接所用的端口號(默認(rèn)為 30303,默認(rèn)的話呻引,可以不寫)
–nodiscover:關(guān)閉節(jié)點發(fā)現(xiàn)機制礼仗,防止加入有同樣初始配置的陌生節(jié)點。這個如果是配置主網(wǎng)的話逻悠,請不要打開元践。
重啟干凈后需要用geth removedb掉數(shù)據(jù)
新購買磁盤掛載
1.fdisk -l,查看是否存在未格式化的磁盤童谒,其中vda表示的系統(tǒng)盤单旁,vdb表示的其他磁盤
2.格式化其他磁盤,mkfs.ext3 /dev/vdb
3.創(chuàng)建磁盤掛載點饥伊,也就是創(chuàng)建一個新的目錄象浑,mkdir /data
4.磁盤掛載,mount /dev/vdb /data/
5.修改fstab撵渡,向其中添加分區(qū)信息融柬,以便系統(tǒng)啟動時自動掛載磁盤死嗦,echo '/dev/vdb /data ext3 defaults 0 0' >> /etc/fstab
6.reboot
7.df -h 查看磁盤是否已經(jīng)掛載