以太坊私鏈入門

本文作者最近在找工作,有意向致電 13113668890

Mr. Neo Chen (陳景峯), netkiller, BG7NYT


中國廣東省深圳市龍華新區民治街道溪山美地
518131
+86 13113668890


版權聲明

轉載請與作者聯繫,轉載時請務必標明文章原始出處和作者信息及本聲明。

http://www.netkiller.cn
http://netkiller.github.io
http://netkiller.sourceforge.net
微信訂閲號 netkiller-ebook (微信掃瞄二維碼)
QQ:13721218 請註明“讀者”
QQ群:128659835 請註明“讀者”

2018-02-10

摘要

本文采用碎片化寫作,原文會不定期更新,請儘量閲讀原文。

http://www.netkiller.cn/journal/ethereum.html


目錄

1. 背景

區塊鏈是什麼?一句話,它是一種特殊的(非關係型)分散式資料庫,這種資料庫只能做插入和查找操作,並且沒有管理員。

首先,區塊鏈的主要作用是儲存信息。任何需要保存的信息,都可以寫入區塊鏈,也可以從裡面讀取,所以它是資料庫。

其次,任何人都可以架設伺服器,加入區塊鏈網絡,成為一個節點。區塊鏈的世界裡面,沒有中心節點,每個節點都是平等的,都保存着整個資料庫。你可以向任何一個節點,寫入/讀取數據,因為所有節點最後都會同步,保證區塊鏈一致。

2. 軟件安裝與配置

2.1. Ubuntu

2.1.1. 安裝 geth

安裝環境



Ubuntu 17.10

				
sudo apt upgrade -y				
sudo apt install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt update
sudo apt install ethereum			
				
				
				
neo@netkiller ~ % geth version
Geth
Version: 1.7.3-stable
Git Commit: 4bb3c89d44e372e6a9ab85a8be0c9345265c763a
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.1
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.9
				
				

2.1.2. 安裝 solc

				
sudo apt install solc -y
				
				
				
neo@netkiller ~ % solc --version
solc, the solidity compiler commandline interface
Version: 0.4.19+commit.c4cbbb05.Linux.g++				
				
				

2.2. CentOS 7

			
yum update -y
yum install git wget bzip2 -y	
yum install golang -y

cd /usr/local/src
git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum/
gmake all
mv build /srv/go-ethereum

echo "export PATH=$PATH:$PWD/build/bin" >> /etc/profile
source /etc/profile		
			
			

上面安裝版本是 unstable 版本,如果是生產環境請使用 Release 版本 https://github.com/ethereum/go-ethereum/tags

			
wget https://github.com/ethereum/go-ethereum/archive/v1.7.3.tar.gz
tar zxvf v1.7.3.tar.gz
cd go-ethereum-1.7.3/
gmake all

mv build /srv/go-ethereum-1.7.3
			
			

2.3. Windows

				
訪問 https://geth.ethereum.org/downloads/
下載並安裝 Geth for Windows				
				
			

2.4. Mac OS

				
brew update
brew upgrade				
brew tap ethereum/ethereum
brew install ethereum
brew install solidity
				
			

2.4.1. Ethereum Wallet

下載安裝以太坊錢包(大陸網絡可能下載有問題,需要翻牆)

https://github.com/ethereum/mist/releases/download/v0.9.3/Ethereum-Wallet-macosx-0-9-3.dmg

參數:

				
neo@MacBook-Pro ~ %  "/Applications/Ethereum Wallet.app/Contents/MacOS/Ethereum Wallet" --help
Usage: /Applications/Ethereum Wallet.app/Contents/MacOS/Ethereum Wallet --help
[Mist options] [Node options]

Mist options:
  --mode, -m              App UI mode: wallet, mist.[string] [default: "wallet"]
  --node                  Node to use: geth, eth        [string] [default: null]
  --network               Network to connect to: main, test
                                                        [string] [default: null]
  --rpc                   Path to node IPC socket file OR HTTP RPC hostport (if
                          IPC socket file then --node-ipcpath will be set with
                          this value).                                  [string]
  --swarmurl              URL serving the Swarm HTTP API. If null, Mist will
                          open a local node.
                                     [string] [default: "http://localhost:8500"]
  --gethpath              Path to Geth executable to use instead of default.
                                                                        [string]
  --ethpath               Path to Eth executable to use instead of default.
                                                                        [string]
  --ignore-gpu-blacklist  Ignores GPU blacklist (needed for some Linux
                          installations).                              [boolean]
  --reset-tabs            Reset Mist tabs to their default settings.   [boolean]
  --logfile               Logs will be written to this file in addition to the
                          console.                                      [string]
  --loglevel              Minimum logging threshold: info, debug, error, trace
                          (shows all logs, including possible passwords over
                          IPC!).                      [string] [default: "info"]
  --syncmode              Geth synchronization mode: [fast|light|full]  [string]
  --version, -v           Display Mist version.                        [boolean]
  --skiptimesynccheck     Disable checks for the presence of automatic time sync
                          on your OS.                                  [boolean]

Node options:
  -  To pass options to the underlying node (e.g. Geth) use the --node- prefix,
     e.g. --node-datadir

Options:
  -h, --help  Show help                                                [boolean]				
				
				

錢包預設是連接到下面地址。

				
IPC endpoint opened: /Users/neo/Library/Ethereum/geth.ipc
				
				

連接到其他ipc地址

				
"/Applications/Ethereum Wallet.app/Contents/MacOS/Ethereum Wallet" --rpc /Users/other/Library/Ethereum/geth.ipc
				
				

如果需要連接到遠程節點上,需要使用命令行,方法如下。啟動錢包並連接到遠程開發環境,localhost 改為你的IP地址即可。

				
"/Applications/Ethereum Wallet.app/Contents/MacOS/Ethereum Wallet" --rpc http://localhost:8545				
				
				

2.5. 編譯安裝

				
git clone https://github.com/ethereum/go-ethereum
sudo apt-get install -y build-essential golang
cd go-ethereum
make geth
				
			

2.6. Netkiller OSCM 一鍵安裝

適用於 CentOS 7

			
curl -s https://raw.githubusercontent.com/oscm/shell/master/blockchain/ethereum/centos/go-ethereum-1.7.3.sh | bash			
			
			

安裝完成後使用下面命令進入控制台

			
[root@localhost ~]# su - ethereum
Last login: Sat Feb  3 00:23:52 EST 2018 on pts/0
			
[ethereum@localhost ~]$ geth attach
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable/linux-amd64/go1.8.3
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 
			
			

3. 創世區塊

		
cd ~
mkdir -p ethereum
cd ethereum		
		
		

3.1. 初始化創世區塊

創建檔案 genesis.json

			
{
  "nonce": "0x0000000000000042",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  "gasLimit": "0x4c4b40",
  "config": {
      "chainId": 15,
      "homesteadBlock": 0,
      "eip155Block": 0,
      "eip158Block": 0
  },
  "alloc": { }
}
			
			



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: 附加信息,隨便填,可以填你的個性信息

