區塊鏈入門(3):在以太坊私有網絡中創建節點集羣,併發生交易

第二節中瞭解了使用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",正式進入區塊鏈的開發.

另外說一下,
本人也是區塊鏈新手,一邊學習,一邊把學習的過程記錄下來向你們分享,中間走了很是多的彎路,
耗費了大量時間, 文章主要是把本身的學習經驗分享出來,一個是本身能夠鞏固,另外能夠幫助你們,避免你們和我同樣走不少彎路.
若是文章中有寫得不對的,或者有更好的方法,還請各位大神批評指正.

相關文章
相關標籤/搜索