Ubuntu下Geth客户端搭建私有网络集群

本篇博客主要介绍一下在一台机器上建立多个节点,并且把节点连接在一起形成一个集群的方法笔记,以及配置时遇到的一些问题。 
本文基于Ubuntu14.04 和 Geth 1.4.5-stable

建立一个私有节点时常用参数:

--nodiscover 使用这个参数,你的节点就不会被其他人发现,除非手动添加你的节点。否则,就只有一个被无意添加到一个陌生区块链上的可能,那就是跟你有相同的genesis文件和networkID。
--maxpeers 0 如果你不想有人连上你的测试链,就用maxpeers 0。或者,你可以调整参数,当你确切的知道有几个节点要连接上来的时候。
--rpc 允许RPC操作你的节点。这个参数在Geth上是默认的。
--rpcapi "db,eth,net,web3" 这个命令指示了允许通过RPC访问的命令。默认情况下,Geth允许web3。
--rpcport "8080"
--rpccorsdomain "http://chriseth.github.io/browser-solidity/"
--datadir "/home/etherTest" 私有链存放路径(最好跟公有链路径不同)
--port "30303" 网络监听端口,用来和其他节点手动连接
--identity “yooliee" 用来标识你的节点的,方便在一大群节点中识别出自己的节点
--networkid 1990 你自己的私有网络的id号
--rpccorsdomain "http://chriseth.github.io/browser-solidity/" 指定可以远程访问你的节点的URL, 值为"*"时是指任何地方都可以远程访问(避免使用*)

本地建立多个节点