gasLimit: 該值設置對GAS的消耗總量限制,用來限制區塊能包含的交易信息總和,因為我們是私有鏈,所以填最大。

初始化創世區塊

			
neo@netkiller ~/ethereum % geth init genesis.json 
WARN [01-19|17:35:17] No etherbase set and no accounts found as default 
INFO [01-19|17:35:17] Allocated cache and file handles         database=/home/neo/.ethereum/geth/chaindata cache=16 handles=16
INFO [01-19|17:35:17] Writing custom genesis block 
INFO [01-19|17:35:17] Successfully wrote genesis state         database=chaindata                          hash=611596…424d04
INFO [01-19|17:35:17] Allocated cache and file handles         database=/home/neo/.ethereum/geth/lightchaindata cache=16 handles=16
INFO [01-19|17:35:18] Writing custom genesis block 
INFO [01-19|17:35:18] Successfully wrote genesis state         database=lightchaindata                          hash=611596…424d04		
			
			

預設目錄是 /home/neo/.ethereum/ 你可以通過 --datadir 參數指定目錄

			
neo@netkiller ~/ethereum % geth --datadir data init genesis.json
WARN [01-19|17:38:16] No etherbase set and no accounts found as default 
INFO [01-19|17:38:16] Allocated cache and file handles         database=/home/neo/ethereum/data/geth/chaindata cache=16 handles=16
INFO [01-19|17:38:17] Writing custom genesis block 
INFO [01-19|17:38:17] Successfully wrote genesis state         database=chaindata                              hash=611596…424d04
INFO [01-19|17:38:17] Allocated cache and file handles         database=/home/neo/ethereum/data/geth/lightchaindata cache=16 handles=16
INFO [01-19|17:38:17] Writing custom genesis block 
INFO [01-19|17:38:17] Successfully wrote genesis state         database=lightchaindata                              hash=611596…424d04		

neo@netkiller ~/ethereum % find data 
data
data/keystore
data/geth
data/geth/chaindata
data/geth/chaindata/LOCK
data/geth/chaindata/LOG
data/geth/chaindata/MANIFEST-000000
data/geth/chaindata/CURRENT
data/geth/chaindata/000001.log
data/geth/lightchaindata
data/geth/lightchaindata/LOCK
data/geth/lightchaindata/LOG
data/geth/lightchaindata/MANIFEST-000000
data/geth/lightchaindata/CURRENT
data/geth/lightchaindata/000001.log		
			
			

目錄結構

			
data
├── geth
│  ├── chaindata
│  │  ├── 000001.log
│  │  ├── CURRENT
│  │  ├── LOCK
│  │  ├── LOG
│  │  └── MANIFEST-000000
│  └── lightchaindata
│      ├── 000001.log
│      ├── CURRENT
│      ├── LOCK
│      ├── LOG
│      └── MANIFEST-000000
└── keystore		
		
			

3.2. 啟動節點

			
neo@netkiller ~/ethereum % geth --networkid 123456 --rpc --rpccorsdomain "*" --nodiscover console 
WARN [01-19|17:47:06] No etherbase set and no accounts found as default 
INFO [01-19|17:47:06] Starting peer-to-peer node               instance=Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
INFO [01-19|17:47:06] Allocated cache and file handles         database=/home/neo/.ethereum/geth/chaindata cache=128 handles=1024
INFO [01-19|17:47:06] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Engine: unknown}"
INFO [01-19|17:47:06] Disk storage enabled for ethash caches   dir=/home/neo/.ethereum/geth/ethash count=3
INFO [01-19|17:47:06] Disk storage enabled for ethash DAGs     dir=/home/neo/.ethash               count=2
INFO [01-19|17:47:06] Initialising Ethereum protocol           versions="[63 62]" network=123456
INFO [01-19|17:47:06] Loaded most recent local header          number=0 hash=611596…424d04 td=131072
INFO [01-19|17:47:06] Loaded most recent local full block      number=0 hash=611596…424d04 td=131072
INFO [01-19|17:47:06] Loaded most recent local fast block      number=0 hash=611596…424d04 td=131072
INFO [01-19|17:47:06] Loaded local transaction journal         transactions=0 dropped=0
INFO [01-19|17:47:06] Regenerated local transaction journal    transactions=0 accounts=0
INFO [01-19|17:47:06] Starting P2P networking 
INFO [01-19|17:47:06] RLPx listener up                         self="enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@[::]:30303?discport=0"
INFO [01-19|17:47:06] IPC endpoint opened: /home/neo/.ethereum/geth.ipc 
INFO [01-19|17:47:06] HTTP endpoint opened: http://127.0.0.1:8545 
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> INFO [01-19|17:47:09] Mapped network port                      proto=tcp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"			
			
			



identity: 區塊鏈的標示,隨便填寫,用於標示目前網絡的名字

init: 指定創世塊檔案的位置,並創建初始塊

datadir: 設置當前區塊鏈網絡數據存放的位置

port: 網絡監聽連接埠

rpc: 啟動rpc通信,可以進行智能合約的部署和調試

rpcapi: 設置允許連接的rpc的客戶端,一般為db,eth,net,web3

networkid: 設置當前區塊鏈的網絡ID,用於區分不同的網絡,是一個數字

console: 啟動命令行模式,可以在Geth中執行命令

3.2.1. rpcaddr

預設是 127.0.0.1

HTTP endpoint closed: http://127.0.0.1:8545

通過 --rpcaddr="0.0.0.0" 指定監聽地址

HTTP endpoint opened: http://0.0.0.0:8545

				
neo@netkiller ~/ethereum % geth --networkid 123456 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" --nodiscover console  
INFO [01-20|01:41:33] Starting peer-to-peer node               instance=Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
INFO [01-20|01:41:33] Allocated cache and file handles         database=/home/neo/.ethereum/geth/chaindata cache=128 handles=1024
INFO [01-20|01:41:34] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Engine: unknown}"
INFO [01-20|01:41:34] Disk storage enabled for ethash caches   dir=/home/neo/.ethereum/geth/ethash count=3
INFO [01-20|01:41:34] Disk storage enabled for ethash DAGs     dir=/home/neo/.ethash               count=2
INFO [01-20|01:41:34] Initialising Ethereum protocol           versions="[63 62]" network=123456
INFO [01-20|01:41:34] Loaded most recent local header          number=531 hash=1a2707…3a27bc td=79083846
INFO [01-20|01:41:34] Loaded most recent local full block      number=531 hash=1a2707…3a27bc td=79083846
INFO [01-20|01:41:34] Loaded most recent local fast block      number=531 hash=1a2707…3a27bc td=79083846
INFO [01-20|01:41:34] Loaded local transaction journal         transactions=0 dropped=0
INFO [01-20|01:41:34] Regenerated local transaction journal    transactions=0 accounts=0
WARN [01-20|01:41:34] Blockchain not empty, fast sync disabled 
INFO [01-20|01:41:34] Starting P2P networking 
INFO [01-20|01:41:34] RLPx listener up                         self="enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@[::]:30303?discport=0"
INFO [01-20|01:41:34] IPC endpoint opened: /home/neo/.ethereum/geth.ipc 
INFO [01-20|01:41:34] HTTP endpoint opened: http://0.0.0.0:8545 
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6
at block: 531 (Tue, 14 Nov 2017 17:36:05 HST)
 datadir: /home/neo/.ethereum
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> INFO [01-20|01:41:40] Mapped network port                      proto=tcp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"
				
				

