搭建以太坊私有链

 环境准备

1  Go-Ethereum

Go-Ethereum是由以太坊基金会提供的官方客户端软件。它是用Go编程语言编写的,简称Geth。可以按照以下wiki说明安装go-ethereum,地址为:https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum

这里简单介绍一下在mac上通过源码安装的步骤:

1)   下载geth源码:

git clone https://github.com/ethereum/go-ethereum

2)   安装go环境

brew install go

3)   compile、build、install geth

cd go-ethereum

make geth

4)   xcode支持

If you see some errors related to header files of Mac OS system library, install XCode Command Line Tools, and try again.

xcode-select --install

5)   测试安装是否成功

执行命令:geth version,如果出现以下信息说明安装成功

geth version

Geth

Version: 1.8.14-stable

Architecture: amd64

Protocol Versions: [63 62]

Network Id: 1

Go Version: go1.10.3

Operating System: darwin

GOPATH=/Users/wuzhengfei/Documents/workspace/go/workspace

GOROOT=/usr/local/go

 

 搭建私有链

go-ethereum中详细介绍了搭建私有链的过程,有兴趣的话,可以详细看一下。

1  常见创世区块

1)   常见创世区块

首先需要为区块链创建一个创世区块,所有的区块都会挂在这个创世区块的后面。创建一个json文件(这里命名为genesis.json),其内容如下:

{

  "config": {

        "chainId"0,

        "homesteadBlock"0,

        "eip155Block"0,

        "eip158Block"0

    },

  "alloc"      : {},

  "coinbase"   : "0x0000000000000000000000000000000000000000",

  "difficulty""0x20000",

  "extraData"  : "",

  "gasLimit"   : "0x2fefd8",

  "nonce"      : "0x0000000000055555",

  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",

  "parentHash""0x0000000000000000000000000000000000000000000000000000000000000000",

  "timestamp"  : "0x00"

}

以上json来自go-ethereum官网,他可以满足大部分场景的需要。建议修改nonce的值,这样可以防止未知的远程节点连接到此私有的测试网络中。

2)   指定数据保存目录

如下图目录结构所示,genesis.json为创世区块地址,data0为区块链数据地址。

搭建以太坊私有链

 

2  初始化

创建好创世区块以后,通过以下命令初始化Geth节点,确保所有参数都能设置正确,如下所示:

geth -datadir /Users/wuzhengfei/Documents/ethereum/testchain/data0 init /Users/wuzhengfei/Documents/ethereum/testchain/genesis.json 

geth init命令用来初始化区块链,其中-datadir指定数据存放目录,genesis.json是init命令的参数运行命令,会读取genesis.json文件,根据其中的内容,将创世区块写入到区块链中。结果如下所示:

$ geth -datadir /Users/wuzhengfei/Documents/ethereum/testchain/data0 init /Users/wuzhengfei/Documents/ethereum/testchain/genesis.json

INFO [12-16|15:00:35.410] Maximum peer count                       ETH=25 LES=0 total=25

INFO [12-16|15:00:35.423] Allocated cache and file handles         database=/Users/wuzhengfei/Documents/ethereum/testchain/data0/geth/chaindata cache=16 handles=16

INFO [12-16|15:00:35.427] Writing custom genesis block 

INFO [12-16|15:00:35.428]Persisted trie from memory database      nodes=4 size=573.00B time=93.543µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B

INFO [12-16|15:00:35.428] Successfully wrote genesis state         database=chaindata                                                          hash=d62439…28110e

INFO [12-16|15:00:35.428] Allocated cache and file handles         database=/Users/wuzhengfei/Documents/ethereum/testchain/data0/geth/lightchaindata cache=16 handles=16

INFO [12-16|15:00:35.430] Writing custom genesis block 

INFO [12-16|15:00:35.431] Persisted trie from memory database      nodes=4 size=573.00B time=73.437µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B

INFO [12-16|15:00:35.431] Successfully wrote genesis state         database=lightchaindata                                                           hash=d62439…28110e

初始化后的目录结构如下所示:

搭建以太坊私有链

3  交互模式

1)    进入交互模式

执行geth console命令

$ geth --datadir data0/ --nodiscover console 2>>../etherum.log

输出信息如下所示,说明进入交互模式成功,当然也可以进入ethereum.log文件中查看日志

wuzhengfeideMacBook-Pro:testchain wuzhengfei$ geth --datadir data0/ --nodiscover console 2>>../etherum.log