为了能在本地建立多个节点,你必须确保:

  • 每个节点所在路径不同(–datadir的值不同)
  • 每个节点运行在不同的端口上(包括eth和rpc) (–port和–rpcport不同)
  • ipc端点是唯一的或者禁用ipc接口(–ipcpath唯一或者–ipcdisable

为了建立一个本地集群,除了上面几个参数值不同以外,必须确保–networkid相同,即节点是属于同一个网络;创世区块相同、集群中的节点必须知道彼此。本测试建立三个节点,然后三个节点彼此相连,形成一个集群。

首先,建立一个文件夹,用来存放三个节点:

mkdir ether

所有节点的genesis.json文件必须相同:

{
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x0",
  "gasLimit": "0x80000000",
  "difficulty": "0x1",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {     }
}

建立第一个节点:

# 在ether目录下创建第一个目录,然后把上面的genesis.json文件复制到此目录下
$ cd ether
$ mkdir 01 && cd 01
# 用genesis.json生成创世区块
$ geth --datadir ~/ether/01 init genesis.json
# 此时01目录中生成了chaindata目录,里面就是存放区块链数据的地方
# 启动第一个节点
$ geth --identity "test" --rpc --rpccorsdomain "*" --datadir ~/ether/01 --port "30301" --nodiscover --rpcport 8101 --rpcapi "db,eth,net,web3" --networkid 1998 console 2>> ~/ether/01/geth.log

此时第一个节点启动成功了,可以通过eth.getBlock(0),查看创世区块信息,如下:

> eth.getBlock(0)
{
  difficulty: 1,
  extraData: "0x00",
  gasLimit: 2147483648,
  gasUsed: 0,
  hash: "0x6099b65e564bd511f49e8f39ba27b6a68b6b78fd1481592257f06bbf93abe624",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x3333333333333333333333333333333333333333",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 505,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 1,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

通过admin.nodeInfo查看此节点的节点信息:

> admin.nodeInfo
{
  enode: "enode://2f86dbb18242371fa0a8e7098cb13a012ad9d8ee80f0bbba94a798b16d3c6c3c247d3e333b8da27a591b38365f927a25359376d4bf38575bb0371a1365294f91@[::]:30301?discport=0",
  id: "2f86dbb18242371fa0a8e7098cb13a012ad9d8ee80f0bbba94a798b16d3c6c3c247d3e333b8da27a591b38365f927a25359376d4bf38575bb0371a1365294f91",
  ip: "::",
  listenAddr: "[::]:30301",
  name: "Geth/v1.4.5-stable-a269a713/linux/go1.4.2/test",
  ports: {
    discovery: 0,
    listener: 30301
  },
  protocols: {
    eth: {
      difficulty: 13919423,
      genesis: "0x6099b65e564bd511f49e8f39ba27b6a68b6b78fd1481592257f06bbf93abe624",
      head: "0xdf1d69ee935ac6091eecf8a0f495f9dcdb644445feb265ea11f961ff9f5b45b5",
      network: 1998
    }
  }
}

当连接同一个网络中的其他节点时,使用的就是上面的第一个字段enode的值,注意一下。

建立第二个节点

# 在ether目录下创建第二个目录,然后把上面的genesis.json文件复制到此目录下
$ cd ether
$ mkdir 02 && cd 02
# 用genesis.json生成创世区块
$ geth --datadir ~/ether/02 init genesis.json
# 此时02目录中生成了chaindata目录,里面就是存放区块链数据的地方
# 启动第二个节点
$ geth --identity "test" --rpc --rpccorsdomain "*" --datadir ~/ether/02 --port "30302" --nodiscover --rpcport 8102 --rpcapi "db,eth,net,web3" --networkid 1998 console 2>> ~/ether/02/geth.log

同样,第二个节点成功启动,可以通过eth.getBlock(0)查看区块信息:

> eth.getBlock(0)
{
  difficulty: 1,
  extraData: "0x00",
  gasLimit: 2147483648,
  gasUsed: 0,
  hash: "0x6099b65e564bd511f49e8f39ba27b6a68b6b78fd1481592257f06bbf93abe624",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x3333333333333333333333333333333333333333",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 505,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 1,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

可以发现,02下的创世区块信息和01下的创世区块信息完全一样,因为是由同一个genesis.json生成,同一个网络中的创世区块也必须相同。

现在,已经创建好了两个节点,但是它们都还不知道彼此,两个节点是相对独立的存在。接下来,我们把两个节点连接起来:

# 在02节点的控制台里通过admin.addPeer(enodeUrlOfFirstInstance)添加第一个节点的信息,使节点1和节点2相连。
>admin.addPeer("enode://2f86dbb18242371fa0a8e7098cb13a012ad9d8ee80f0bbba94a798b16d3c6c3c247d3e333b8da27a591b38365f927a25359376d4bf38575bb0371a1365294f91@[::]:30301?discport=0")
> net.peerCount  #检测有没有连接的节点
1
> admin.peers   #查看连在02节点上的节点信息,可以看见id就是之前的01节点的id
[{
    caps: ["eth/61", "eth/62", "eth/63"],
    id: "2f86dbb18242371fa0a8e7098cb13a012ad9d8ee80f0bbba94a798b16d3c6c3c247d3e333b8da27a591b38365f927a25359376d4bf38575bb0371a1365294f91",
    name: "Geth/v1.4.5-stable-a269a713/linux/go1.4.2/test",
    network: {
      localAddress: "[::1]:36114",
      remoteAddress: "[::1]:30301"
    },
    protocols: {
      eth: {
        difficulty: 13919423,
        head: "df1d69ee935ac6091eecf8a0f495f9dcdb644445feb265ea11f961ff9f5b45b5",
        version: 63
      }
    }
}]

同理,创建第三个节点

# 在ether目录下创建第三个目录,然后把上面的genesis.json文件复制到此目录下
$ cd ether
$ mkdir 03 && cd 03
# 用genesis.json生成创世区块
$ geth --datadir ~/ether/03 init genesis.json
# 此时03目录中生成了chaindata目录,里面就是存放区块链数据的地方
# 启动第三个节点
$ geth --identity "test" --rpc --rpccorsdomain "*" --datadir ~/ether/03 --port "30303" --nodiscover --rpcport 8103 --rpcapi "db,eth,net,web3" --networkid 1998 console 2>> ~/ether/03/geth.log

然后在启动的控制台里面添加第一个节点:

> admin.addPeer("enode://2f86dbb18242371fa0a8e7098cb13a012ad9d8ee80f0bbba94a798b16d3c6c3c247d3e333b8da27a591b38365f927a25359376d4bf38575bb0371a1365294f91@[::]:30301?discport=0")
true
> net.peerCount
1

此时03节点添加了01节点,02节点添加了01节点,在01控制台中输入:

> net.peerCount
2

可以看见01节点现在有两个节点跟它相连。现在,三个节点相连,形成了一个小的集群,任意一个节点挖矿,挖到区块之后,都会同步到其他的两个节点。

以上是正确配置集群时用的方法,如果genesis.json文件不相同或者networkid不相同时,都不能添加成功。genesis.json不同,将会生成不一样的创世区块,networkid不同就是两个不同的网络,自然就不能添加成功。

你可能感兴趣的:(区块链技术)