【Ethereum基础实践】:以太坊测试私链的搭建

以太坊测试私链的搭建

这篇文档通过使用Geth来搭建Ethereum(以太坊)私有测试链。
本文档两个节点的系统环境为:

OS:Ubuntu
Memory:8G
CPU:Intel Xeon E5-2620

安装Geth

Geth是通过Go语言实现的一款Ethereum客户端,通过Geth我们可以搭建Ethereum的测试私链。

1
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

搭建私有测试链

通过搭建私有测试链,可以预分配以太币或者调低挖矿的难度来高效的获取以太币,可以便于对以太坊的测试。

搭建私有测试链需要做的主要有下列这些事项:

  • 自定义创世块(Genesis Block)
  • 自定义数据存放位置
  • 自定义网络ID
  • 关闭节点发现(Node Discovery)(推荐)

自定义创世块(Genesis Block)

  • CustomGenesis.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"config": {
"chainId": 3131,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
}
,

"difficulty": "200000000",
"gasLimit": "2100000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400" }
}

}

创世块是区块链中的第一个初始区块,我们通过定义CustomGenesis.json文件来对其进行自定义。

在创世块的配置文件^1中,有四个参数是必须要指定的:

  • config:区块链的相关参数
    • chainId:防止重放攻击(replay attack,简单来说就是未经授权的用户来假扮交易的发送者)
    • homesteadBlock:Homestead^2是以太坊的第二个发行版本(Frontier^3是第一个发行版本),值为0表示的使用的是该版本的以太坊
  • difficult:初始挖矿难度
  • gasLimit:每一个区块所消耗的gas上限
  • alloc:可以往地址中预先分配以太币

生成创世块

使用下列命令来初始化创世块:

1
geth --datadir /path/to/data init /path/to/CustomGenesis.json
  • --datadir:指定区块链的数据目录(默认为~/.ethereum
  • init:创世块初始化JSON文件的目录

启动以太坊私有测试链

相关启动参数

启动geth有如下主要参数(可以使用geth --help进行查看):

  • --nodiscover:关闭节点的可发现性,可以防止使用了相同network id和创世块的节点连接到你的区块链网络中(只能通过手动来添加节点)
  • --maxpeers 0:指定网络中的最多节点数
  • --rpc:启用RPC服务
  • --rpcapi "db,eth,net,web3":指定启用的RPC API
  • --rpcport "8080":指定RPC的端口
  • --rpccorsdomain:指定哪些URL可以连接到你的节点
  • --datadir:以太坊区块链的数据目录
  • --port:连接到其它节点的网络监听端口
  • --identity "FirstNode":指定节点名称
  • console:启动geth控制台程序

启动geth

使用以下命令来启动geth:

1
geth --identity "ETH-MainNode" --rpc --rpcport "6060" --rpccorsdomain "*" --datadir "/home/lyh/privatechain-eth/data" --port "30303" --nodiscover --maxpeers 5 --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --networkid 3131 console

使用相同的配置对两个节点进行配置并启动。

节点连接

在其中一个节点的geth控制台中执行:

1
> admin.nodeInfo

我们得到该节点的信息:

1
> admin.nodeInfo
{
  enode: "enode://09444457dd475ac1a81948c5066602d23abd49407cae33edef929c9d96374396496f97b1a8fb1c22d36d990e90ed16a2a4faf3fd2ae63c08f4f58ee6249bcec7@[::]:30303",
  id: "09444457dd475ac1a81948c5066602d23abd49407cae33edef929c9d96374396496f97b1a8fb1c22d36d990e90ed16a2a4faf3fd2ae63c08f4f58ee6249bcec7",
  ip: "::",
  listenAddr: "[::]:30303",
  name: "Geth/ETH-MainNode/v1.8.2-stable-b8b9f7f4/linux-amd64/go1.9.4",
  ports: {
    discovery: 30303,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        chainId: 3131,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 92699744128,
      genesis: "0x54fd3f9117e7d8c5b130af59fed07ddc9eef0826016d4d5b9c07db8db1dfac23",
      head: "0xd67ba0763b4fc50741b33205e486d0113aa182d310ee0225332459d104ed5b58",
      network: 3131
    }
  }
}

得到enode信息:
enode://09444457dd475ac1a81948c5066602d23abd49407cae33edef929c9d96374396496f97b1a8fb1c22d36d990e90ed16a2a4faf3fd2ae63c08f4f58ee6249bcec7@[::]:30303

我们需要在另一台节点上添加上该节点,使用命令:

1
> admin.addPeer("09444457dd475ac1a81948c5066602d23abd49407cae33edef929c9d96374396496f97b1a8fb1c22d36d990e90ed16a2a4faf3fd2ae63c08f4f58ee6249bcec7@[::]:30303")
true

我们需要将上述enode信息中的[::]更换为该节点的IP地址。

使用命令:

1
> net.peerCount
1

我们看到已经添加了一个节点。

测试以太坊私有链

我们可以通过在两个节点分别创建账号构造一笔转账交易来验证多节点的私链是否搭建成功。

分别在两个节点中创建账号:

1
> personal.newAccount()

设置密码后,得到地址:

节点一:

> "0xa9436991e002986f58d948d79e737df190c4f26b"

节点二:

> "0xf7be2382f03cf7dd8ed5e59253a7b9321aac20ec"

开始挖矿:

由于新创建的账号中是没有以太币的,因此我们需要启用矿工进行挖矿:

1
> miner.setEtherbase("0xa9436991e002986f58d948d79e737df190c4f26b")
> miner.start(1)

另一个节点同样开启挖矿:

1
> miner.setEtherbase("0xf7be2382f03cf7dd8ed5e59253a7b9321aac20ec")
> miner.start(1)

构造一笔交易:

在进行转账之前,我们需要对钱包进行解锁:

1
> personal.unlockAccount("0xa9436991e002986f58d948d79e737df190c4f26b")

输入密码对钱包进行解锁后,构造一笔转账交易:

1
> eth.sendTransaction({from: "0xa9436991e002986f58d948d79e737df190c4f26b", to: "0xf7be2382f03cf7dd8ed5e59253a7b9321aac20ec", value: web3.toWei(10, "ether")})

在交易被矿工进行验证与打包至区块之后,我们可以查询一下钱包的余额来验证交易是否完成:

1
> eth.getBalance("0xf7be2382f03cf7dd8ed5e59253a7b9321aac20ec")

本文的版权归作者 罗远航 所有,采用 Attribution-NonCommercial 3.0 License。任何人可以进行转载、分享,但不可在未经允许的情况下用于商业用途;转载请注明出处。感谢配合!