以太坊研究系列【私链搭建、挖矿、交易】

in #ethereum7 years ago (edited)

此文档为个人整理学习使用,部分内容来源于网络,也期待能给你带来益处

Geth介绍

Geth又名Go Ethereum,由Go语言开发,完全开源的项目。

Geth是以太坊协议的具体落地实现,通过Geth,你可以实现以太坊的各种功能,如账户的新建编辑删除,开启挖矿,ether币的转移,智能合约的部署和执行等等

Geth官网
https://geth.ethereum.org/

Geth的Github地址
https://github.com/ethereum/go-ethereum

Geth安装文档
https://ethereum.github.io/go-ethereum/install/


mac上安装geth

brew tap ethereum/ethereum
brew install ethereum

Chaim:pyeth Chaim$ brew install ethereum
==> Installing ethereum from ethereum/ethereum
==> Installing dependencies for ethereum/ethereum/ethereum: git, go
==> Installing ethereum/ethereum/ethereum dependency: git
==> Downloading https://homebrew.bintray.com/bottles/git-2.15.1_1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring git-2.15.1_1.high_sierra.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions and functions have been installed to:
  /usr/local/share/zsh/site-functions

Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/git
==> Summary
🍺  /usr/local/Cellar/git/2.15.1_1: 1,488 files, 34.1MB
==> Installing ethereum/ethereum/ethereum dependency: go
==> Downloading https://homebrew.bintray.com/bottles/go-1.9.2.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring go-1.9.2.high_sierra.bottle.tar.gz
==> Caveats
A valid GOPATH is required to use the `go get` command.
If $GOPATH is not specified, $HOME/go will be used by default:
  https://golang.org/doc/code.html#GOPATH

You may wish to add the GOROOT-based install location to your PATH:
  export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> Summary
🍺  /usr/local/Cellar/go/1.9.2: 7,646 files, 293.9MB
==> Installing ethereum/ethereum/ethereum
==> Cloning https://github.com/ethereum/go-ethereum.git
Cloning into '/Users/Chaim/Library/Caches/Homebrew/ethereum--git'...
remote: Counting objects: 2474, done.
remote: Compressing objects: 100% (2185/2185), done.
remote: Total 2474 (delta 315), reused 1456 (delta 163), pack-reused 0
Receiving objects: 100% (2474/2474), 8.39 MiB | 1.20 MiB/s, done.
Resolving deltas: 100% (315/315), done.
Note: checking out '4bb3c89d44e372e6a9ab85a8be0c9345265c763a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

==> Checking out tag v1.7.3
==> go env
==> make all
==> Caveats
To have launchd start ethereum/ethereum/ethereum now and restart at login:
  brew services start ethereum/ethereum/ethereum
==> Summary
🍺  /usr/local/Cellar/ethereum/1.7.3: 10 files, 52.7MB, built in 2 minutes 54 seconds

显示帮助
geth -h

列出当前用户
geth account list

检查版本

Chaim:pyeth Chaim$ geth version
Geth
Version: 1.7.3-stable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.2
Operating System: darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.9.2/libexec

以太坊网络

  1. 以太坊生产网络
  2. 以太坊测试网络 TestNet
  3. 以太坊私有网络 PrivateNetwork

建立私有以太坊网络

建立目录和创世区块配置文件

Chaim:workspace Chaim$ mkdir ethPri

Chaim:workspace Chaim$ cd ethPri/

建立创世块配置文件genesis.json,输入以下内容:

{
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x0",
  "gasLimit": "0x80000000",
  "difficulty": "0x1",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {     }
}

各参数的作用:
title

执行命令,创建创世区块

Chaim:ethPri Chaim$ geth --datadir "./" init genesis.json
Fatal: invalid genesis file: json: cannot unmarshal hex string of odd length into Go struct field Genesis.extraData of type hexutil.Bytes

但是执行时出错了,看起来是extraData数据有些问题,修改为:
"extraData": "0x00"

执行结果如下:

Chaim:ethPri Chaim$ geth --datadir "./" init genesis.json
WARN [12-28|15:02:34] No etherbase set and no accounts found as default 
INFO [12-28|15:02:34] Allocated cache and file handles         database=/Users/Chaim/Documents/workspace/ethPri/geth/chaindata cache=16 handles=16
Fatal: Failed to write genesis block: genesis has no chain configuration

常遇到的几个错误:
Fatal: invalid genesis file: missing 0x prefix for hex data:这个错误信息意思很明白,就是你的json文件中,对于16进制数据,需要加上0x前缀
Fatal: invalid genesis file: hex string has odd length: 从v1.6开始,设置的十六进制数值,不能是奇数位, 比如不能是0x0,而应该是0x00。
Fatal: failed to write genesis block: genesis has no chain configuration :这个错误信息,就是说,你的json文件中,缺少config部分。看到这个信息,我们不需要把geth退回到v1.5版本,而是需要加上config部分。
Error: invalid sender undefined: 这个错误不会导致初始化失败,但是会在以后的转账(eth.sendTransaction),或者部署智能合约的时候产生。解决方法就是chainId 不能设置为0。 如果你完全按照github上给的官方配置文件,就会产生这个错误。

一些参数如下:
title

当前目录下新增两个文件夹geth和keystore
geth中保存的是区块链的相关数据
keystore中保存的是该链条中的用户信息

目录结构如下:
title

创建私有链

Chaim:ethPri Chaim$ geth --datadir "./" --nodiscover console 2>>geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable/darwin-amd64/go1.9.2
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

在私有链上创建用户

> eth.accounts
[]
> personal.newAccount("123456")
"0x390410e96d77e47847e719e0ea06d72a3f1b624c"
> eth.accounts
["0x390410e96d77e47847e719e0ea06d72a3f1b624c"]
> 

查看区块链的日志

Chaim:ethPri Chaim$ tail -f geth.log
INFO [12-28|15:13:48] Disk storage enabled for ethash DAGs     dir=/Users/Chaim/.ethash                                count=2
INFO [12-28|15:13:48] Initialising Ethereum protocol           versions="[63 62]" network=1
INFO [12-28|15:13:48] Loaded most recent local header          number=0 hash=d4e567…cb8fa3 td=17179869184
INFO [12-28|15:13:48] Loaded most recent local full block      number=0 hash=d4e567…cb8fa3 td=17179869184
INFO [12-28|15:13:48] Loaded most recent local fast block      number=0 hash=d4e567…cb8fa3 td=17179869184
INFO [12-28|15:13:48] Loaded local transaction journal         transactions=0 dropped=0
INFO [12-28|15:13:48] Regenerated local transaction journal    transactions=0 accounts=0
INFO [12-28|15:13:48] Starting P2P networking 
INFO [12-28|15:13:48] RLPx listener up                         self="enode://49299b4d177c88956521ae225f0c89c2adf74a2f35acdc8e401d3de196e86f093f85089f1376886c0111877a8fc030643c4760ed9b576d1b50ed89c46e6fba92@[::]:30303?discport=0"
INFO [12-28|15:13:48] IPC endpoint opened: /Users/Chaim/Documents/workspace/ethPri/geth.ipc 

开始挖矿

好迫切啊,看了这么多理论就这个挖矿是真正赚钱的,试一试!

> miner.start()
null

从日志窗口可以看到挖矿的进程:

INFO [12-28|15:21:25] Generating DAG in progress               epoch=0 percentage=95 elapsed=52.986s
INFO [12-28|15:21:26] Generating DAG in progress               epoch=0 percentage=96 elapsed=53.553s
INFO [12-28|15:21:27] Generating DAG in progress               epoch=0 percentage=97 elapsed=54.123s
INFO [12-28|15:21:27] Generating DAG in progress               epoch=0 percentage=98 elapsed=54.692s
INFO [12-28|15:21:28] Generating DAG in progress               epoch=0 percentage=99 elapsed=55.393s
INFO [12-28|15:21:28] Generated ethash verification cache      epoch=0 elapsed=55.395s

