以太坊学习路线——(一)私有链搭建与基本操作
這篇博客演示的基本操作系統環境是CentOS 7,參考書籍:以太坊開發實戰——以太坊關鍵技術與案例分析 第五章(吳壽鶴、馮翔、劉濤、周廣益?? 著)。
文章結構:
一.geth客戶端安裝
二.搭建一個私有鏈
1.新建一個geth工作目錄
2.創世區塊配置文件
3.初始化
4.啟動私有鏈
三.以太坊私有鏈上的基本操作
1.創建用戶
2.查看余額
3.挖礦
4.解鎖賬戶
5.交易
6.區塊
7.賬戶管理
8.區塊數據管理
9.遠程節點連接
10.通過attach命令連接已啟動節點
四.常見問題
1.執行miner.start()返回null
一.geth客戶端安裝
這篇博客演示的基本操作系統環境是CentOS 7,參考書籍:以太坊開發實戰——以太坊關鍵技術與案例分析(吳壽鶴、馮翔、劉濤、周廣益?? 著)。首先從github上獲取go-ethereum源碼,然后編譯geth。獲取源碼命令:
[root@localhost opt]# git clone https://github.com/ethereum/go-ethereum.git??? 如果git未安裝請自行百度安裝。
如上圖所示,由于之前在本目錄中下載過go-ethereum,故顯示其已存在。然后進入到go-ethereum目錄,進行編譯:
[root@localhost opt]# cd go-ethereum/ [root@localhost go-ethereum]# make geth由于我的客戶端編譯過了,所以沒有顯示編譯細節,但只要編譯成功便會在末尾顯示:Run "/opt/go-ethereum/build/bin/geth" to launch geth來提示啟動geth,注意雙引號之間的內容為你安裝時的路徑,會有所不同。
二.搭建一個私有鏈
??????? 1.新建一個geth工作目錄
$ mkdir geth $ cd geth $ mkdir db $ touch gensis.json //執行完成后目錄結構 geth ├── db └── gensis.json??????? 2.創世區塊配置文件
??????? gensis. json文件內容如下:
{"config": {"chainId": 15,"homesteadBlock": 0,"eip155Block": 0,"eip158Block": 0},"coinbase" : "0x0000000000000000000000000000000000000000","difficulty" : "0x40000","extraData" : "","gasLimit" : "0xffffffff","nonce" : "0x0000000000000042","mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000","parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000","timestamp" : "0x00","alloc": { }}?相關參數作用表如下:
| chainID | 指定了獨立的區塊鏈網絡 ID。網絡 ID 在連接到其他節點的時候會用到,以太坊公網的網絡 ID 是 1,為了不與公有鏈網絡沖突,運行私有鏈節點的時候要指定自己的網絡 ID。不同 ID 網絡的節點無法相互連接 |
| homesteadBlock | 取值為0表示正在使用homesteadBlock版本。 以太坊的發展分成了四個階段:(每個階段進步到下一個階段都是通過硬分叉的方式實現的) ??????? 1.Frontier(前沿):2015年7月30日,以太坊發布了Frontier階段,此時的軟件還不太成熟,但可以進行基本的挖礦測試去中心化應用(Dapps),該階段參與者主要為開發者。 ??????? 2.HomesteadBlock(家園):在2016年3月14日(圓周率節),以太坊發布了HomesteadBlock階段。以太坊開始平穩運行,提供了圖形界面的錢包,普通用戶也可以體驗和使用以太坊。 ??????? 3.Metropolis(大都會):Metropolis被分成了兩個階段:Byzantium(拜占庭)和Constantinople (居士坦丁堡)。 ?????????? 2017.10.16,以太坊拜占庭硬分叉成功,引入了包括:zk-SNARKs(簡明非交互零知識證明)、revert功能、return和抽象賬戶。?? ?????????? 2019年2月底,以太坊區塊鏈的第7,080,000區塊作為激活點正式開啟君士坦丁堡硬分叉,點在于將以太坊的共識機制由PoW向PoW+PoS混合機制過渡,從而使整個以太坊網絡更加的輕盈、快捷與安全。按官方說法,具體在現有以太坊PoW主網上進行升級的有以下5個方面: ?????????? (1).EIP 145:給EVM增加移位相關指令,包括左移SHL,邏輯右移SHR,算術右移SAR ?????????? (2).EIP 1014:產生合約地址的一種新規則,與狀態通道有關。規則為keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:] ?????????? (3).EIP 1052:為EVM增加EXTCODEHASH指令,這個指令可以獲得一個合約bytecode的keccak256的hash值; ?????????? (4).EIP 1283:修改EVM的SSTORE指令gas計算方式,預計會減少許多合約的gas消耗,需要硬分叉支持; ?????????? (5).EIP 1234:將是潛在最有爭議的提案,也需要硬分叉支持,它包括難度炸彈(Difficulty Bomb)協議推遲12個月和挖礦獎勵調整,難度炸彈使挖礦難度隨時間推移越來越高,挖礦獎勵調整將挖礦獎勵從3個降低到2個; ??????? 4.Serenity(寧靜) |
| eip155Block | eip是ethereum improvement proposal的縮寫,你的鏈不會因為因為這些提議分叉,故設置為“0”即可 |
| eip158Block | eip是ethereum improvement proposal的縮寫,你的鏈不會因為因為這些提議分叉,故設置為“0”即可 |
| mixhsah | 與nonce配合用于挖礦,由上一個區塊的一部分生成的哈希。注意它和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 | 上一個區塊的哈希值,由于是創世區塊,所以值為0 |
| extraData | 可以寫入32Byte大小的任意數據,每個block都會有,由挖出block的miner來決定要不要在里面寫什么 |
| gasLimit | 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總 |
???????3.初始化
//進入geth目錄中,執行初始化命令: $ geth --datadir "./db" init gensis.json??????? geth init命令用來初始化區塊連,命令可以帶有選項和參數,其中--datadir后面跟了一個目錄名db,表示指定數據存放目錄為db,gensis.json為init命令的參數。初始化成功后,會在db目錄中生成geth和keystore兩個文件夾,其中,geth/db/geth/chaindata中存放的是區塊數據,geth/db/keystore中存放的是賬戶數據。geth目錄結構如下:
[root@localhost geth]# tree ../geth/ ../geth/ ├── db │?? ├── geth │?? │?? ├── chaindata │?? │?? │?? ├── 000001.log │?? │?? │?? ├── CURRENT │?? │?? │?? ├── LOCK │?? │?? │?? ├── LOG │?? │?? │?? └── MANIFEST-000000 │?? │?? └── lightchaindata │?? │?? ├── 000001.log │?? │?? ├── CURRENT │?? │?? ├── LOCK │?? │?? ├── LOG │?? │?? └── MANIFEST-000000 │?? └── keystore └── gensis.json??????? 4.啟動私有鏈
//console 2>>geth.log 表示將日志輸出到geth.log,打開另外一個控制臺執行tail -f 查看日志 $ geth --datadir "./db" --nodiscover console 2>>geth.log??? geth啟動參數詳解:
| identity | 區塊鏈的標識,用于標識目前網絡的名字 |
| datadir | 指明當前區塊鏈私鑰和網絡數據存放的位置 |
| port | 指定以太坊網絡監聽端口,默認為30303 |
| rpc | 開啟HTTP-RPC服務,可以進行智能合約的部署和調試 |
| rpcaddr | 指定HTTP-RPC服務監聽地址,默認為“localhost” |
| rpcapi | 設置允許連接的rpc的客戶端,一般為db、eth、net、web3 |
| rpcport | 指定HTTP-RPC服務監聽端口,默認為8545 |
| networkid | 指定以太坊id,其實就是區塊鏈網絡的身份標識,共有鏈為1,測試鏈為3,默認啟動id為1 |
| etherbase | 指定礦工帳號,默認為keystory中首個帳號 |
| mine | 開啟挖礦,默認為CPU挖礦 |
| minerthreads | 挖礦占用CPU線程數,默認為4 |
| nodiscover | 關閉自動連接節點,但可以手動添加節點,在搭建私有鏈時,為避免其他節點連入私有鏈,可使用該命令 |
| maxpeers | 設置允許最大節點數,默認為25 |
| console | 啟動命令行模式,可以在geth中執行命令 |
?????? 啟動后進入javascript命令行控制臺,顯示結果如下:
[root@localhost geth]# geth --datadir "./db" --nodiscover console 2>>geth.log Welcome to the Geth JavaScript console!instance: Geth/v1.8.20-unstable/linux-amd64/go1.11 coinbase: 0x1baed334cbf41a94daef7b247beebd6fdc45100c at block: 112 (Mon, 25 Mar 2019 21:37:17 HKT)datadir: /opt/geth/dbmodules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0>??? 打開另一個終端,執行 tail -f geth.log可以時刻查看相關日志內容:
[root@localhost geth]# tail -f geth.log INFO [03-26|10:20:55.418] Loaded most recent local header number=112 hash=842b42…2c27da td=28062821 age=12h43m38s INFO [03-26|10:20:55.418] Loaded most recent local full block number=112 hash=842b42…2c27da td=28062821 age=12h43m38s INFO [03-26|10:20:55.418] Loaded most recent local fast block number=112 hash=842b42…2c27da td=28062821 age=12h43m38s INFO [03-26|10:20:55.419] Loaded local transaction journal transactions=0 dropped=0 INFO [03-26|10:20:55.419] Regenerated local transaction journal transactions=0 accounts=0 WARN [03-26|10:20:55.419] Blockchain not empty, fast sync disabled INFO [03-26|10:20:55.584] New local node record seq=2 id=c9432d51b9f92fe1 ip=127.0.0.1 udp=0 tcp=30303 INFO [03-26|10:20:55.584] Started P2P networking self="enode://688e30b0fd748189b882fb54af5ddf5c2d11555fbf9fd869a96b0f59729cab43b7e6f4c02e59df5ee94a4c2890e54804fa7a2e9476d82e708a903b6b9cc5383a@127.0.0.1:30303?discport=0" INFO [03-26|10:20:55.587] IPC endpoint opened url=/opt/geth/db/geth.ipc INFO [03-26|10:20:55.786] Etherbase automatically configured address=0x1Baed334CbF41A94daEF7B247bEebD6fdC45100C??? 以太坊的javascript控制臺中內置了一些以太坊對象,通過這些對象我們可以很方便的與以太坊交互:
- ??????? eth:提供了操作區塊鏈相關的方法
- ??????? net:提供了查看p2p網絡狀態的方法
- ??????? admin:提供了管理節點相關的方法
- ??????? miner:提供啟動和停止挖礦的方法
- ??????? personal:提供了管理賬戶的方法
- ??????? txpool:提供了查看交易內存池的方法
- ??????? web3:除了包含以上對象中有的方法,還包含了一些單位換算的方法
三.以太坊私有鏈上的基本操作
??????? 1.創建用戶
//查看帳戶,可以看到有我之前創建的三個賬戶,若沒有創建過賬戶則顯示: [] > eth.accounts ["0x1baed334cbf41a94daef7b247beebd6fdc45100c", "0xdb3d4ae8e3624d1ec75bba5c4da024c5984e3b17", "0x115b0ba0ffddb13cd513ec38679e1089c252c839"] > //建帳戶的方式有兩種,第一種創建帳戶時直接初始化密碼 //如下創建的賬戶為“0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103”,密碼為“444444” > personal.newAccount("444444") "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103" > //第二種方法是先創建賬戶,然后輸入密碼"555555" > personal.newAccount() Passphrase: Repeat passphrase: "0x6ccfd99b17da037d7f974aa9bd9bd65a04f514d1" > //此時查看已創建的用戶,有5個 > eth.accounts ["0x1baed334cbf41a94daef7b247beebd6fdc45100c", "0xdb3d4ae8e3624d1ec75bba5c4da024c5984e3b17", "0x115b0ba0ffddb13cd513ec38679e1089c252c839", "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103", "0x6ccfd99b17da037d7f974aa9bd9bd65a04f514d1"] >???
//賬戶創建成功后會返回賬戶地公鑰,生成的賬戶文件在keystore文件夾下: db/keystore/ ├── UTC--2019-03-25T13-11-16.002140069Z--1baed334cbf41a94daef7b247beebd6fdc45100c ├── UTC--2019-03-25T13-15-38.206845483Z--db3d4ae8e3624d1ec75bba5c4da024c5984e3b17 ├── UTC--2019-03-25T13-28-30.957174224Z--115b0ba0ffddb13cd513ec38679e1089c252c839 ├── UTC--2019-03-26T02-47-59.331021277Z--eed50d745a67eaa2a2eaf9e08a2485d1c1145103 └── UTC--2019-03-26T02-52-31.434967091Z--6ccfd99b17da037d7f974aa9bd9bd65a04f514d1??????? 2.查看余額
? ? 以太幣的最小單位為wei,1 ether = wei
//由于我的賬戶挖過礦,且發生過交易,故前三個賬戶有余額,單位為wei //而新創建的兩個賬戶未發生過交易,故余額為0 > eth.getBalance(eth.accounts[0]) 557000021000000000000 > eth.getBalance(eth.accounts[1]) 999979000000000000 > eth.getBalance(eth.accounts[2]) 2000000000000000000 > eth.getBalance(eth.accounts[3]) 0 > eth.getBalance(eth.accounts[4]) 0 >??????? 3.挖礦
//在挖礦之前要先設置挖礦獎勵地址,默認為創建的第一個賬戶地址,即eth.accounts[0] > miner.setEtherbase(eth.accounts[0]) true > //設置完成后,查看是否設置成功,返回結果為設置后的挖礦獎勵地址 > eth.coinbase "0x1baed334cbf41a94daef7b247beebd6fdc45100c" > //開始挖礦 > miner.start() null //在之前打開的另一個終端中可以看到挖礦日志記錄 INFO [03-26|13:05:36.057] Updated mining threads threads=4 INFO [03-26|13:05:36.057] Transaction pool price threshold updated price=1000000000 INFO [03-26|13:05:36.059] Commit new mining work number=113 sealhash=527c2b…95e338 uncles=0 txs=0 gas=0 fees=0 elapsed=746.685μs INFO [03-26|13:06:55.500] Successfully sealed new block number=113 sealhash=527c2b…95e338 hash=0b5a7f…5202bb elapsed=1m19.441s INFO [03-26|13:06:55.500] ? mined potential block number=113 hash=0b5a7f…5202bb INFO [03-26|13:06:55.501] Commit new mining work number=114 sealhash=20a5a4…07fb8c uncles=0 txs=0 gas=0 fees=0 elapsed=137.993μs INFO [03-26|13:06:56.895] Successfully sealed new block number=114 sealhash=20a5a4…07fb8c hash=5bae51…cca193 elapsed=1.394s INFO [03-26|13:06:56.895] ? mined potential block number=114 hash=5bae51…cca193 INFO [03-26|13:06:56.895] Commit new mining work number=115 sealhash=75cdcb…42129c uncles=0 txs=0 gas=0 fees=0 elapsed=187.946μs INFO [03-26|13:07:00.470] Successfully sealed new block number=115 sealhash=75cdcb…42129c hash=52352a…4e6153 elapsed=3.574s INFO [03-26|13:07:00.470] ? mined potential block number=115 hash=52352a…4e6153 INFO [03-26|13:07:00.470] Commit new mining work number=116 sealhash=8590f9…10690f uncles=0 txs=0 gas=0 fees=0 elapsed=138.993μs INFO [03-26|13:07:01.796] Successfully sealed new block number=116 sealhash=8590f9…10690f hash=2bc9b7…1d7a1c elapsed=1.326s INFO [03-26|13:07:01.796] ? mined potential block number=116 hash=2bc9b7…1d7a1c INFO [03-26|13:07:01.797] Commit new mining work number=117 sealhash=4f171e…976b8e uncles=0 txs=0 gas=0 fees=0 elapsed=208.115μs INFO [03-26|13:07:02.863] Successfully sealed new block number=117 sealhash=4f171e…976b8e hash=89b748…8abebc elapsed=1.066s INFO [03-26|13:07:02.864] ? mined potential block number=117 hash=89b748…8abebc INFO [03-26|13:07:02.864] Commit new mining work number=118 sealhash=d23ff5…1ee086 uncles=0 txs=0 gas=0 fees=0 elapsed=173.425μs INFO [03-26|13:07:06.387] Successfully sealed new block number=118 sealhash=d23ff5…1ee086 hash=573e64…31050e elapsed=3.522s INFO [03-26|13:07:06.387] ? mined potential block number=118 hash=573e64…31050e INFO [03-26|13:07:06.387] Commit new mining work number=119 sealhash=c8840a…c9c0af uncles=0 txs=0 gas=0 fees=0 elapsed=228.028μs INFO [03-26|13:07:12.455] Successfully sealed new block number=119 sealhash=c8840a…c9c0af hash=dae780…86c027 elapsed=6.068s INFO [03-26|13:07:12.455] ? mined potential block number=119 hash=dae780…86c027 INFO [03-26|13:07:12.455] Commit new mining work number=120 sealhash=f89e85…f46780 uncles=0 txs=0 gas=0 fees=0 elapsed=134.293μs INFO [03-26|13:07:12.851] Successfully sealed new block number=120 sealhash=f89e85…f46780 hash=b034c6…e2c5fc elapsed=395.460ms INFO [03-26|13:07:12.851] ? block reached canonical chain number=113 hash=0b5a7f…5202bb INFO [03-26|13:07:12.851] ? mined potential block number=120 hash=b034c6…e2c5fc??????? 4.解鎖賬戶
?//方式一,參數中只傳入要解鎖的賬戶地址,控制臺提示輸入密碼時請輸入密碼,成功后返回true > personal.unlockAccount(eth.accounts[2]) Unlock account 0x115b0ba0ffddb13cd513ec38679e1089c252c839 Passphrase: true > //方式二,參數中傳入賬戶地址和密碼 > personal.unlockAccount(eth.accounts[2],"333333") true > //方式三,參數中傳入賬戶地址、密碼、賬戶解鎖狀態持續時間 > personal.unlockAccount(eth.accounts[2],"333333",300) true >??????? 5.交易
//發起交易,內容為accounts[2]賬戶向accounts[3]賬戶發送1 ether以太幣,返回值為交易hash //此時的交易正在礦工的交易池中等待被打包 > eth.sendTransaction({from: eth.accounts[2], to: eth.accounts[3],value: web3.toWei(1,"ether")}) "0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0"//查看accounts[2]用戶和accounts[3]用戶的余額如下: > eth.getBalance(eth.accounts[2]) 2000000000000000000 > eth.getBalance(eth.accounts[3]) 0//查看交易池等待被打包的交易,其中有一條pending的交易,表示已提交但還未被處理的交易 > txpool.status {pending: 1,queued: 0 }//查看pending交易詳情 > txpool.inspect.pending {0x115B0ba0ffDdB13Cd513ec38679E1089C252C839: {0: "0xeed50D745A67EaA2A2EAf9e08A2485D1c1145103: 1000000000000000000 wei + 90000 gas × 1000000000 wei"} } //要使交易被處理,必須要挖礦,啟動挖礦后,等待挖到一個區塊之后就可以停止挖礦了 > miner.start(1);admin.sleepBlocks(1);miner.stop(); null > //在日志顯示終端可以看到正常執行后的挖礦日志 INFO [03-26|14:37:06.377] Updated mining threads threads=1 INFO [03-26|14:37:06.377] Transaction pool price threshold updated price=1000000000 INFO [03-26|14:37:06.378] Commit new mining work number=418 sealhash=14f834…2c37a4 uncles=0 txs=0 gas=0 fees=0 elapsed=376.473μs INFO [03-26|14:37:06.381] Commit new mining work number=418 sealhash=f1a1e0…13c185 uncles=0 txs=1 gas=21000 fees=2.1e-05 elapsed=3.129ms INFO [03-26|14:37:06.537] Successfully sealed new block number=418 sealhash=f1a1e0…13c185 hash=a79ae1…4cce3e elapsed=158.086ms INFO [03-26|14:37:06.537] ? block reached canonical chain number=411 hash=8de5b1…25b9e2 INFO [03-26|14:37:06.537] ? mined potential block number=418 hash=a79ae1…4cce3e INFO [03-26|14:37:06.537] Commit new mining work number=419 sealhash=58dcdb…adddbf uncles=0 txs=0 gas=0 fees=0 elapsed=217.251μs //此時交易已經成功打包,并且加入區塊鏈中了,此時查看余額: > eth.getBalance(eth.accounts[2]) 999979000000000000 > eth.getBalance(eth.accounts[3]) 1000000000000000000 >??????? accounts[3]余額正確為1 ether,而accounts[2]似乎應該由2 ether變為1 ether,但結果并不是,這其中的原由便需要好好解釋一下。
??????? 在以太坊中一個比較重要的概念就是gas,當你調用一個智能合約的時候,整個網絡中的每個礦工會分別執行你調用的合約程序,這會消耗礦工的CPU、內存、與硬盤空間,在合約中執行每個命令的消耗會用單位gas計數。
??????? gasPrice是你愿意為單位gas支付的費用,以gwei為單位表示。1 gwei = 1 000 000 000 wei,在交易中gasPrice是由發起交易的人規定的,每個礦工接收到交易請求時,會根據gasPrice的高低來決定是否要打包進區塊中。
??????? 如果你希望礦工運行你的合約,你最好提供高一點的gasPrice。在某種程度上,這是一場基于合約運行,有多意愿付費驅動下的競價。
??????? 在每個交易中必須包含gasLimit和gasPrice的值。gasLimit代表這個交易在執行過程中最多被允許消耗的gas數量。gasLimit和gasPrice就代表了交易發送者愿意為執行交易支付的wei的最大值。其最多可能付款金額 =? gasLimit ? X? gasPrice? (wei)。
??????? 在交易完成后,如果實際消耗的gas小于gasLimit,那么剩余的gas會返回給交易發起者,交易實際法非金額計算方式:
??????????????????????????????????????????????????? 實際交易費 = gasUsed?? X?? gasPrice
??????? 回到本例子中,通過查看下文中本交易被發起時的交易詳情可以知道,本例子的轉賬交易發起時的gas = 90000,gasPrice = 1 000 000 000。而交易完成后被打包進區塊后,該交易的詳細信息中gasUsed: = 21 000 。
??????? 故這次交易的花費了:21 000 X 1 000 000 000 = 21 000 000 000 000 wei
??????? accounts[2]向accounts[3]轉賬了1 ether后剩余1 ether = 1 000 000 000 000 000 000 wei,但還要承擔交易費,故:
??????? 1 ?? 0 0 0 ?? 0 0 0 ?? 0 0 0? ? 0 0 0 ?? 0 0 0? ? 0 0 0
— ? ? ??????? ? ? ? ? ?? ? 2 1 ?? 0 0 0??? 0 0 0??? 0 0 0??? 0 0 0
——————————————————————
???? ? ? ??? 9 9 9??? 9 7 9 ?? 0 0 0??? 0 0 0??? 0 0 0???? 0 0 0?????????
? ? ? ? 所以accounts[2]賬戶的余額為999 979 000 000 000 000
??????? 6.區塊
//查看指定交易哈希值 所對應交易 被發起時的交易詳情: > eth.getTransaction("0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0") {blockHash: "0xa79ae173965c379d7fd75e865faf955e65d55feb1b3afe840a18fbe8f04cce3e",blockNumber: 418,from: "0x115b0ba0ffddb13cd513ec38679e1089c252c839",gas: 90000,gasPrice: 1000000000,hash: "0x28f7e6989893d6e8b1cd26d5d7a285654f5a3c8eff7d6b2029817496deb8bda0",input: "0x",nonce: 0,r: "0xb7579b66aa0e051b7ec7e8dad8f4d07454d415df6d7a2497a76f76b7e4bb0b62",s: "0x53357a3b80e1e478012b89df718be16613f4f3a20141393acb16538dd3b02d23",to: "0xeed50d745a67eaa2a2eaf9e08a2485d1c1145103",transactionIndex: 0,v: "0x42",value: 1000000000000000000 } >??? 其中參數詳情 :
| blockHash | 交易所在區塊的哈希值。當這個區塊處于pending時將會返回null |
| blockNumber | 交易所在區塊的區號。當這個區塊處于pending時將會返回null |
| from | 交易發起的地址 |
| gas | 交易發起者提供的gas數量 |
| gasPrice | 交易發起者提供的gasPrice,單位為wei |
| hash | 交易的哈希值 |
| input | 交易附帶的數據 |
| nonce | 交易的發起者在之前發起過的交易數量 |
| transactionIndex | 交易在區塊中的序號。當這個區塊處于pending時將會返回null |
| value | 交易附帶的貨幣量,單位為wei |
| to | 交易接受者的地址 |
??????? 其中參數詳情 :
| blockHash | 交易所在區塊的哈希值。 |
| blockNumber | 交易所在區塊的區號。 |
| contractAddress | 創建的合約地址。如果是一個合約創建交易,則返回合約地址,其他情況返回null |
| cumulativeGasUsed | 當前交易執行后累計花費的gas總值 |
| from | 交易發送者的地址 |
| gasUsed | 執行當前這個交易單獨花費的gas |
| logs | 這個交易產生的日志對象數組 |
| logsBloom | logsBloom由logs中的address與topics共同決定,詳細請看以太坊黃皮書,作用是便于快速查找監聽的事件是否在該交易中產生 |
| root | 交易執行后的stateroot |
| to | 交易接收者的地址。如果是一個合約創建的交易,返回null |
| transactionHash | 交易的哈希值 |
| transationIndex | 交易在區塊里面的序號 |
??????? 常用查詢區塊命令:
- ??????????????? 查看當前區塊總數:eth.blockNumber
- ??????????????? 查詢最新區塊:eth.getBlock("latest")? 返回該區塊的詳細信息,eth.getBlock(blockNumber/blockHash)根據區塊?? Number或Hash查詢區塊 //查看當前區塊鏈節點中第Number為1的區塊詳情
> eth.getBlock(1)
{difficulty: 249472,extraData: "0xd683010814846765746886676f312e3131856c696e7578",gasLimit: 4290772993,gasUsed: 0,hash: "0xc18e6263be514c9c79b822d1d1fa9c17f25c148f4e71fb876da2c676eb19df2a",logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",miner: "0x1baed334cbf41a94daef7b247beebd6fdc45100c",mixHash: "0xf67374106da53196fe47cd9002ea0e18415d209efae336619c8fa4fab1359455",nonce: "0x1f7390e1d36e28fd",number: 1,parentHash: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e",receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",size: 535,stateRoot: "0xbb491beccc4865b5728c8cec43bc46846591d54ba2a87dbd86aa03af18bcdbfd",timestamp: 1553519563,totalDifficulty: 511616,transactions: [],transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",uncles: []
}
>
??????????????? 參數含義如下:
difficulty 挖礦難度,后面區塊難度會隨著區塊高度升高而提高 extraData 當前區塊鏈附加信息,若創世區塊該值為空,則在第二個區塊中會保存創建該私有鏈時的geth、go,以及操作系統版本,保存的信息為第一個挖到該區塊的礦工信息 gasLimit 該區塊允許的最大gas數 GasUsed gas花費,在以太坊中交易和部署智能合約會消耗gas hash 當前區塊哈希值 logsBloom logsBloom由logs中的address與topics共同決定,詳細請看以太坊黃皮書,作用是便于快速查找監聽的事件是否在該交易中產生 miner
挖到該區塊的礦工地址 mixHash 與nonce配合用于挖礦,由上一個區塊的一部分生成的hash nonce 工作量證明 number 當前區塊鏈高度 parentHash 上一個區塊鏈哈希值 receiptsRoot 區塊receipt trie的根 sha3Uncles 對叔區塊進行hash運算的結果 size 區塊大小,以字節為單位 stateRoot 塊的狀態樹根結果 timestamp 時間戳 totalDifficulty 達到該區塊的難度綜總數 transactions 以數組的形式保存交易的tx值 transactionsRoot 交易的默爾克樹根 uncles 當前區塊引用的束縛區塊的哈希值
7.賬戶管理
(1).創建新帳號
[root@localhost geth]# geth --datadir "./db1" account new INFO [03-29|20:39:53.169] Maximum peer count ETH=25 LES=0 total=25 Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat passphrase: Address: {b1d70e94ffcba142fd024ece374e0be3cd9c08ad}(2).列舉已存在帳號
[root@localhost geth]# geth --datadir "./db1" account list INFO [03-29|20:46:02.607] Maximum peer count ETH=25 LES=0 total=25 Account #0: {c4e87bb87064c40ecc07ed8955f35533c92a82f0} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T13-07-34.305959164Z--c4e87bb87064c40ecc07ed8955f35533c92a82f0 Account #1: {70083e2f06da81015c1ee24b60a53fde4f30bddb} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T14-08-09.815911074Z--70083e2f06da81015c1ee24b60a53fde4f30bddb Account #2: {da66a23edbec03deef9eea953c1a2d865bf3acb3} keystore:///opt/geth/db1/keystore/UTC--2019-03-28T14-21-37.216641721Z--da66a23edbec03deef9eea953c1a2d865bf3acb3 Account #3: {b1d70e94ffcba142fd024ece374e0be3cd9c08ad} keystore:///opt/geth/db1/keystore/UTC--2019-03-29T12-40-09.120020587Z--b1d70e94ffcba142fd024ece374e0be3cd9c08ad(3).修改賬戶密碼
[root@localhost geth]# geth --datadir "./db1" account update b1d70e94ffcba142fd024ece374e0be3cd9c08ad INFO [03-29|20:48:53.009] Maximum peer count ETH=25 LES=0 total=25 Unlocking account b1d70e94ffcba142fd024ece374e0be3cd9c08ad | Attempt 1/3 Passphrase: INFO [03-29|20:48:58.466] Unlocked account address=0xB1d70e94FfCBa142FD024ecE374e0bE3Cd9C08ad Please give a new password. Do not forget this password. Passphrase: Repeat passphrase:(4).導入密鑰文件
[root@localhost geth]# geth --datadir "./db1" account import ecc.key INFO [03-29|21:06:10.906] Maximum peer count ETH=25 LES=0 total=25 Your new account is locked with a password. Please give a password. Do not forget this password. Passphrase: Repeat passphrase: Address: {fc563cb4086c1c9621c72b1a9f8d3b487fe438e9} //其中ecc.key是ECDSA[橢圓曲線數字簽名算法(ECDSA)是使用橢圓曲線密碼(ECC)對數字簽名算法(DSA)的模擬]的私鑰 [root@localhost geth]# cat ecc.key 25066ae7675c08bdafded1c1403cc5d1431597149eac21261c5a3002339a007b8.區塊數據管理
(1).導出區塊數據
//將db1目錄中的區塊數據導入到bak文件中: [root@localhost geth]# geth --datadir "./db1" export ./bak INFO [03-29|21:14:53.492] Maximum peer count ETH=25 LES=0 total=25 INFO [03-29|21:14:53.496] Allocated cache and file handles database=/opt/geth/db1/geth/chaindata cache=512 handles=1024 INFO [03-29|21:14:53.810] Disk storage enabled for ethash caches dir=/opt/geth/db1/geth/ethash count=3 INFO [03-29|21:14:53.810] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2 INFO [03-29|21:14:53.870] Loaded most recent local header number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s INFO [03-29|21:14:53.870] Loaded most recent local full block number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s INFO [03-29|21:14:53.870] Loaded most recent local fast block number=35 hash=7f2f97…73ba58 td=4603649 age=23h9m8s INFO [03-29|21:14:53.870] Exporting blockchain file=./bak INFO [03-29|21:14:53.870] Exporting batch of blocks count=36 INFO [03-29|21:14:53.873] Exported blockchain file=./bak Export done in 3.070252ms //導入成功好會在當前目錄下生成一個bak文件 [root@localhost geth]# ll total 48 -rwxr-xr-x. 1 root root 19230 Mar 29 21:14 bak drwx------. 4 root root 49 Mar 28 22:06 db1 -rw-r--r--. 1 root root 65 Mar 29 21:06 ecc.key -rw-r--r--. 1 root root 605 Mar 28 20:11 gensis.json -rw-r--r--. 1 root root 20377 Mar 28 22:06 geth.log?(2).移除區塊數據
[root@localhost geth]# geth --datadir "./db1" removedb INFO [03-29|21:18:16.562] Maximum peer count ETH=25 LES=0 total=25 /opt/geth/db1/geth/chaindata Remove this database? [y/N] y Remove this database? [y/N] y INFO [03-29|21:18:23.975] Database successfully deleted database=chaindata elapsed=1.166ms /opt/geth/db1/geth/lightchaindata Remove this database? [y/N] y Remove this database? [y/N] y INFO [03-29|21:18:26.355] Database successfully deleted database=lightchaindata elapsed=1.276ms(3).導入區塊數據
//導入區塊數據之前要用gensis.json文件執行初始化 [root@localhost geth]# geth --datadir "./db1" init gensis.json INFO [03-29|21:19:30.372] Maximum peer count ETH=25 LES=0 total=25 INFO [03-29|21:19:30.374] Allocated cache and file handles database=/opt/geth/db/geth/chaindata cache=16 handles=16 INFO [03-29|21:19:30.464] Writing custom genesis block INFO [03-29|21:19:30.464] Persisted trie from memory database nodes=0 size=0.00B time=21.737μs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [03-29|21:19:30.464] Successfully wrote genesis state database=chaindata hash=1ef75f…d1799a INFO [03-29|21:19:30.464] Allocated cache and file handles database=/opt/geth/db/geth/lightchaindata cache=16 handles=16 INFO [03-29|21:19:30.548] Writing custom genesis block INFO [03-29|21:19:30.548] Persisted trie from memory database nodes=0 size=0.00B time=6.821μs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [03-29|21:19:30.549] Successfully wrote genesis state database=lightchaindata hash=1ef75f…d1799a //初始化完成后就可以導入區塊數據le [root@localhost geth]# geth --datadir "./db1" import ./bak INFO [03-29|21:21:32.802] Maximum peer count ETH=25 LES=0 total=25 INFO [03-29|21:21:32.805] Allocated cache and file handles database=/opt/geth/db1/geth/chaindata cache=512 handles=1024 INFO [03-29|21:21:32.990] Writing default main-net genesis block INFO [03-29|21:21:33.440] Persisted trie from memory database nodes=12356 size=1.88mB time=72.102914ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [03-29|21:21:33.440] Disk storage enabled for ethash caches dir=/opt/geth/db1/geth/ethash count=3 INFO [03-29|21:21:33.440] Disk storage enabled for ethash DAGs dir=/root/.ethash count=2 INFO [03-29|21:21:33.468] Loaded most recent local header number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w INFO [03-29|21:21:33.468] Loaded most recent local full block number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w INFO [03-29|21:21:33.468] Loaded most recent local fast block number=0 hash=d4e567…cb8fa3 td=17179869184 age=49y11mo2w INFO [03-29|21:21:33.469] Importing blockchain file=./bak ERROR[03-29|21:21:33.471] ########## BAD BLOCK ######### Chain config: {ChainID: 1 Homestead: 1150000 DAO: 1920000 DAOSupport: true EIP150: 2463000 EIP155: 2675000 EIP158: 2675000 Byzantium: 4370000 Constantinople: <nil> Engine: ethash}Number: 1 Hash: 0xa5144c4a46a7047492371bdee8459785d09ae44e32d06a8a96c7409dfd35013aError: unknown ancestor ##############################ERROR[03-29|21:21:33.471] Import error err="invalid block 35: unknown ancestor" INFO [03-29|21:21:33.471] Blockchain manager stopped Import done in 2.573417ms.CompactionsLevel | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB) -------+------------+---------------+---------------+---------------+---------------Read(MB):0.00000 Write(MB):2.38956 Trie cache misses: 0 Trie cache unloads: 0Object memory: 268.085 MB current, 267.908 MB peak System memory: 334.967 MB current, 334.967 MB peak Allocations: 1.118 million GC pause: 396.612μsCompacting entire database... Compaction done in 786.903722ms.CompactionsLevel | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB) -------+------------+---------------+---------------+---------------+---------------0 | 0 | 0.00000 | 0.59842 | 0.00000 | 1.915271 | 1 | 1.91526 | 0.13436 | 1.91527 | 1.91526Read(MB):1.88542 Write(MB):6.22033 INFO [03-29|21:21:34.304] Database closed database=/opt/geth/db1/geth/chaindata(4).dump
//從區塊鏈中dump制定區塊數據,geth命令后可以傳入區塊編號或區塊hash值 $ geth --datadir "./db1" dump 0 ?9.遠程節點連接
(1).查看節點信息
> admin.nodeInfo {enode: "enode://4b13086b294f1b7b0801ff78eb62cd9b1bf2991819ccc2b69df9a0371a031c0d8f25e84aa92781cb590a20b4ed25d4c67184c44470e008a77dfbe9ec4fedfe20@127.0.0.1:38690?discport=0",enr: "0xf895b8407a227a916f7016b5dec567b0ecb41d6452fb41130b69bf861fae9ed271ff9c46607ae835137bf7b5508dfdd86a8df8ce859c61d044513ed707d72f5a58e272a50183636170ccc5836574683fc58373686806826964827634826970847f00000189736563703235366b31a1024b13086b294f1b7b0801ff78eb62cd9b1bf2991819ccc2b69df9a0371a031c0d83746370829722",id: "d0bd4223d5c476927e34787e99179c27da96f4e1dee7913a345d445c89a164dd",ip: "127.0.0.1",listenAddr: "[::]:38690",name: "Geth/v1.8.20-unstable/linux-amd64/go1.11",ports: {discovery: 0,listener: 38690},protocols: {eth: {config: {byzantiumBlock: 0,chainId: 1337,clique: {...},constantinopleBlock: 0,eip150Block: 0,eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",eip155Block: 0,eip158Block: 0,homesteadBlock: 0},difficulty: 37,genesis: "0x004680c14f64dd409489eb632569fb1440bffbfbbc4996263e3f3cadb10e37a1",head: "0x782e496b3110c566136549d7dfbc2cf7700b6414fcc3aa9d74eb5984ab076f39",network: 1337},shh: {maxMessageSize: 1048576,minimumPoW: 0.2,version: "6.0"}} }(2).添加其他節點
可以通過admin.addPeer()方法連接到其他節點,兩個接節點想要聯通,必須保證網絡時相通的,并且要指定相同的networkid。我的第一個節點時我的本機節點,另一個節點時遠程服務器節點,兩個節點的gensis.json文件相同。
首先通過在遠程服務器節點獲取其encode信息,注意要把encode中的[::]替換成該機器的IP地址。
> admin.nodeInfo.enode "enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303" //在本機連接遠程服務器節點 > admin.addPeer("enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303") true ?(3).查看已連接的遠程節點
> admin.peers [{caps: ["eth/63"],enode: "enode://e5b417b09f971fc06a4a413ed4ed2d431cd303e286e44b01cf6c126c51708bde44cf6f692f611e441ba22f0ebce1b384d3f418af338589358daacd322f9df966@207.246.103.126:30303",id: "f40c748606f81f3d600584b70e4425165ed68ed47484d20afe5051655e509719",name: "Geth/v1.8.23-stable/linux-amd64/go1.10.3",network: {inbound: false,localAddress: "192.168.124.48:48550",remoteAddress: "207.246.103.126:30303",static: true,trusted: false},protocols: {eth: {difficulty: 1,head: "0x1ef75f7ced81aa0ff14865c59117439c6ae6760468d64e46e06311190dd1799a",version: 63}} }]10.通過attach命令連接已啟動節點?
當通過geth命令啟動了一個以太坊私有鏈時,會在數據目錄下生成一個geth.ipc文件,在本例子中即為“./db/geth.ipc”。通過attach命令可以連接這個已經啟動的節點,來啟動一個Js命令環境:
[root@localhost geth]# geth --datadir "./db" attach ipc:./db/geth.ipc Welcome to the Geth JavaScript console!instance: Geth/v1.9.0-unstable-acbb8a14/linux-amd64/go1.11 coinbase: 0x8c7ae59ab7e5d510ae3f09a9544978f50315b5f5 at block: 107 (Sat, 06 Apr 2019 15:27:50 HKT)datadir: /opt/geth/dbmodules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0>四.常見問題
1.執行miner.start()返回null
解決方案借鑒自:https://blog.csdn.net/billwzf/article/details/83145111
geth版本更新之后,–dev模式(回歸測試模式)下新增了一個參數項:
--dev Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled --dev.period value Block period to use in developer mode (0 = mine only if transaction pending) (default: 0)–dev是我們常用的參數,之前版本中我們只用使用–dev然后執行miner.start()就可以挖礦,但是在后面的版本中,當我們會發現只有發送交易了才會挖一個塊。引起此問題的原因就是新增了–dev.period value配置項。此配置默認值為0,也就是說只有pending中存在交易才會挖礦。所以–dev參數依舊使用,然后再在后面添加–dev.period 1,即設置dev.period的參數為1。
由于此參數的存在,使得存在兩種啟動模式:
1.dev模式
//該模式下需要在pending中先存在交易才可以挖礦 geth --networkid 15 --dev console 2>>geth.log2.dev自動挖礦模式
geth --networkid 15 --dev --dev.period 1 console 2>>geth.log?
總結
以上是生活随笔為你收集整理的以太坊学习路线——(一)私有链搭建与基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 多线程——pthread_can
- 下一篇: TI/德州仪器 TPS57040QDGQ