Welcome to the Geth JavaScript console!

 

instance: Geth/v1.8.14-stable/darwin-amd64/go1.10.3

 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

 

2)   创建账户

a)    查看已创建账户

执行eth.accounts方法

eth.accounts

因为还未创建账户,所以输出信息如下所示:

> eth.accounts

[]

 

b)    创建账户

执行newAccount()方法,如下所示;

personal.newAccount()

输出信息如下所示:

personal.newAccount("wuzhengfei")

"0x555b8a7fb1e3f95745fd31be168f8e1d77dced5a"

再次执行eth.accounts命令即可看到当前的账户。

> eth.accounts

["0x555b8a7fb1e3f95745fd31be168f8e1d77dced5a"]

 

3)   挖矿

a)    查看账户余额

eth.getBalance("0x555b8a7fb1e3f95745fd31be168f8e1d77dced5a")

因为还没有以太币,所以输出结果如下:

> eth.getBalance("0x555b8a7fb1e3f95745fd31be168f8e1d77dced5a")

0

b)    挖矿

执行miner.start(),开始挖矿

miner.start()

输出结果如下

> miner.start()

null

此时进入ethereum.log文件中,可以看到挖矿有一个初始化过程,达到100以后即开始挖矿。

INFO [12-16|15:44:25.879] Generating DAG in progress               epoch=0 percentage=96 elapsed=2m32.178s

INFO [12-16|15:44:27.878] Generating DAG in progress               epoch=0 percentage=97 elapsed=2m34.177s

INFO [12-16|15:44:29.756] Generating DAG in progress               epoch=0 percentage=98 elapsed=2m36.055s

INFO [12-16|15:44:31.931] Generating DAG in progress              epoch=0 percentage=99 elapsed=2m38.230s

INFO [12-16|15:44:31.934] Generated ethash verification cache      epoch=0 elapsed=2m38.232s

INFO [12-16|15:44:33.799] Successfully sealed new block            number=1 hash=c40a19…a0977d elapsed=2m40.760s

INFO [12-16|15:44:33.812] mined potential block                  number=1 hash=c40a19…a0977d

INFO [12-16|15:44:33.813] Commit new mining work                   number=2 uncles=0 txs=0 gas=0 fees=0 elapsed=177.937µs

INFO [12-16|15:44:35.770] Successfully sealed new block           number=2 hash=b0f39a…03fef1 elapsed=1.956s

INFO [12-16|15:44:35.770] mined potential block                  number=2 hash=b0f39a…03fef1

 

c)    查看账户余额

挖矿一段时间后,再次查看账户余额

> eth.getBalance("0x555b8a7fb1e3f95745fd31be168f8e1d77dced5a")

200000000000000000000

d)    停止挖矿

停止挖矿,只需执行miner.stop()

miner.stop()

输出结果如下

> miner.stop()

true

 

 常见问题

1  创世区块中的alloc问题

网上的博客中,都说通过在创世区块的alloc中指定账户以及账户余额,如下所示:

{

  "config": {

       "chainId": 10,

       "homesteadBlock": 0,

       "eip155Block": 0,

       "eip158Block": 0

    },

 "coinbase"   : "0x0000000000000000000000000000000000000000",

  "difficulty" : "0x20000",

 "extraData"  : "",

 "gasLimit"   : "0x2fefd8",

  "nonce"      : "0x00000000000666666666",

  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",

  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",

 "timestamp"  : "0x00",

  "alloc": {

       "0x1d82a7d2c4fd6aad2054a368098318ab998f4786": {

             "balance": "100000000000000000000"

        }

  }

}

然后执行geth init命令,如下所示

geth --datadir data0/ init genesis.json

就能在初始化后的网络中看到这些账户,并且账户有一定余额。亲测,这是有问题的。因为在init前区块链中不存在此账户(0x1d82a7d2c4fd6aad2054a368098318ab998f4786),所以init后是查不到这个账户,当然也就没有余额了。如果想给指定的一批账号初始化余额,需要先创建账户,然后在执行init。具体步骤如下:

第一步:先在交互模式下创建账户:

persion.newAccount(密码)

第二步:移除之前的db

geth removedb --datadir data0/

第三步:将账户信息放入genesis.json中,即将上面alloc中的账户改成第一步中创建的账户。

重新init

geth --datadir data0/ init genesis.json

 

 

 

 

 

上一篇:正则表达式解析_学习笔记


下一篇:Interrupt