注意点:

  1. 挖矿挖到的ether币会默认保在第一个账户中,即eth.acccounts[0]中。
  2. 挖矿是执行智能合约的基础。如果停止挖矿的话,不仅以太币会停止生成,所有智能合约的调用也会不起作用。
  3. 如果真的要停止挖矿,可以执行命令miner.stop()来停止挖矿
  4. 按上面的命令,应该是可以实现以太坊挖矿的。如果不行的话,有可能就是之前有存在的链,此时应该删除之前的数据。在Mac下即删除~/.ethash文件夹和里面的文件即可

查看主帐户的以太币数量

> acc0 = eth.accounts[0]
"0x390410e96d77e47847e719e0ea06d72a3f1b624c"
> eth.getBalance(acc0)
0

看起来是挖矿有问题,日志显示第二次

INFO [12-28|15:23:30] Generated ethash verification cache      epoch=1 elapsed=1m58.982s

就卡住不动了!


记得前面创建创世区块时有个错误,先去解决看看!
删除目录下除genesis.json外的所有文件和目录,修改genesis.json文件加入config相关字段,如下:

{
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x00",
  "gasLimit": "0x80000000",
  "difficulty": "0x1",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {     },
    "config":{
      "chainId":15,
      "homesteadBlock":0,
      "eip155Block":0,
      "eip158Block":0
  }
}

再次执行创建命令:

Chaim:ethPri Chaim$ geth --datadir "./" init genesis.json
WARN [12-28|15:55:57] No etherbase set and no accounts found as default 
INFO [12-28|15:55:57] Allocated cache and file handles         database=/Users/Chaim/Documents/workspace/ethPri/geth/chaindata cache=16 handles=16
INFO [12-28|15:55:57] Writing custom genesis block 
INFO [12-28|15:55:57] Successfully wrote genesis state         database=chaindata                                              hash=6099b6…abe624
INFO [12-28|15:55:57] Allocated cache and file handles         database=/Users/Chaim/Documents/workspace/ethPri/geth/lightchaindata cache=16 handles=16
INFO [12-28|15:55:57] Writing custom genesis block 
INFO [12-28|15:55:57] Successfully wrote genesis state         database=lightchaindata                                              hash=6099b6…abe624

这次没有报错了,继续以上剩余过程看看!

Chaim:ethPri Chaim$ geth --datadir "./" --nodiscover console 2>>geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable/darwin-amd64/go1.9.2
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> eth.accounts
[]
> personal.newAccount("123456")
"0x54b865714068f5f03574ace39a1f3279c4e83e2c"
> eth.accounts
["0x54b865714068f5f03574ace39a1f3279c4e83e2c"]
> miner.start()
null
> acc0 = eth.accounts[0]
"0x54b865714068f5f03574ace39a1f3279c4e83e2c"
> eth.getBalance(acc0)
50000000000000000000
> 

这次查看帐号的确挖到了,日志文件也显示正常挖矿了,如下:

INFO [12-28|16:02:17] Generating DAG in progress               epoch=0 percentage=96 elapsed=53.579s
INFO [12-28|16:02:17] Generating DAG in progress               epoch=0 percentage=97 elapsed=54.184s
INFO [12-28|16:02:18] Generating DAG in progress               epoch=0 percentage=98 elapsed=54.785s
INFO [12-28|16:02:19] Generating DAG in progress               epoch=0 percentage=99 elapsed=55.534s
INFO [12-28|16:02:19] Generated ethash verification cache      epoch=0 elapsed=55.536s
INFO [12-28|16:02:20] Successfully sealed new block            number=1 hash=34fd21…7c3776
INFO [12-28|16:02:20] 🔨 mined potential block                  number=1 hash=34fd21…7c3776
INFO [12-28|16:02:20] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=113.005µs
INFO [12-28|16:02:21] Successfully sealed new block            number=2 hash=df1f6d…f30144

交易

建立一个新帐号,并且进行交易:

> acc0 = eth.accounts[0]
"0x54b865714068f5f03574ace39a1f3279c4e83e2c"
> personal.newAccount("123456")
"0x469f07278600b1cb031448fd25f187f24a89ecb6"
> acc1 = eth.accounts[1]
"0x469f07278600b1cb031448fd25f187f24a89ecb6"
> eth.getBalance(acc1)
0
> amount = web3.toWei(1)
"1000000000000000000"
> eth.sendTransaction({from:acc0, to:acc1, value:amount})
Error: authentication needed: password or unlock
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at <anonymous>:1:1

> 

报错了,查询是以太坊的保护机制,每隔一段时间帐户就会自动锁定,这个时候任何以太币在账户之间的转换都会被拒绝,除非把该账户解锁。

> personal.unlockAccount(acc0)
Unlock account 0x54b865714068f5f03574ace39a1f3279c4e83e2c
Passphrase: 
true
> eth.sendTransaction({from:acc0, to:acc1, value:amount})
"0x678490d8e86e4d61cb3aa45992b7eb0f0809f41d9b2ef4b2dd74adbb70366a72"
> eth.getBalance(acc1)
1000000000000000000

解锁后再交易就成功了!

停止挖矿交易就没法进行,来试一下!

> miner.stop()
true
> eth.sendTransaction({from:acc0, to:acc1, value:amount})
"0x258cf41b049f41149b7770639e7f9d0c94ecebac8ac8a3b2627923d7894fcdc0"
> eth.getBalance(acc1)
1000000000000000000
> txpool.status
{
  pending: 1,
  queued: 0
}

的确是这样,虽然交易提交了但是并没有被执行,用txpool.status可以查看正在处理的交易。

停止挖矿后,我的电脑也安静了,刚才风扇吹得哗哗响!
重新挖矿看看交易是不是马上完成了!

> miner.start()
null
> txpool.status
{
  pending: 0,
  queued: 0
}
> eth.getBalance(acc1)
2000000000000000000

ether和Wei之间转换

> web3.toWei(1)
"1000000000000000000"
> web3.toWei(2.3601)
"2360100000000000000"
> web3.fromWei(2000000000000000000)
"2"

重置以太坊私有链

如果链条已经被关闭的话,或者启动不了,或者挖矿无法产生比特币的话,可以重置以太坊私链。

重置以太坊私有链的方法
1.删除根目录下的隐藏文件夹.ethash, 在mac系统中该文件夹在 ~/下
2.删除以太坊私有链所在文件夹下的geth/keystore两个文件夹

建立快捷命令

以太坊私链搭建好了,Mist也装好了,为了防止电脑重启以后又不知道怎么启动这么多命令,把要执行的命令记录备查。

cmd1 运行私链
cd /Users/Chaim/Documents/workspace/ethPri
geth --datadir "./" --nodiscover console 2>>geth.log

    进入私链命令行后,启动挖矿
    miner.start()

cmd2 mist服务
cd /Users/Chaim/Documents/workspace/mist/interface
meteor --no-release-check

cmd3 启动mist
cd /Users/Chaim/Documents/workspace/mist
yarn dev:electron . --rpc /Users/Chaim/Documents/workspace/ethPri/geth.ipc 

cmd4 私链日志
cd /Users/Chaim/Documents/workspace/ethPri
tail -f geth.log

参考

http://blog.csdn.net/qq_39733285/article/details/77253163

http://m.blog.csdn.net/vinsuan1993/article/details/75208203

http://www.8btc.com/eth-privatenetwork-testnet

***************************************

作者简介


老鱼,从事互联网技术十余年,知名上市公司CTO;炒股十余年,从亏损几十万到略有盈利;顺应创业大潮多次创业,在传统行业和手游行业有所获;研习佛学易理,性格淡泊清净!

欢迎有兴趣的朋友加入微信群和电报群,一起学习探讨,一起实现咱们的小目标!

  • 百分百区块链群,微信扫码后会再显示一个二维码,长按图片“识别图中二维码”加入!


Sort:  

Upvoted ☝ Have a great day!

Thank you! You too!

Coin Marketplace

STEEM 0.17
TRX 0.16
JST 0.029
BTC 61436.18
ETH 2381.46
USDT 1.00
SBD 2.55