3.3. 使用節點進行挖礦

3.3.1. 啟動礦工開始挖礦

				
> miner.start(1)		
				
				

這裡的1表示只使用一個綫程運行,第一次運行時將開始創建DAG檔案,只需等待進度條到100,則將開始挖礦。 實際你看到的挖礦速度很快,這是因為我們已經在初始化創世區塊時配置為:"nonce": "0x0000000000000042"。 “0x42”難度能讓你在私有測試網鏈上快速挖以太幣。

提示

挖礦時必然有礦工賬戶,而系統預設使用創建的第一個賬號。

				
> miner.start(1)
INFO [01-19|21:06:43] Updated mining threads                   threads=1
INFO [01-19|21:06:43] Transaction pool price threshold updated price=18000000000
INFO [01-19|21:06:43] Starting mining operation 
null
> INFO [01-19|21:06:43] Commit new mining work                   number=1 txs=0 uncles=0 elapsed=717.552µs
INFO [01-19|21:06:46] Generating ethash verification cache     epoch=0 percentage=91 elapsed=3.000s
INFO [01-19|21:06:46] Generated ethash verification cache      epoch=0 elapsed=3.273s
INFO [01-19|21:06:51] Generating DAG in progress               epoch=0 percentage=0  elapsed=5.056s
INFO [01-19|21:06:56] Generating DAG in progress               epoch=0 percentage=1  elapsed=10.140s
INFO [01-19|21:07:01] Generating DAG in progress               epoch=0 percentage=2  elapsed=15.119s
INFO [01-19|21:07:06] Generating DAG in progress               epoch=0 percentage=3  elapsed=19.924s
INFO [01-19|21:07:11] Generating DAG in progress               epoch=0 percentage=4  elapsed=24.739s
INFO [01-19|21:07:16] Generating DAG in progress               epoch=0 percentage=5  elapsed=29.473s
INFO [01-19|21:07:22] Generating DAG in progress               epoch=0 percentage=6  elapsed=35.641s
INFO [01-19|21:07:26] Generating DAG in progress               epoch=0 percentage=7  elapsed=40.374s
INFO [01-19|21:07:31] Generating DAG in progress               epoch=0 percentage=8  elapsed=45.134s
INFO [01-19|21:07:36] Generating DAG in progress               epoch=0 percentage=9  elapsed=49.908s
INFO [01-19|21:07:41] Generating DAG in progress               epoch=0 percentage=10 elapsed=54.633s	
......
......
......
INFO [01-19|21:22:43] Generated ethash verification cache      epoch=0 elapsed=15m57.328s
INFO [01-19|21:22:47] Generating ethash verification cache     epoch=1 percentage=17 elapsed=3.031s
INFO [01-19|21:22:50] Generating ethash verification cache     epoch=1 percentage=34 elapsed=6.056s
INFO [01-19|21:22:53] Generating ethash verification cache     epoch=1 percentage=49 elapsed=9.562s
INFO [01-19|21:22:57] Generating ethash verification cache     epoch=1 percentage=70 elapsed=13.115s
INFO [01-19|21:23:00] Generating ethash verification cache     epoch=1 percentage=90 elapsed=16.123s
INFO [01-19|21:23:01] Generated ethash verification cache      epoch=1 elapsed=17.576s
INFO [01-19|21:23:19] Generating DAG in progress               epoch=1 percentage=0  elapsed=18.198s
INFO [01-19|21:23:32] Successfully sealed new block            number=1 hash=e2b5b9…9b1bfe
INFO [01-19|21:23:32] 🔨 mined potential block                  number=1 hash=e2b5b9…9b1bfe
INFO [01-19|21:23:32] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=1.188ms
INFO [01-19|21:23:37] Generating DAG in progress               epoch=1 percentage=1  elapsed=35.913s
INFO [01-19|21:23:41] Successfully sealed new block            number=2 hash=62db3f…e27b50
INFO [01-19|21:23:41] 🔨 mined potential block                  number=2 hash=62db3f…e27b50
INFO [01-19|21:23:41] Commit new mining work                   number=3 txs=0 uncles=0 elapsed=772.239µs
INFO [01-19|21:23:43] Successfully sealed new block            number=3 hash=34384b…c387f2
INFO [01-19|21:23:43] 🔨 mined potential block                  number=3 hash=34384b…c387f2
INFO [01-19|21:23:43] Commit new mining work                   number=4 txs=0 uncles=0 elapsed=1.002ms
INFO [01-19|21:23:55] Generating DAG in progress               epoch=1 percentage=2  elapsed=53.757s
INFO [01-19|21:24:13] Generating DAG in progress               epoch=1 percentage=3  elapsed=1m11.561s
INFO [01-19|21:24:30] Generating DAG in progress               epoch=1 percentage=4  elapsed=1m28.986s
INFO [01-19|21:24:30] Successfully sealed new block            number=4 hash=681970…462135
INFO [01-19|21:24:30] 🔨 mined potential block                  number=4 hash=681970…462135
INFO [01-19|21:24:30] Commit new mining work                   number=5 txs=0 uncles=0 elapsed=833.629µs
INFO [01-19|21:24:36] Successfully sealed new block            number=5 hash=7b058b…d2f07a
INFO [01-19|21:24:36] 🔨 mined potential block                  number=5 hash=7b058b…d2f07a
INFO [01-19|21:24:36] Commit new mining work                   number=6 txs=0 uncles=0 elapsed=897.815µs
INFO [01-19|21:24:43] Successfully sealed new block            number=6 hash=a5fc3d…b1221e
INFO [01-19|21:24:43] 🔗 block reached canonical chain          number=1 hash=e2b5b9…9b1bfe
INFO [01-19|21:24:43] 🔨 mined potential block                  number=6 hash=a5fc3d…b1221e
INFO [01-19|21:24:43] Commit new mining work                   number=7 txs=0 uncles=0 elapsed=758.061µs
INFO [01-19|21:24:47] Successfully sealed new block            number=7 hash=003b02…e886fd
INFO [01-19|21:24:47] 🔗 block reached canonical chain          number=2 hash=62db3f…e27b50
INFO [01-19|21:24:47] 🔨 mined potential block                  number=7 hash=003b02…e886fd
INFO [01-19|21:24:47] Commit new mining work                   number=8 txs=0 uncles=0 elapsed=920.862µs
INFO [01-19|21:24:48] Generating DAG in progress               epoch=1 percentage=5  elapsed=1m46.827s
INFO [01-19|21:25:06] Generating DAG in progress               epoch=1 percentage=6  elapsed=2m4.338s
INFO [01-19|21:25:23] Successfully sealed new block            number=8 hash=fd23c9…361c65
INFO [01-19|21:25:23] 🔗 block reached canonical chain          number=3 hash=34384b…c387f2
INFO [01-19|21:25:23] 🔨 mined potential block                  number=8 hash=fd23c9…361c65
INFO [01-19|21:25:23] Commit new mining work                   number=9 txs=0 uncles=0 elapsed=825.737µs
INFO [01-19|21:25:23] Generating DAG in progress               epoch=1 percentage=7  elapsed=2m22.061s
				
				

