经过一段时间关于以太坊的学习,博主也算是对区块链以及以太坊有了一个初步的了解,整理一篇关于以太坊搭建私有链的方法。
若想以太坊节点之间能够相互连接需要满足一定的条件:
- 相同的协议版本
- 相同的network id
搭建私有链最简单的方式就是使用geth里的 --network 选项,设置一个与主网不同的network id (以太坊主网id是1)
一、建立创世区块
打开终端输入以下命令
1 mkdir privatechain #建立文件夹,名字自拟 2 cd privatechain #终端进入建立的文件夹
建立创世区块文件genesis.json
1 vim genesis.json #注:没有安装vim 可以用 vi 命令
在创世区块的json文件中填入以下内容:
1 { 2 "config": { 3 "chainId": 20, 4 "homesteadBlock": 0, 5 "eip155Block": 0, 6 "eip158Block": 0 7 }, 8 "coinbase" : "0x0000000000000000000000000000000000000000", 9 "difficulty" : "0x100", #为方便挖矿,我们这里将难度值设置的很小 10 "extraData" : "", 11 "gasLimit" : "0xffffffff", 12 "nonce" : "0x0000000000000042", 13 "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 14 "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", 15 "timestamp" : "0x00", 16 "alloc": { } 17 }
各个参数的介绍
参数名称 | 参数详解 |
chainId | 指定了独立的区块链网络id,网络id在连接到其它节点的时候会用到,以太坊公网id是1,不同的id网络的节点无法相互连接 |
homesteadBlock | HomesteadBlock是以太坊的第二个主要版本,第一个是Frontier,这个值设置为“0”表示目前正在使用Homestead版本 |
eip155Block | eip是ethereum improvement proposal的缩写,我们的链不会提议分叉,所以设置为“0”即可 |
eip158Block | eip是ethereum improvement proposal的缩写,我们的链不会提议分叉,所以设置为“0”即可 |
coinbase | 矿工的账号(随便填) |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度 |
extraData | 可以写入32byte大小的任意数据,每个block都会有,由挖出block的miner来决定要不要写点什么 |
gasLimit | 该值设置对gas的消耗总量限制,用来限制区块能包含的交易信息和,因为我们是私有链,所以填最大 |
nonce | 一个用于挖矿的64位随机数 |
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的哈希,注意它和nonce的设置需要满足以太坊的yellow paper |
parentHash | 上一个区块的哈希值,因为是创世区块,所以这个值是0 |
timestamp | 设置创世区块的时间戳 |
alloc | 给某个账户预分配以太币 |
二、初始化创世节点,并且设置data目录
在privatechain目录终端下输入如下命令
1 geth --datadir ./data/00 init genesis.json 2 3 #--datadir data 中data是文件夹的名称,私有链的数据会存储在这个文件夹内。若存在其他节点文件名要不同。可以通过“--datadir 文件名”来区分不同的私有链节点,若没有设置--datadir,则会读取以太坊主网的数据,默认位置在/root/.ethereum
出现以日志说明初始化成功
INFO [06-26|21:02:01.682] Maximum peer count ETH=25 LES=0 total=25 INFO [06-26|21:02:01.697] Allocated cache and file handles database=/home/milo/private-geth/data/00/geth/chaindata cache=16 handles=16 INFO [06-26|21:02:01.866] Writing custom genesis block INFO [06-26|21:02:01.866] Persisted trie from memory database nodes=0 size=0.00B time=4.212µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [06-26|21:02:01.867] Successfully wrote genesis state database=chaindata hash=696bed…1d07ed INFO [06-26|21:02:01.867] Allocated cache and file handles database=/home/milo/private-geth/data/00/geth/lightchaindata cache=16 handles=16 INFO [06-26|21:02:01.956] Writing custom genesis block INFO [06-26|21:02:01.956] Persisted trie from memory database nodes=0 size=0.00B time=3.013µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B INFO [06-26|21:02:01.957] Successfully wrote genesis state database=lightchaindata hash=696bed…1d07ed
三、启动节点
1 geth --datadir ./data/00 --networkid 100 console 2 #100为network id,1为主网id,可以选择除1以外的随机数
milo@milo-K46CB:~/private-geth$ tree 终端输入tree,查看生成的目录 . ├── data │ └── 00 │ ├── geth │ │ ├── chaindata │ │ │ ├── 000002.ldb │ │ │ ├── 000003.log │ │ │ ├── CURRENT │ │ │ ├── CURRENT.bak │ │ │ ├── LOCK │ │ │ ├── LOG │ │ │ └── MANIFEST-000004 │ │ ├── lightchaindata │ │ │ ├── 000001.log │ │ │ ├── CURRENT │ │ │ ├── LOCK │ │ │ ├── LOG │ │ │ └── MANIFEST-000000 │ │ ├── LOCK │ │ ├── nodekey │ │ ├── nodes │ │ │ ├── 000001.log │ │ │ ├── CURRENT │ │ │ ├── LOCK │ │ │ ├── LOG │ │ │ └── MANIFEST-000000 │ │ └── transactions.rlp │ ├── geth.ipc │ └── keystore │ └── UTC--2019-06-26T13-02-31.335901324Z--8830397771710ade101f0080f0da076181bad374 └── genesis.json
INFO [06-26|21:02:06.602] Maximum peer count ETH=25 LES=0 total=25 INFO [06-26|21:02:06.604] Starting peer-to-peer node instance=Geth/v1.8.27-stable-4bcc0a37/linux-amd64/go1.10.4 INFO [06-26|21:02:06.604] Allocated cache and file handles database=/home/milo/private-geth/data/00/geth/chaindata cache=512 handles=2048 INFO [06-26|21:02:06.792] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Constantinople: <nil> ConstantinopleFix: <nil> Engine: unknown}" INFO [06-26|21:02:06.792] Disk storage enabled for ethash caches dir=/home/milo/private-geth/data/00/geth/ethash count=3 INFO [06-26|21:02:06.792] Disk storage enabled for ethash DAGs dir=/home/milo/.ethash count=2 INFO [06-26|21:02:06.792] Initialising Ethereum protocol versions="[63 62]" network=100 INFO [06-26|21:02:06.863] Loaded most recent local header number=0 hash=696bed…1d07ed td=256 age=50y2mo1w INFO [06-26|21:02:06.863] Loaded most recent local full block number=0 hash=696bed…1d07ed td=256 age=50y2mo1w INFO [06-26|21:02:06.863] Loaded most recent local fast block number=0 hash=696bed…1d07ed td=256 age=50y2mo1w INFO [06-26|21:02:06.863] Regenerated local transaction journal transactions=0 accounts=0 INFO [06-26|21:02:07.009] New local node record seq=1 id=1b933112e1333f9a ip=127.0.0.1 udp=30303 tcp=30303 INFO [06-26|21:02:07.015] Started P2P networking self=enode://bfad31051f4ba04bf5bbb2fdd455bfcbf924479991b029a8604ab5abb386431b7c7f7d1edbba0bf6db66ad172b632ca45518239979634f190a0c26c0a9b9864b@127.0.0.1:30303 INFO [06-26|21:02:07.016] IPC endpoint opened url=/home/milo/private-geth/data/00/geth.ipc Welcome to the Geth JavaScript console! instance: Geth/v1.8.27-stable-4bcc0a37/linux-amd64/go1.10.4 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 >
出现这样的日志说明私有网络就搭建成功了,下一步我们来在这个私有网络挖矿。
四、挖矿
要挖矿首先必须要有一个账户,根据以下命令。
> eth.accounts #查看node中的所有账户 [] ##输出了一个“[]”,说明没有账户 > personal.newAccount("123456") ##创建新账户,123456是账户密码,一般会输出以下结果 "0x8830397771710ade101f0080f0da076181bad374" > eth.accounts ["0x8830397771710ade101f0080f0da076181bad374"] 此时账户已经有了,我们可以进行挖矿了,输入以ixa命令 > miner.start(3) ##miner.start()是启动挖矿,3是启动线程数,为避免影响电脑性能,这里我们就用3线程
到这里时会出现一些问题,一般来说,第一次启动挖矿,应当会出现以下日志
INFO [05-16|00:07:25] Updated mining threads threads=0 INFO [05-16|00:07:25] Starting mining operation null INFO [05-16|00:07:25] Commit new mining work number=1 txs=0 uncles=0 elapsed=38.053ms INFO [05-16|00:07:28] Generating DAG in progress epoch=0 percentage=0 elapsed=1.715 INFO [05-16|00:07:30] Generating DAG in progress epoch=0 percentage=1 elapsed=3.448s INFO [05-16|00:07:31] Generating DAG in progress epoch=0 percentage=2 elapsed=5.059s INFO [05-16|00:07:33] Generating DAG in progress epoch=0 percentage=3 elapsed=6.799s INFO [05-16|00:07:35] Generating DAG in progress epoch=0 percentage=4 elapsed=8.373s ##当percentage=100时,也就是加载到100%时,会开始挖矿,这个过程可能会比较慢,要耐心等待。 INFO [06-26|21:10:53.002] Successfully sealed new block number=1 sealhash=dac366…ad5c8d hash=3cb840…442e46 elapsed=8m9.375s INFO [06-26|21:10:53.042] ? mined potential block number=1 hash=3cb840…442e46 INFO [06-26|21:10:53.103] Commit new mining work number=2 sealhash=088254…66c59d uncles=0 txs=0 gas=0 fees=0 elapsed=60.592ms INFO [06-26|21:10:53.906] Successfully sealed new block number=2 sealhash=088254…66c59d hash=446602…93d76b elapsed=803.002ms INFO [06-26|21:10:53.906] ? mined potential block number=2 hash=446602…93d76b INFO [06-26|21:10:53.906] Commit new mining work number=3 sealhash=6c39db…66d2bf uncles=0 txs=0 gas=0 fees=0 elapsed=178.137µs INFO [06-26|21:10:54.406] Successfully sealed new block number=3 sealhash=6c39db…66d2bf hash=fa550b…95d423 elapsed=500.446ms INFO [06-26|21:10:54.407] ? mined potential block number=3 hash=fa550b…95d423 ##这个就是代表挖到矿了
正常来讲,第一次搭建私有链到这里都没什么问题,而当我第二次开启节点挖矿时出现了问题
> miner.start(3) INFO [06-26|21:02:43.616] Updated mining threads threads=3 INFO [06-26|21:02:43.626] Transaction pool price threshold updated price=1000000000 INFO [06-26|21:02:43.627] Etherbase automatically configured address=0x8830397771710ADE101f0080f0da076181Bad374 null > INFO [06-26|21:02:43.627] Commit new mining work number=1 sealhash=dac366…ad5c8d uncles=0 txs=0 gas=0 fees=0 elapsed=373.028µs ##当我再次输入挖矿命令时,情况陷入了僵局,此时会一直停留在Commit new mining work ##我在网上搜索过许多,大多没有解决办法,也没有指出问题的原因,反反复复试过很多次,自第一次搭建私有链后,后续的都一直是这样。 ##所以我打算在另一台电脑上安装虚拟机,重新再来一遍试试,而这个我也一直放着一直加载。 ##当我在经过一系列猛如虎的操作下,装虚拟机,装ethereum开发环境,终于也到了加载DGA的那一步 ##这时再看一直僵在Commit new mining work的电脑时,它突然开始挖矿了。。。。。 ##所以到这个步骤时,并不是什么错误,我们应当耐心等待 > INFO [06-26|21:02:43.627] Commit new mining work number=1 sealhash=dac366…ad5c8d uncles=0 txs=0 gas=0 fees=0 elapsed=373.028µs INFO [06-26|21:10:53.002] Successfully sealed new block number=1 sealhash=dac366…ad5c8d hash=3cb840…442e46 elapsed=8m9.375s INFO [06-26|21:10:53.042] ? mined potential block number=1 hash=3cb840…442e46 INFO [06-26|21:10:53.103] Commit new mining work number=2 sealhash=088254…66c59d uncles=0 txs=0 gas=0 fees=0 elapsed=60.592ms INFO [06-26|21:10:53.906] Successfully sealed new block number=2 sealhash=088254…66c59d hash=446602…93d76b elapsed=803.002ms INFO [06-26|21:10:53.906] ? mined potential block number=2 hash=446602…93d76b INFO [06-26|21:10:53.906] Commit new mining work number=3 sealhash=6c39db…66d2bf uncles=0 txs=0 gas=0 fees=0 elapsed=178.137µs INFO [06-26|21:10:54.406] Successfully sealed new block number=3 sealhash=6c39db…66d2bf hash=fa550b…95d423 elapsed=500.446ms INFO [06-26|21:10:54.407] ? mined potential block number=3 hash=fa550b…95d423 INFO [06-26|21:10:54.457] Commit new mining work number=4 sealhash=f170b2…be929e uncles=0 txs=0 gas=0 fees=0 elapsed=50.737ms INFO [06-26|21:10:54.946] Successfully sealed new block number=4 sealhash=f170b2…be929e hash=190e69…4fbc8b elapsed=488.870ms
查看挖到的区块
1 > miner.stop() 2 null 3 > eth.getBalance(eth.accounts[0]) 4 155000000000000000000 5 > eth.blockNumber 6 31
到这里,一个基于以太坊的私有链就搭建完成了