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

来源:互联网 发布:域名后缀的区别 编辑:程序博客网 时间:2024/06/06 06:38

本篇博客主要介绍一下在一台机器上建立多个节点,并且把节点连接在一起形成一个集群的方法笔记,以及配置时遇到的一些问题。
本文基于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.peerCount1

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

> net.peerCount2

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

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

在一台电脑上创建多个节点,然后把多个节点连接起来形成一个集群网络是成功的。但是,现在我想在Windows下,同样用geth客户端,同样的genesis.json文件,最后在控制台下查看创世区块时跟上面的一样,但是在添加节点时总是失败的,没有添加成功,不知道为什么(Windows下geth节点连接上面在Ubuntu下建立的集群)。哪位大神知道原因的帮忙的留个言,谢谢分享。