3.3.2. 停止挖礦

				
> miner.stop()
true
>
				
				

3.3.3. 查看所挖金額

				
> eth.getBalance(eth.accounts[0])
70000000000000000000				
				
				

3.4. 在創世鏈中制定礦工賬號併為它充值

			
  "alloc": {
    "0xe8abf98484325fd6afc59b804ac15804b978e607": {
      "balance": "300000"
    },
    "0x013b5e735e1b48421dd3de3b931d6f03e769e22b": {
      "balance": "400000"
    }
  }		
			
			

4. geth 命令

4.1. 控制台

Geth JavaScript console

			
neo@netkiller ~/ethereum % geth  --networkid 123456 console
INFO [01-19|22:14:52] Starting peer-to-peer node               instance=Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
INFO [01-19|22:14:52] Allocated cache and file handles         database=/home/neo/.ethereum/geth/chaindata cache=128 handles=1024
INFO [01-19|22:14:52] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Engine: unknown}"
INFO [01-19|22:14:52] Disk storage enabled for ethash caches   dir=/home/neo/.ethereum/geth/ethash count=3
INFO [01-19|22:14:52] Disk storage enabled for ethash DAGs     dir=/home/neo/.ethash               count=2
INFO [01-19|22:14:52] Initialising Ethereum protocol           versions="[63 62]" network=123456
INFO [01-19|22:14:52] Loaded most recent local header          number=14 hash=70d7f1…45850a td=1966848
INFO [01-19|22:14:52] Loaded most recent local full block      number=14 hash=70d7f1…45850a td=1966848
INFO [01-19|22:14:52] Loaded most recent local fast block      number=14 hash=70d7f1…45850a td=1966848
INFO [01-19|22:14:52] Loaded local transaction journal         transactions=0 dropped=0
INFO [01-19|22:14:52] Regenerated local transaction journal    transactions=0 accounts=0
WARN [01-19|22:14:52] Blockchain not empty, fast sync disabled 
INFO [01-19|22:14:52] Starting P2P networking 

INFO [01-19|22:14:56] UDP listener up                          self=enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@101.232.64.12:30303
INFO [01-19|22:14:56] RLPx listener up                         self=enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@101.232.64.12:30303
INFO [01-19|22:14:56] IPC endpoint opened: /home/neo/.ethereum/geth.ipc 
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6
at block: 14 (Fri, 19 Jan 2018 21:27:16 HST)
 datadir: /home/neo/.ethereum
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 
> INFO [01-19|22:14:56] Mapped network port                      proto=udp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"			
			
			

4.2. 連接控制台

一般測試啟動我們使用 console,如果是正式啟動無需使用 console。同事我們使用&符號使其進入後台運行。

			
neo@netkiller ~/ethereum % geth --networkid 123456 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" --nodiscover &			
			
			

進入控制台

			
neo@netkiller ~/ethereum % geth attach
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6
at block: 531 (Tue, 14 Nov 2017 17:36:05 HST)
 datadir: /home/neo/.ethereum
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
			
			

退出控制台

			
> exit
			
			

4.2.1. 指定 geth.ipc 檔案位置

				
geth --ipcpath ~/.ethereum/geth.ipc attach				
				
				

4.2.2. IPC 方式連接

				
neo@netkiller ~ % geth attach ethereum/data1/geth.ipc 
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

>				
				
				

4.2.3. TCP 連接控制台

連接遠程控制台

				
neo@netkiller ~/ethereum % geth --exec 'eth.coinbase' attach http://172.16.0.10:8545
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"
				
				

4.3. 賬號管理

4.3.1. 新建賬號

查看賬號

				
neo@netkiller ~/ethereum % geth account list 
Account #0: {83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6} keystore:///home/neo/.ethereum/keystore/UTC--2018-01-20T04-04-06.786586541Z--83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6				
				
				

創建賬號

				
neo@netkiller ~/ethereum % geth account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {e8abf98484325fd6afc59b804ac15804b978e607}				
				
				

指定密碼

				
$ echo "abc123" > password 
$ geth --password /path/to/password account new
				
				

賬號創建在 ~/.ethereum/keystore 目錄下

				
Mac: ~/Library/Ethereum/keystore
Linux: ~/.ethereum/keystore
Windows: %APPDATA%/Ethereum/keystore				
				
				
				
neo@netkiller ~/.ethereum/keystore % ll
total 8.0K
-rw------- 1 neo neo 491 Jan 19 18:04 UTC--2018-01-20T04-04-06.786586541Z--83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6
-rw------- 1 neo neo 491 Jan 19 20:11 UTC--2018-01-20T06-11-23.608902164Z--e8abf98484325fd6afc59b804ac15804b978e607				
				
				

4.3.2. 查看賬號

				
neo@netkiller ~/ethereum % geth account list 
Account #0: {83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6} keystore:///home/neo/.ethereum/keystore/UTC--2018-01-20T04-04-06.786586541Z--83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6
Account #1: {e8abf98484325fd6afc59b804ac15804b978e607} keystore:///home/neo/.ethereum/keystore/UTC--2018-01-20T06-11-23.608902164Z--e8abf98484325fd6afc59b804ac15804b978e607				
				
				

4.4. api 相關參數

rpcapi 啟動後允許連接到系統的API協議

			
geth --networkid 100000 --rpc --rpcapi "db,eth,net,web3" --rpccorsdomain "*" --datadir "/app/chain" --port "30303" console	
			
			

系統預設監聽 127.0.0.1 如果希望外部訪問本機,需要通過--rpcaddr指定監聽地址。

			
geth --networkid 123456 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" --nodiscover		
			
			

--rpcapi 可以控制訪問內容

			
$ geth --rpcapi personal,db,eth,net,web3 --rpc --rinkeby	
			

			

4.5. 配置自動解鎖賬號

創建password檔案,在裡面輸入密碼,每個賬號一行密碼如:

			
123456
123456
123456			
			
			

啟動參數

			
geth --rpc --rpcaddr="0.0.0.0" --rpccorsdomain="*" --unlock '0,1,2' --password ~/.ethereum/password   --nodiscover --maxpeers '5' --networkid '12345' --datadir '~/.ethereum'  console			
			
			

4.6. 運行JS

			
neo@netkiller ~/ethereum % geth --exec "eth.blockNumber" attach
531
			
			
			
$ geth --exec 'loadScript("/tmp/checkbalances.js")' attach http://123.123.123.123:8545
$ geth --jspath "/tmp" --exec 'loadScript("checkbalances.js")' attach http://123.123.123.123:8545			
			
			

