通过Geth搭建多节点私有链

上一篇中,介绍了一些区块链前端开发必知必会的基本概念以及区块链前端开发与传统业务前端开发的区别。这篇开始,我们将进入实战环节。跟做任何开发一样,区块链前端开发,首先也要搭建区块链的开发环境。下面将以Windows系统为例进行讲解。

https://golang.org/dl/下载go1.10.windows-amd64.msi,安装到C:Go目录下,并将C:Gobin添加到系统环境变量Path中。

如果你之前装过go的话,现在再安装则可能会看到询问是否卸载旧版本的提示。只需要选择“Yes, Uninstall”继续安装即可。

打开系统控制台,在其中输入命令

go version

然后回车执行,如果返回如下信息,说明Go已经安装成功:

go version go1.10 windows/amd64

2、安装Geth

Geth是官方提供的以太坊协议的Go语言实现,是一个以太坊的客户端,一个命令行工具,通过它可以进行一系列以太坊的操作。

首先从https://geth.ethereum.org/downloads/下载Geth 1.8.2 for Windows版本。如果你下载过程中遇到反复终端连接,无法下载成功的情况,可以尝试把下载地址https://gethstore.blob.core.windows.net/builds/geth-windows-amd64-1.8.2-b8b9f7f4.exe复制到迅雷中下载。

然后,将Geth安装到C:Program FilesGeth目录下,并将C:Program FilesGeth 添加到系统环境变量path中。

然后到控制台中执行命令

geth version

看到如下提示,则表示geth安装成功:

Geth
Version: 1.8.2-stable
Git Commit: b8b9f7f4476a30a0aaf6077daade6ae77f969960
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.2
Operating System: windows
GOPATH=
GOROOT=C:Go

web3.js库中所有API 以及 Geth自身的管理API

执行这个命令后,等待片刻,当你看到如下这样的提示:

INFO [03-11|11:14:29] Block synchronisation started
INFO [03-11|11:15:01] Imported new block headers               count=0 elapsed=3.976ms number=240  hash=37f92c…39e00c ignored=192
INFO [03-11|11:15:01] Imported new block receipts              count=0 elapsed=0s      number=54   hash=8387c7…c0d90e size=0.00B ignored=6

则表明已经在进行同步了。

默认情况下,在笔者的Windows 10系统中,会同步到C:Users【我的用户名】AppDataRoamingEthereumgethchaindata这个目录下。如果你看不到AppData这个文件夹,请确认下你有没有勾选中下图中所示的“隐藏的项目复选框”。

图片描述

怎么退出Geth JavaScript Console呢?在控制台中输入exit并按回车即可。

因为同步的以太坊的数据比较占空间,所以我们更改保存以太坊网络同步数据的位置,改成存在d:ethereum目录下:

geth --datadir d:ethereum console

其中,–datadir配置的地址指明了用来保存区块链数据库与keystore的地址,即d:ethereum。

同步的过程中,会不断出现下图这样的区块同步提示:

图片描述

表示刚刚将以太坊网络上的哪个区块同步到了本地。其中,number是区块号,而hash就是该区块的hash值。我们拿着这个区块号到以太坊区块浏览器Etherscan上去浏览一下该区块的信息,比如,这里的区块号是30344,那么在https://etherscan.io/block/30344这个页面中就可以看到该区块的详细信息,如下图。

图片描述

当你同步到的区块与https://etherscan.io/blocks中显示的最新区块的height一样时,就说明本地节点已经同步到最新状态了。

2、同步以太坊测试网络上的数据到本机

因为在以太坊主网络进行部署智能合约、发送交易等操作是需要花费真实的以太币的,所以对于开发者来说,更多的调试和测试工作,不能在主网络上进行(谁的真金白银花得不心疼?),而应该在测试网络上。测试网络上用的是测试币(play-Ether),而不是主网络上真正需要真金白银换来的以太币。所以,作为开发者,你通常需要同步测试网络上的全节点。通过如下命令来完成:

geth --testnet console

其它操作与同步以太坊主网络上的全节点一样,不再赘述。

https://gitforwindows.org/ 下载后安装即可),因为windows自带的控制台是不支持bash文件的执行的。装好Git Bash,我们就可以通过bash starthttp.shbash startws.sh命令来分别启动提供HTTP-RPC服务的私有链和提供WebSockets-RPC服务的私有链,达成简化启动命令的目的。

