第二節中瞭解了使用geth搭建以太坊私有網絡,這一次則要在私有網絡中創建多個node組成的集羣,並互相發現,產生交易.node
爲了在本地網絡運行多個以太坊節點的實例,必須確保一下幾點:
1. 每一個實例都有獨立的數據目錄(--datadir)
2. 每一個實例運行都有獨立的端口.(eth和rpc二者都是)(--port 和 --rpcprot)
3. 在集羣的狀況下, 實例之間都必需要知道彼此.
4. 惟一的ipc通訊端點,或者禁用ipc.
啓動第一個節點(指定端口,並禁用ipc),運行命令和結果以下:linux
~/Documents/private-geth geth --datadir ./data/00 --networkid 314590 --ipcdisable --port 61910 --rpcport 8200 console
INFO [05-29|16:18:59] Starting peer-to-peer node instance=Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
INFO [05-29|16:18:59] Allocated cache and file handles database=/home/zl/Documents/private-geth/data/00/geth/chaindata cache=128 handles=1024
INFO [05-29|16:18:59] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Engine: unknown}"
INFO [05-29|16:18:59] Disk storage enabled for ethash caches dir=/home/zl/Documents/private-geth/data/00/geth/ethash count=3
INFO [05-29|16:18:59] Disk storage enabled for ethash DAGs dir=/home/zl/.ethash count=2
INFO [05-29|16:18:59] Initialising Ethereum protocol versions="[63 62]" network=314590
INFO [05-29|16:18:59] Loaded most recent local header number=29 hash=8ff3ff…dac4a2 td=7372364
INFO [05-29|16:18:59] Loaded most recent local full block number=29 hash=8ff3ff…dac4a2 td=7372364
INFO [05-29|16:18:59] Loaded most recent local fast block number=29 hash=8ff3ff…dac4a2 td=7372364
WARN [05-29|16:18:59] Blockchain not empty, fast sync disabled
INFO [05-29|16:18:59] Starting P2P networking
INFO [05-29|16:19:01] Mapped network port proto=udp extport=61910 intport=61910 interface="UPNP IGDv1-IP1"
INFO [05-29|16:19:02] RLPx listener up self=enode://ad307e052d0e04af519b8999fa870800df8a7a0cc2a91e6aea30e879b75c344dfa12c773a63a71677c2a3ea1254cf982815817f7ff58bd79e5837ea44d791a2d@192.168.1.2:61910
INFO [05-29|16:19:02] Mapped network port proto=tcp extport=61910 intport=61910 interface="UPNP IGDv1-IP1"
Welcome to the Geth JavaScript console!
instance: Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
coinbase: 0x5fba50fce50baf0b8a7314200ba46336958ac97e
at block: 29 (Mon, 29 May 2017 13:13:46 CST)
datadir: /home/zl/Documents/private-geth/data/00
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
上面的命令以命令行的(console)的方式啓動了節點, 因此咱們能夠經過繼續輸入下面的命令獲取節點實例的enode url:git
>admin.nodeInfo.enode
"enode://ad307e052d0e04af519b8999fa870800df8a7a0cc2a91e6aea30e879b75c344dfa12c773a63a71677c2a3ea1254cf982815817f7ff58bd79e5837ea44d791a2d@192.168.1.2:61910"
>
###########################獲取本機IP地址###########################github
$ ifconfig|grep netmask|awk '{print $2}'
127.0.0.1
192.168.1.102
###########################
再打開一個終端,初始化第二個節點:web
geth --datadir ./data/01 init ./genesis.json
啓動第二個節點:json
~/Documents/private-geth geth --datadir ./data/01 --networkid 314590 --ipcdisable --port 61911 --rpcport 8101 --bootnodes "enode://ad307e052d0e04af519b8999fa870800df8a7a0cc2a91e6aea30e879b75c344dfa12c773a63a71677c2a3ea1254cf982815817f7ff58bd79e5837ea44d791a2d@192.168.1.2:61910" console
INFO [05-29|18:42:15] Starting peer-to-peer node instance=Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
INFO [05-29|18:42:15] Allocated cache and file handles database=/home/zl/Documents/private-geth/data/01/geth/chaindata cache=128 handles=1024
INFO [05-29|18:42:15] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO: DAOSupport: false EIP150: EIP155: 0 EIP158: 0 Engine: unknown}"
INFO [05-29|18:42:15] Disk storage enabled for ethash caches dir=/home/zl/Documents/private-geth/data/01/geth/ethash count=3
INFO [05-29|18:42:15] Disk storage enabled for ethash DAGs dir=/home/zl/.ethash count=2
INFO [05-29|18:42:15] Initialising Ethereum protocol versions="[63 62]" network=314590
INFO [05-29|18:42:15] Loaded most recent local header number=36 hash=e1541c…418ce3 td=8938686
INFO [05-29|18:42:15] Loaded most recent local full block number=36 hash=e1541c…418ce3 td=8938686
INFO [05-29|18:42:15] Loaded most recent local fast block number=36 hash=e1541c…418ce3 td=8938686
WARN [05-29|18:42:15] Blockchain not empty, fast sync disabled
INFO [05-29|18:42:15] Starting P2P networking
INFO [05-29|18:42:17] Mapped network port proto=udp extport=61911 intport=61911 interface="UPNP IGDv1-IP1"
INFO [05-29|18:42:17] RLPx listener up self=enode://2261c433ed5d12924f727b61bf4084f22f4199b430115827c8eae3bb210c0dd5b3dd7df8dc13d8ca80c80f4a36e25c7bc7737737001d0b09324ee43ca6b9d7f8@192.168.1.2:61911
INFO [05-29|18:42:17] Mapped network port proto=tcp extport=61911 intport=61911 interface="UPNP IGDv1-IP1"
Welcome to the Geth JavaScript console!
instance: Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1
coinbase: 0x0a8c35653d8b229c16f0c9ce6f63cffb877cfdcf
at block: 36 (Mon, 29 May 2017 18:30:22 CST)
datadir: /home/zl/Documents/private-geth/data/01
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
上面的命令中,--bootndoes 是設置當前節點啓動後,直接經過設置--bootndoes 的值來連接第一個節點, --bootnoedes 的值能夠經過在第一個節的命令行中,輸入:admin.nodeInfo.enode命令打印出來.
也能夠不設置 --bootnodes, 直接啓動,啓動後進入命令行, 經過命令admin.addPeer(enodeUrlOfFirst Instance)把它做爲一個peer添加進來.
爲了確認連接成功,第二個節點輸入: bash
> admin.nodeInfo
{
enode: "enode://2261c433ed5d12924f727b61bf4084f22f4199b430115827c8eae3bb210c0dd5b3dd7df8dc13d8ca80c80f4a36e25c7bc7737737001d0b09324ee43ca6b9d7f8@192.168.1.2:61911",
id: "2261c433ed5d12924f727b61bf4084f22f4199b430115827c8eae3bb210c0dd5b3dd7df8dc13d8ca80c80f4a36e25c7bc7737737001d0b09324ee43ca6b9d7f8",
ip: "192.168.1.2",
listenAddr: "[::]:61911",
name: "Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1",
ports: {
discovery: 61911,
listener: 61911
},
protocols: {
eth: {
difficulty: 8938686,
genesis: "0xa0e580c6769ac3dd80894b2a256164a76b796839d2eb7f799ef6b9850ea5e82e",
head: "0xe1541cc54dbcade54fb61053ffa71391c44bb6655cf9619635263960bc418ce3",
network: 314590
}
}
}
>
第一個節點輸入:網絡
> net.peerCount
1
> admin.peers
[{
caps: ["eth/62", "eth/63"],
id: "2261c433ed5d12924f727b61bf4084f22f4199b430115827c8eae3bb210c0dd5b3dd7df8dc13d8ca80c80f4a36e25c7bc7737737001d0b09324ee43ca6b9d7f8",
name: "Geth/v1.6.1-stable-021c3c28/linux-amd64/go1.8.1",
network: {
localAddress: "192.168.0.103:61910",
remoteAddress: "192.168.1.2:41912"
},
protocols: {
eth: {
difficulty: 8938686,
head: "0xe1541cc54dbcade54fb61053ffa71391c44bb6655cf9619635263960bc418ce3",
version: 63
}
}
}]
>
從獲得的結果能夠看出,第一個節點有1個peer連接, 連接的node id爲:
"2261c433ed5d12924f727b61bf4084f22f4199b430115827c8eae3bb210c0dd5b3dd7df8dc13d8ca80c80f4a36e25c7bc7737737001d0b09324ee43ca6b9d7f8"
這個id,正好就是第二個節點的id.
按照這樣的方式繼續擴展,能夠很是容易就能夠創建本地節點集羣.這些工做均可以寫成腳本代碼來完成, 裏面還能夠包含建立帳戶,挖礦等..
請參考:https://github.com/ethersphere/eth-utils下的gethcluster.sh腳本,以及README中的使用方法和示例.
連接成功後,使用咱們在上一篇文章中挖礦的帳戶,向第二個節點發送 "ether"(以太幣的貨幣單位,還有一種叫"Wei",基本上這些貨幣單位都是用一些牛逼的人的名字來命名的).
首先查看第二個節點的Wei數量和整個網絡的區塊號,還有接收貨幣的帳號id:app
> eth.getBalance(eth.accounts[0])
0000000000000000000
> eth.blockNumber
30
> eth.accounts[0]
"0x0a8c35653d8b229c16f0c9ce6f63cffb877cfdcf"
>
在第一個節點命令行中,執行下面的操做:tcp
> personal.unlockAccount(eth.accounts[0], "ko2005")
true
> eth.sendTransaction({from: "0x5fba50fce50baf0b8a7314200ba46336958ac97e", to: "0x0a8c35653d8b229c16f0c9ce6f63cffb877cfdcf", value: web3.toWei(1, "ether")})
INFO [05-29|17:33:42] Submitted transaction fullhash=0x51a75422f79fa96e70a0c1481851bc9f827868c44203b68d74f9815ffb367d5f recipient=0x0a8c35653d8b229c16f0c9ce6f63cffb877cfdcf
"0x51a75422f79fa96e70a0c1481851bc9f827868c44203b68d74f9815ffb367d5f"
> 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.sendTransaction就是執行發送以太幣的操做, 參數from, to分別是發送帳戶和接收帳戶, web3.toWei(1, "ether")是將1單位"ether"轉換爲相應的"Wei"數量.
而後執行挖礦(這裏我也不理解,爲何發送貨幣之後,要經過挖礦才能讓交易生效)
> miner.start()
INFO [05-29|18:26:47] Updated mining threads threads=0
INFO [05-29|18:26:47] Starting mining operation
null
> INFO [05-29|18:26:47] Commit new mining work number=31 txs=1 uncles=0 elapsed=1.094ms
> INFO [05-29|18:30:14] Successfully sealed new block number=31 hash=19e3d7…a6ecd5
INFO [05-29|18:30:14] 🔨 mined potential block number=31 hash=19e3d7…a6ecd5
INFO [05-29|18:30:14] Commit new mining work number=32 txs=0 uncles=0 elapsed=2.314ms
INFO [05-29|18:30:17] Successfully sealed new block number=32 hash=94748a…cdbc17
INFO [05-29|18:30:17] 🔨 mined potential block number=32 hash=94748a…cdbc17
INFO [05-29|18:30:17] Commit new mining work number=33 txs=0 uncles=0 elapsed=156.295µs
INFO [05-29|18:30:19] Successfully sealed new block number=33 hash=b8e037…cd50ff
INFO [05-29|18:30:19] 🔨 mined potential block number=33 hash=b8e037…cd50ff
INFO [05-29|18:30:19] Commit new mining work number=34 txs=0 uncles=0 elapsed=131.676µs
> mINFO [05-29|18:30:20] Successfully sealed new block number=34 hash=7ad61a…f63067
INFO [05-29|18:30:20] 🔨 mined potential block number=34 hash=7ad61a…f63067
INFO [05-29|18:30:20] Commit new mining work number=35 txs=0 uncles=0 elapsed=138.957µs
> miner.stINFO [05-29|18:30:22] Successfully sealed new block number=35 hash=eb9652…a1a9e3
INFO [05-29|18:30:22] 🔨 mined potential block number=35 hash=eb9652…a1a9e3
INFO [05-29|18:30:22] Commit new mining work number=36 txs=0 uncles=0 elapsed=334.318µs
> miner.stopINFO [05-29|18:30:22] Successfully sealed new block number=36 hash=e1541c…418ce3
INFO [05-29|18:30:22] 🔗 block reached canonical chain number=31 hash=19e3d7…a6ecd5
INFO [05-29|18:30:22] 🔨 mined potential block number=36 hash=e1541c…418ce3
INFO [05-29|18:30:22] Commit new mining work number=37 txs=0 uncles=0 elapsed=117.185µs
> miner.stop()
true
>
從上面的日誌能夠看到,執行挖礦以後,一共有6個區塊產生.
再在第二個節點的命令行輸入:
> eth.blockNumber
36
> eth.getBalance(eth.accounts[0])
1000000000000000000
能夠看到第二個節點中的帳戶,已經得有了1個"ether", 而且能夠看出,以太坊中,1"ether"=1000000000000000000"Wei.
以前輸入eth.blockNumber,獲得的值爲30,其實只要挖出第一個區塊的時候,就能夠中止,發送到第二個node帳戶中的一個"ether",就已經生效.
總結一下:
此次以咱們完成了如下內容:
1)建立區塊鏈私有網絡,並在網絡中,創建本身的節點集羣.
2)在接點集羣中,經過一個節點的帳戶向網絡中的另一個節點的帳戶轉了1個以太坊幣,交易成功.
下一次,咱們將開始使用truffle,寫一個以太坊的"Hello World",正式進入區塊鏈的開發.
另外說一下,
本人也是區塊鏈新手,一邊學習,一邊把學習的過程記錄下來向你們分享,中間走了很是多的彎路,
耗費了大量時間, 文章主要是把本身的學習經驗分享出來,一個是本身能夠鞏固,另外能夠幫助你們,避免你們和我同樣走不少彎路.
若是文章中有寫得不對的,或者有更好的方法,還請各位大神批評指正.