4.7. 節點管理

			
geth --bootnodes enode://pubkey1@ip1:port1,enode://pubkey2@ip2:port2,enode://pubkey3@ip3:port3
			
			

4.8. 啟動挖礦

			
geth --mine
			
			

4.8.1. 挖礦綫程數

預設為 2

				
geth --mine --minerthreads=16
				
				

4.8.2. 指定曠工賬號

預設是第一個賬號

				
geth --mine --minerthreads=16 --etherbase=0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6			
				
				

4.9. 日誌

			
geth --networkid 123456 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*"  2>> /tmp/geth.log			
			
			

後台運行

			
neo@netkiller ~ % geth --networkid 123456 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" 2>> /tmp/geth.log &     
[1] 30075
 
neo@netkiller ~ % tail -f /tmp/geth.log        
INFO [02-02|21:18:59] Got interrupt, shutting down... 
INFO [02-02|21:18:59] HTTP endpoint closed: http://0.0.0.0:8545 
INFO [02-02|21:18:59] IPC endpoint closed: /home/neo/.ethereum/geth.ipc 
INFO [02-02|21:18:59] Blockchain manager stopped 
INFO [02-02|21:18:59] Stopping Ethereum protocol 
INFO [02-02|21:18:59] Ethereum protocol stopped 
INFO [02-02|21:18:59] Transaction pool stopped 
INFO [02-02|21:18:59] Database closed                          database=/home/neo/.ethereum/geth/chaindata
INFO [02-02|21:18:59] Mapped network port                      proto=tcp extport=30303 intport=30303 interface="UPNP IGDv1-IP1"
WARN [02-02|21:19:00] Already shutting down, interrupt more to panic. times=9			
			
			

5. JavaScript Console

5.1. personal 管理

5.1.1. 創建賬號

				
> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"				
				
				

指定密碼創建用戶

				
personal.newAccount("123")				
				
				

5.1.2. 列出賬號