3、添加节点,组成多节点网络

至此,一个单节点的私有链网络已经启动起来。可以通过admin.nodeInfo查看当前网络节点信息如下:

{
  enode: "enode://4eaf1ef8fd69bb3669741df19a0bfe58b827da56446b7513901631b95b395797277909be4dbbadc25c343fc4c1ca538319311bcae6d17bd7006bbe8c655fdcdf@[::]:30303",
  id: "4eaf1ef8fd69bb3669741df19a0bfe58b827da56446b7513901631b95b395797277909be4dbbadc25c343fc4c1ca538319311bcae6d17bd7006bbe8c655fdcdf",
  ip: "::",
  listenAddr: "[::]:30303",
  name: "Geth/v1.8.2-stable-b8b9f7f4/windows-amd64/go1.9.2",
  ports: {
    discovery: 30303,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        chainId: 1337,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 131072,
      genesis: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      network: 23
    }
  }
}

但是,目前只是单节点的网络,如何添加节点,让它不再是单节点网络呢?

通过如下命令,用上文中创建的同一份创世块配置文件初始化另一个目录(d:/privatechain2)下的创世块。

geth --datadir d:/privatechain2 init d:/privatechain/genesis.json

我们将d:/starthttp.sh文件拷贝一份,命名为starthttp2.sh,同样放在d:/下。将starthttp2.sh的内容修改为:

#!/bin/bashgeth  --datadir "d:privatechain2" --port 30304 --ipcdisable --networkid 23 --rpc  --rpcaddr "localhost" --rpcport "8546" --rpccorsdomain "*" --rpcapi "db,eth,net,web3" console

即修改了--datadir--rpcport两个选项的值,添加了--port 30304 --ipcdisable,以免与现有节点相冲突。然后另开一个Git Bash控制台窗口,我们通过bash starthttp2.sh命令启动了另一个节点。 再用admin.nodeInfo命令查看下新节点的信息,发现与原有节点enode是不一样的,证明两个节点确实不同(不过,需要确保两个节点的protocols信息是一致的,因为它们必须是基于同一份创世区块配置产生出来的,才能连接成功,具体需要满足哪些条件才能连接成功,可以参考https://github.com/ethereum/go-ethereum/wiki/Setting-up-private-network-or-local-cluster)。

{
  enode: "enode://d5e8b09b13ddff0b88e13259e8d764e8ec982e76592f48fc1db11c4829f5d9cabdaaeecf13b5812e216506536b1f8a53068470975650beb86ab46c27718c7cdd@[::]:30304",
  id: "d5e8b09b13ddff0b88e13259e8d764e8ec982e76592f48fc1db11c4829f5d9cabdaaeecf13b5812e216506536b1f8a53068470975650beb86ab46c27718c7cdd",
  ip: "::",
  listenAddr: "[::]:30304",
  name: "Geth/v1.8.2-stable-b8b9f7f4/windows-amd64/go1.9.2",
  ports: {
    discovery: 30304,
    listener: 30304
  },
  protocols: {
    eth: {
      config: {
        chainId: 1337,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 131072,
      genesis: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      network: 23
    }
  }
}

接下来我们让两个节点连接起来。

在第二个控制台中用admin.peers查看一下,发现返回是空数组。 然后执行:

admin.addPeer("enode://4eaf1ef8fd69bb3669741df19a0bfe58b827da56446b7513901631b95b395797277909be4dbbadc25c343fc4c1ca538319311bcae6d17bd7006bbe8c655fdcdf@[::]:30303")

其中括号内的是第一个节点的节点信息中的enode的值。

然后再通过amin.peers查看,可以看到如下内容,表示添加成功:

[{
    caps: ["eth/63"],
    id: "4eaf1ef8fd69bb3669741df19a0bfe58b827da56446b7513901631b95b395797277909be4dbbadc25c343fc4c1ca538319311bcae6d17bd7006bbe8c655fdcdf",
    name: "Geth/v1.8.2-stable-b8b9f7f4/windows-amd64/go1.9.2",
    network: {
    inbound: false,
    localAddress: "127.0.0.1:53792",
    remoteAddress: "127.0.0.1:30303",
    static: true,
    trusted: false
    },
    protocols: {
    eth: {
        difficulty: 131072,
        head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
        version: 63
    }
    }
}]

原文出处

请使用浏览器的分享功能分享到微信等