列出所有賬號

				
> personal.listAccounts
["0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "0xe8abf98484325fd6afc59b804ac15804b978e607"]				
				
				

列出指定賬號

				
> personal.listAccounts[1]
"0xe8abf98484325fd6afc59b804ac15804b978e607"

> personal.listAccounts[0]
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"				
				
				

5.1.3. 解鎖賬號

				
 > personal.unlockAccount(eth.accounts[0],"password")						
				
				

指定過期時間,單位是毫秒,下面例子是 20 分鐘

				
> personal.unlockAccount(eth.accounts[0],"password", 1000*60*20)				
				
				

5.2. eth 管理

5.2.1. 礦工賬號

查看預設曠工賬號,系統中的第一個賬號。

				
> eth.coinbase
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"				
				
				

查看賬號列表

				
> eth.accounts
["0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "0xe8abf98484325fd6afc59b804ac15804b978e607"]	

> eth.accounts[0]
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"			
				
				

5.2.2. 餘額

				
> eth.getBalance(eth.accounts[0])
70000000000000000000
				
				
5.2.2.1. 單位轉換

eth.getBalance()返回的餘額是以太幣的最小面額wei,將wei轉換為以太幣ether。

					
primary = eth.accounts[0]
balance = web3.fromWei(eth.getBalance(primary), "ether");	
					
					

演示

					
> primary = eth.accounts[0]
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"
> balance = web3.fromWei(eth.getBalance(primary), "ether");
70			
					
					
5.2.2.2. 一次檢查所有賬號餘額

定義函數

					
function checkAllBalances() {
  web3.eth.getAccounts(function(err, accounts) {
   accounts.forEach(function(id) {
    web3.eth.getBalance(id, function(err, balance) {
     console.log("" + id + ":\tbalance: " + web3.fromWei(balance, "ether") + " ether");
   });
  });
 });
};					
					
					

運行函數

					
checkAllBalances()					
					
					

輸出演示

					
> function checkAllBalances() {
...   web3.eth.getAccounts(function(err, accounts) {
.........    accounts.forEach(function(id) {
...............     web3.eth.getBalance(id, function(err, balance) {
.....................      console.log("" + id + ":\tbalance: " + web3.fromWei(balance, "ether") + " ether");
.....................    });
...............   });
.........  });
... };
undefined
> checkAllBalances()
0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6:	balance: 929 ether
0xe8abf98484325fd6afc59b804ac15804b978e607:	balance: 11 ether
undefined					
					
					

5.2.3. 轉賬

				
personal.unlockAccount("0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "", 300)	
eth.sendTransaction({from: '0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6', to: '0xe8abf98484325fd6afc59b804ac15804b978e607', value: web3.toWei(1, "ether")})
				
				
				
預設礦工賬號
				
> eth.coinbase
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"

查看系統中的賬號,如果沒有請參考上面章節創建

> eth.accounts
["0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "0xe8abf98484325fd6afc59b804ac15804b978e607"]

轉出賬號中又 285 個以太幣

> web3.fromWei(eth.getBalance(eth.accounts[0]))
285

轉入賬號目前是 0 

> web3.fromWei(eth.getBalance(eth.accounts[1]))
0

解鎖傳出賬號,否則不能轉出。personal.unlockAccount(賬號, 密碼, 300)

> personal.unlockAccount("0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "", 300)
true

轉賬操作

> eth.sendTransaction({from: '0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6', to: '0xe8abf98484325fd6afc59b804ac15804b978e607', value: web3.toWei(10, "ether")})
"0xb0674a7fee52555d8712f3a1f0f30fbbbf67ff7b5b4b53ab5d131262613215c6"

如果你現在查看轉入賬號,你會發現餘額仍然是 0 ,交易還未成功寫進區塊,寫進區塊的方式是挖礦,所以你必須執行挖礦

> miner.start(1)
null

稍後幾分鐘,再次查看轉入賬號,將會看到有10個以太幣入賬。傳出賬號會減少10個以太幣,同時仍然繼續挖礦中。

> web3.fromWei(eth.getBalance(eth.accounts[1]))
10
				
				

5.2.4. 查看掛起的交易

				
> eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0x5fba50fce50baf0b8a7314200ba46336958ac97e",
    gas: 90000,
    gasPrice: 20000000000,
    hash: "0x51a75422f79fa96e70a0c1481851bc9f827868c44203b68d74f9815ffb367d5f",
    input: "0x",
    nonce: 0,
    r: "0x5632a8ade4a767dbd949ba1042cb33f98dd0722ab999ba18e1454d19d8bd1f6d",
    s: "0x515dcfa3de297f0c956ad9a061a5561f47cc9ccbb0a547cda59193c77fcbe3f7",
    to: "0x0a8c35653d8b229c16f0c9ce6f63cffb877cfdcf",
    transactionIndex: 0,
    v: "0x42",
    value: 1000000000000000000
}]				
				
				

如果返回空值,表示交易全部完成。

				
> eth.pendingTransactions
[]				
				
				

5.2.5. 查看當前區塊總數

				
> eth.blockNumber 
719			
				
				

5.2.6. 查看區塊信息

				
> eth.getBlock(1) 
{
  difficulty: 131072,
  extraData: "0xd783010702846765746885676f312e398777696e646f7773",
  gasLimit: 4995119,
  gasUsed: 0,
  hash: "0x62bc2fc0fd647b43013ba75e65a3f16520cebb60cadc0995965c891d4266a88c",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xba1821227ebad7e88a51078f6219b392fd601822",
  mixHash: "0x80ad2e29d057e0f6bb9d03f12a252fdc65cb520248fa0023ae6624c997b5d5f2",
  nonce: "0x3d743ef28ba8c8c8",
  number: 1,
  parentHash: "0x611596e7979cd4e7ca1531260fa706093a5492ecbdf58f20a39545397e424d04",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 535,
  stateRoot: "0x418d9f66e33cbd41fd524b87c10c5fc75f8a6360896967d827a2d56a0c8aadda",
  timestamp: 1510715249,
  totalDifficulty: 262144,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}
> eth.getBlock(2)
{
  difficulty: 131072,
  extraData: "0xd783010702846765746885676f312e398777696e646f7773",
  gasLimit: 4990242,
  gasUsed: 0,
  hash: "0x3323c566fd3501c29e8b026c4a9d2e83a8dd62d153a32b5f879120e999013d07",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xba1821227ebad7e88a51078f6219b392fd601822",
  mixHash: "0xc415fc64f1bc13842455f8289d33842260c1578a32b5befded5b4293e7a92276",
  nonce: "0x4f4a0e65412663db",
  number: 2,
  parentHash: "0x62bc2fc0fd647b43013ba75e65a3f16520cebb60cadc0995965c891d4266a88c",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 535,
  stateRoot: "0x39ccb22ff5ca19a2340e137fa64acedb704d42827a753780b53a0aff8922e403",
  timestamp: 1510715341,
  totalDifficulty: 393216,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}
				
				
				

5.2.7. 查看智能合約編譯器

				
> eth.compile
{
  lll: function(),
  serpent: function(),
  solidity: function()
}				
				
				

5.3. web3

5.3.1. Ether幣的基本單位

Ether幣最小的單位是Wei,也是命令行預設的單位, 然後每1000個進一個單位,依次是



kwei (1000 Wei)
mwei (1000 KWei)
gwei (1000 mwei)
szabo (1000 gwei)
finney (1000 szabo)
ether (1000 finney)

如何進行ether 和 Wei之間的轉換,簡單地說就是就是1 以太幣 = 1000000000000000000 Wei (這就是上一站章中為何我們轉移0.01個以太幣,結果卻顯示很長的原因)

單位轉換

					
> web3.fromWei(10000000000000000,"ether")
"0.01"				
					
				
5.3.1.1. web3.toWei
						
Ether–> Wei

> web3.toWei(1)
"1000000000000000000"
> web3.toWei(1.3423423)
"1342342300000000000"
> web3.toWei(0.00034)
"340000000000000"						
						
					
5.3.1.2. web3.fromWei
						
Wei –> Ether

> web3.fromWei(10000000000000000)
"0.01"
> web3.fromWei(1000000000000000000)
"1"
>
						
					

5.4. admin 管理

5.4.1. 看看 networkid

				
> admin.nodeInfo.protocols.eth.network
123456				
				
				

5.4.2. 節點管理

可以通過admin.addPeer()方法連接到其他節點,兩個節點要想聯通,必須保證網絡是相通的,並且要指定相同的networkid

提示

注意去掉 --nodiscover 參數

確保網絡可用

				
> net.listening
true
				
				
5.4.2.1. 顯示節點

顯示當前節點信息

					
> admin.nodeInfo
{
  enode: "enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@14.103.209.119:30303",
  id: "9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527",
  ip: "14.103.209.119",
  listenAddr: "[::]:30303",
  name: "Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1",
  ports: {
    discovery: 30303,
    listener: 30303
  },
  protocols: {
    eth: {
      difficulty: 108754979,
      genesis: "0x611596e7979cd4e7ca1531260fa706093a5492ecbdf58f20a39545397e424d04",
      head: "0x61330b27cfbfaecbb36bb8666cbe0564c1e0bdecfdcd153622d8c2ca2b82786e",
      network: 123456
    }
  }
}					
					
					

節點地址

					
> admin.nodeInfo.enode 
"enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@[::]:30303?discport=0"
					
					

[::] 是 ipv6 地址,可以改為 ipv4 地址。

5.4.2.2. 添加節點
					
> admin.addPeer('enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@172.16.0.1:30303')				
					
					
5.4.2.3. 查看節點

查看節點數量

					
> net.peerCount
1					
					
					

查看節點地址

					
> admin.peers
[{
    caps: ["eth/62", "eth/63", "par/1", "par/2", "pip/1"],
    id: "a7bbd8fb72e02681b027908f14fd2dbd80e35a1477d7d9d4dc19ed34420be26fe9f991c83a83e4ab8aa371ffbb149494471f30216bc2f662d1ebc6d01811c7a2",
    name: "Parity/v1.7.12-stable-9b796e8-20180121/x86_64-linux-gnu/rustc1.21.0",
    network: {
      localAddress: "172.16.0.1:34092",
      remoteAddress: "52.67.171.152:30388"
    },
    protocols: {
      eth: "handshake"
    }
}]				
					
					

列出節點IP地址

					
admin.peers.forEach(function(p) {console.log(p.network.remoteAddress);})	
					
					

5.5. miner 挖礦管理

5.5.1. 開始挖礦

				
> miner.start(2)
null			
				
				

過幾分鐘後運行

				
> web3.fromWei(eth.getBalance(eth.coinbase), "ether")
30					
				
				

這時我們已經看到已經產生了30個以太幣。

5.5.2. 停止挖礦

				
> miner.stop()
true
>
				
				

5.5.3. 設置預設礦工賬號

預設挖礦使用系統中的第一個賬號,你可以使用 miner.setEtherbase() 指定賬號。

				
> miner.setEtherbase("0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6")
true	
				
				

				
> eth.accounts
["0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "0xe8abf98484325fd6afc59b804ac15804b978e607", "0x013b5e735e1b48421dd3de3b931d6f03e769e22b"]

> eth.coinbase
"0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6"


> miner.setEtherbase("0xe8abf98484325fd6afc59b804ac15804b978e607")
true

> eth.coinbase
"0xe8abf98484325fd6afc59b804ac15804b978e607"	
				
				

5.6. txpool 管理

5.6.1. txpool.status

查看狀態

				
> txpool.status 
{
  pending: 0,
  queued: 0
}
				
				

例如做一筆轉賬

				
> amount = web3.toWei(5,'ether')  
"5000000000000000000"  
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})	

> txpool.status 
{
  pending: 1,
  queued: 0
}

> miner.start(1);admin.sleepBlocks(1);miner.stop(); 

> txpool.status 
{
  pending: 0,
  queued: 0
}

> web3.fromWei(eth.getBalance(eth.accounts[1]),'ether')  
5  
				
				

5.7. net

5.7.1. 監聽狀態

				
> net.listening
true
				
				

6. Ethereum Wallet(Mist)

開始學習以太坊時閲讀大量文章常常會提到 Mist 一頭霧水,後來才知道 Mist 就是 Ethereum Wallet。 Ethereum Wallet 是軟件名字, Mist 是項目名字。

Ethereum Wallet 可以在以太坊首頁下載,如果你需要安裝歷史版本可以訪問 https://github.com/ethereum/mist/releases

7. 總結

7.1. 單機多實例演示

在沒有條件安裝虛擬機也沒有多台伺服器的情況下我們可以使用一台伺服器運行多個實例的方法也可以實現多個節點運行環境。

			
cd ~
mkdir -p ethereum
cd ethereum
mkdir data{1,2}
			
			

創建檔案 genesis.json

			
{
  "nonce": "0x0000000000000042",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  "gasLimit": "0x4c4b40",
  "config": {
      "chainId": 15,
      "homesteadBlock": 0,
      "eip155Block": 0,
      "eip158Block": 0
  },
  "alloc": { }
}			
			
			

7.1.1. 實例一

				
geth --datadir ~/ethereum/data1 init genesis.json
geth --datadir="~/ethereum/data1" --networkid 123456 --port 30301 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" --rpcport 8541		
				
				

啟動後終端輸出

				
neo@netkiller ~/ethereum % geth --datadir ~/ethereum/data1 init genesis.json
WARN [02-02|22:09:56] No etherbase set and no accounts found as default 
INFO [02-02|22:09:56] Allocated cache and file handles         database=/home/neo/ethereum/data1/geth/chaindata cache=16 handles=16
INFO [02-02|22:09:56] Writing custom genesis block 
INFO [02-02|22:09:56] Successfully wrote genesis state         database=chaindata                               hash=611596…424d04
INFO [02-02|22:09:56] Allocated cache and file handles         database=/home/neo/ethereum/data1/geth/lightchaindata cache=16 handles=16
INFO [02-02|22:09:57] Writing custom genesis block 
INFO [02-02|22:09:57] Successfully wrote genesis state         database=lightchaindata                               hash=611596…424d04

neo@netkiller ~ % geth --datadir="~/ethereum/data1" --networkid 123456 --port 30301 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" -rpcport 8541             
WARN [02-02|22:36:02] No etherbase set and no accounts found as default 
INFO [02-02|22:36:02] Starting peer-to-peer node               instance=Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
INFO [02-02|22:36:02] Allocated cache and file handles         database=/home/neo/ethereum/data1/geth/chaindata cache=128 handles=1024
INFO [02-02|22:36:02] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Engine: unknown}"
INFO [02-02|22:36:02] Disk storage enabled for ethash caches   dir=/home/neo/ethereum/data1/geth/ethash count=3
INFO [02-02|22:36:02] Disk storage enabled for ethash DAGs     dir=/home/neo/.ethash                    count=2
INFO [02-02|22:36:02] Initialising Ethereum protocol           versions="[63 62]" network=123456
INFO [02-02|22:36:02] Loaded most recent local header          number=0 hash=611596…424d04 td=131072
INFO [02-02|22:36:02] Loaded most recent local full block      number=0 hash=611596…424d04 td=131072
INFO [02-02|22:36:02] Loaded most recent local fast block      number=0 hash=611596…424d04 td=131072
INFO [02-02|22:36:02] Loaded local transaction journal         transactions=0 dropped=0
INFO [02-02|22:36:02] Regenerated local transaction journal    transactions=0 accounts=0
INFO [02-02|22:36:02] Starting P2P networking 
INFO [02-02|22:36:05] UDP listener up                          self=enode://53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062@14.103.209.119:30301
INFO [02-02|22:36:05] HTTP endpoint opened: http://0.0.0.0:8541 
INFO [02-02|22:36:05] IPC endpoint opened: /home/neo/ethereum/data1/geth.ipc 
INFO [02-02|22:36:05] RLPx listener up                         self=enode://53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062@14.103.209.119:30301
INFO [02-02|22:36:05] Mapped network port                      proto=udp extport=30301 intport=30301 interface="UPNP IGDv1-IP1"
INFO [02-02|22:36:07] Mapped network port                      proto=tcp extport=30301 intport=30301 interface="UPNP IGDv1-IP1"
				
				

7.1.2. 實例二

				
geth --datadir ~/ethereum/data2 init genesis.json
geth --datadir="~/ethereum/data2" --networkid 123456 --port 30302 --rpc --rpcaddr="0.0.0.0" --rpccorsdomain "*" --rpcport 8542		
				
				

啟動後控制台輸出與實例一類似

7.1.3. 添加節點

開啟一個新終端窗口,運行下面命令查看節點一的 enode 字元串

				
geth --exec 'admin.nodeInfo.enode' attach ethereum/data1/geth.ipc
"enode://53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062@[::]:30301?discport=0"				
				
				

進入節點二,並連接到節點一。

				
neo@netkiller ~ % geth attach ethereum/data2/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> admin.addPeer("enode://53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062@[::]:30302")
true
> admin.addPeer("enode://53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062@[::]:30301")
true



				
				

查看節點

				
> admin.peers
[{
    caps: ["eth/63"],
    id: "53433417f11d1d9a17f155cbaad2c4ec375af7b141e2989f049b572fc3f856d78f254e58fa82ed6eab48a16b7d625527214522ec0fd3e3af030b5b8dfdadc062",
    name: "Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1",
    network: {
      localAddress: "[::1]:51250",
      remoteAddress: "[::1]:30301"
    },
    protocols: {
      eth: {
        difficulty: 131072,
        head: "0x611596e7979cd4e7ca1531260fa706093a5492ecbdf58f20a39545397e424d04",
        version: 63
      }
    }
}]
				
				

至此,節點已經添加完畢。

				
> exit				
				
				

退出

7.1.4. 節點測試

這裡我們實現兩個節點間的以太幣轉賬。

現在兩個節點上都沒有任何賬號

				
neo@netkiller ~ % geth --exec 'personal.listAccounts' attach ethereum/data1/geth.ipc                                        
[]
neo@netkiller ~ % geth --exec 'personal.listAccounts' attach ethereum/data2/geth.ipc
[]
				
				

在兩個節點上分別創建兩個賬號,一個是礦工賬號,另一個是普通賬號。

				
neo@netkiller ~ % geth --exec 'personal.newAccount("abc123")' attach ethereum/data1/geth.ipc
"0x5ad227e8d7e460713c78eebbe558473571edae72"

neo@netkiller ~ % geth --exec 'personal.newAccount("abc123")' attach ethereum/data1/geth.ipc
"0x3e822e05ee975e02be3f15f32b0fddced8d5bdd0"

neo@netkiller ~ % geth --exec 'personal.listAccounts' attach ethereum/data1/geth.ipc 
["0x5ad227e8d7e460713c78eebbe558473571edae72", "0x3e822e05ee975e02be3f15f32b0fddced8d5bdd0"]



neo@netkiller ~ % geth --exec 'personal.newAccount("abc123")' attach ethereum/data2/geth.ipc
"0xa6df3e3c141e27726f4aeb21a5dab2e5c76c9565"

neo@netkiller ~ % geth --exec 'personal.newAccount("abc123")' attach ethereum/data2/geth.ipc
"0xa66c7b8b1c26856d284a0b962385babe02caa51d"

neo@netkiller ~ % geth --exec 'personal.listAccounts' attach ethereum/data2/geth.ipc 
["0xa6df3e3c141e27726f4aeb21a5dab2e5c76c9565", "0xa66c7b8b1c26856d284a0b962385babe02caa51d"]
				
				

啟動挖礦

				
geth --exec 'miner.start(1)' attach ethereum/data1/geth.ipc 
geth --exec 'miner.start(1)' attach ethereum/data2/geth.ipc 
				
				

如果正常運行,兩個節點上的礦工賬號都會有一定的以太幣。而普通賬號額度應該為零。

				
neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[0])' attach ethereum/data1/geth.ipc
299438256000000000000

neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data1/geth.ipc
0

neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data1/geth.ipc
298000056000000000000

neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data2/geth.ipc
0				
				
				

我們嘗試從節點一礦工賬號向節點二上的普通用戶轉賬。

				
neo@netkiller ~ % geth attach ethereum/data1/geth.ipc                               
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0x5ad227e8d7e460713c78eebbe558473571edae72
at block: 144 (Fri, 02 Feb 2018 23:24:35 HST)
 datadir: /home/neo/ethereum/data1
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> personal.listAccounts
["0x5ad227e8d7e460713c78eebbe558473571edae72"]

> personal.unlockAccount(eth.accounts[0], "abc123")
true

> eth.sendTransaction({from: "0x5ad227e8d7e460713c78eebbe558473571edae72", to: "0xa66c7b8b1c26856d284a0b962385babe02caa51d", value: web3.toWei(1, "ether")})
"0x87c059d0769c8a74499ddd08c04a10f23b7681651615a28098d73ec63a943684"

> eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0x5ad227e8d7e460713c78eebbe558473571edae72",
    gas: 90000,
    gasPrice: 18000000000,
    hash: "0x87c059d0769c8a74499ddd08c04a10f23b7681651615a28098d73ec63a943684",
    input: "0x",
    nonce: 2,
    r: "0xce004f964f268a00e90cadd4e8a685131aa34f37144f7e2e47dc7fe4ec784e55",
    s: "0x412209c18513a28422e62c4bdb85a223f190e133cf71990a87c570a3a53ae093",
    to: "0xa66c7b8b1c26856d284a0b962385babe02caa51d",
    transactionIndex: 0,
    v: "0x41",
    value: 1000000000000000000
}]
				
				

稍後一會,當使用 eth.pendingTransactions 查看掛起交易為空的時候,表示已經處理完畢。這時退出控制台。

				
> eth.pendingTransactions
[]
> exit				
				
				

現在查看節點二上的第二個普通賬號餘額

				
neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data2/geth.ipc
1000000000000000000
				
				

轉賬成功

現在我們從節點二上的普通用戶向節點一上的普通用戶轉賬。

				
neo@netkiller ~ % geth attach ethereum/data2/geth.ipc                                        
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0xa6df3e3c141e27726f4aeb21a5dab2e5c76c9565
at block: 319 (Fri, 02 Feb 2018 23:50:07 HST)
 datadir: /home/neo/ethereum/data2
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> personal.unlockAccount(eth.accounts[1], "abc123")
true

> eth.sendTransaction({from: "0xa66c7b8b1c26856d284a0b962385babe02caa51d", to: "0x3e822e05ee975e02be3f15f32b0fddced8d5bdd0", value: web3.toWei(0.1, "ether")})
"0x951bd161dfd000ff825379cb0644c4acd4afd4d3e1ac4f4c1c6009b3c2a1d366"

> eth.pendingTransactions
[]
> exit		
				
				

查看兩個普通賬號的餘額

				
neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data1/geth.ipc
100000000000000000
neo@netkiller ~ % geth --exec 'eth.getBalance(eth.accounts[1])' attach ethereum/data2/geth.ipc
899622000000000000
				
				

8. FAQ

8.1. Error: authentication needed: password or unlock

			
> eth.sendTransaction({from: '0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6', to: '0xe8abf98484325fd6afc59b804ac15804b978e607', value: web3.toWei(1, "ether")})
Error: authentication needed: password or unlock
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at <anonymous>:1:1			
			
			

解鎖轉出賬號

			
> personal.unlockAccount("0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6", "your_password", 300)
true
> eth.sendTransaction({from: '0x83fda0ba7e6cfa8d7319d78fa0e6b753a2bcb5a6', to: '0xe8abf98484325fd6afc59b804ac15804b978e607', value: web3.toWei(1, "ether")})
"0xd9e8c8fdc71e24ee8052048de4ff0acd7157b872393f37344c8ec2083f3fe48f"			
			
			

8.2. 新增節點後不生效

新增節點顯示 true ,但是使用 admin.peers 查看不到。

			
> admin.addPeer("enode://c4586276391b3c88ec23889d1bc825d0c7d69bd5765d4545686f835608068b8dc48799d2686a04ea0f9e17aed099bf9b56935679fa6493e9b17151624a320714@172.16.0.17:30303")
true
> admin.peers
[]			
			
			

查看節點,如果發現 ip: "::" 同時 discovery: 0

			
> admin.nodeInfo
{
  enode: "enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@[::]:30303?discport=0",
  id: "9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527",
  ip: "::",
  listenAddr: "[::]:30303",
  name: "Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1",
  ports: {
    discovery: 0,
    listener: 30303
  },
  protocols: {
    eth: {
      difficulty: 131072,
      genesis: "0x611596e7979cd4e7ca1531260fa706093a5492ecbdf58f20a39545397e424d04",
      head: "0x611596e7979cd4e7ca1531260fa706093a5492ecbdf58f20a39545397e424d04",
      network: 123456
    }
  }
}
> 
			
			

解決方案啟動時可能增加了 --nodiscover 參數,去掉參數後可以解決。

有三種方法新增節點

第一種,啟動指定

			
geth --bootnodes enode://pubkey1@ip1:port1,enode://pubkey2@ip2:port2,enode://pubkey3@ip3:port3
			
			

第二種,在控制台中添加

			
> admin.addPeer('enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@172.16.0.1:30303')				
			
			

第三種,在檔案 ~/.ethereum/geth/static-nodes.json 中添加節點數據

			
[
  "enode://9f6490ffb5236f2ddc5710ae73d47c740e0a3644bbd2d67029cf4a6c4693d2f470b642fd2cc3507f7e851df60aaeb730a1270b7a477f91ec5b6b17a8a4b40527@172.16.0.17:30303",
  "enode://pubkey@ip:port"
]
			
			

這個檔案內容是一個數組,類似 ["","",""] 。