使用Geth 构建以太坊区块链并模拟挖矿过程

Go-ethereum 是以太坊官方的一个Golang 实现,我们可以使用Geth 工具来创建创世区块并启动区块链,使用Clef 实现以太坊钱包的功能,以及使用evm、puppeth 用来以太坊开发。本次我们使用Geth,在两台Host 上,创建一条以太坊区块链和两个账户,并进行区块链的一些基本操作。

我的网络环境中,Host1 的IP 地址为192.168.0.100,Host2 的IP 地址为192.168.0.180

本文绝大多数参考资料来源于Geth Documentation,在官方的文档里可以找到诸如Geth 安装使用、如何产生私有区块链、JSON-RPC APIs 的使用方法等,

1. 获得 Geth

Geth 在各个平台都可用,直接从https://geth.ethereum.org/docs/install-and-build/installing-geth 获取即可

在Windows 上,安装Geth,我们会获得几个可执行程序:

    Directory: C:\Users\sun\Desktop\geth

Mode                 LastWriteTime         Length Name
---- ------------- ------ ----
-a--- 2020/12/11 16:17 50280980 abigen.exe
-a--- 2020/12/11 16:17 48783481 bootnode.exe
-a--- 2020/12/11 16:17 63922102 clef.exe
-a--- 2020/12/11 16:18 49921889 evm.exe
-a--- 2020/12/11 16:18 67456679 geth.exe
-a--- 2020/12/11 16:18 26165842 puppeth.exe
-a--- 2020/12/11 16:18 2512896 rlpdump.exe

其中Geth 理论上已经被写进Path,在任何位置打开shell 都可用。

2. 准备

新建一个privatechain1文件夹,用来保存我们第一个区块链。geth需要一个创世配置文件genisis.json,来创建区块链,例如:

{
"config": {
"chainId": 10086,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"ethash": {}
},
"difficulty": "1",
"gasLimit": "80000",
"alloc": {}
}

此处我们定义chainID 为10086,使用PoW 共识机制,挖矿难度为1,没有初始资产

有关genesis.json 的详细格式可以参考:创世区块配置文件genesis.json的格式解读

3. 启动

创建好genesis.json后,就可以根据该配置创建区块链:

geth init --datadir . genesis.json

--datadir参数指定区块链相关文件的放置目录

随后启动区块链:

geth --networkid 191 --nodiscover --http --http.addr "0.0.0.0" --http.port 8545 --http.api personal,eth,net,web3 --allow-insecure-unlock --datadir . console

启动参数较多,分别为:

--networkid 网络ID。只有当NetworkID,ChainID,创世区块全部相同时,才是同一条区块链

--nodiscover 由于本次为实验环境,而且只有两台Host,我们可以关闭自动发现,手动添加Peers

--http 该区块链使用http协议。除了http,还可以使用websocket

--http.addr 监听地址,由于之后要在两台Host上传输数据,因此此处为0.0.0.0

--http.port 默认端口为8545

--http.api 可以允许使用http进行的一些操作,后续会详解

--allow-insecure-unlock 由于在本地做测试,为了方便不会配置https证书,加上这个参数可以在非HTTPS的环境下解锁账户

--datadir 指定区块链数据所在的目录

console 打开控制台

有关详细的Geth 启动参数,可以参阅Geth Command-line Options

启动成功后,会打开一个web3控制台,类似这样:

在Host2上重复上述操作,启动相同的区块链。

4. 操作

4.1 新用户

此时geth的任务已完成,我们开始使用 JSON RPC APIs 进行操作。

> eth.accounts
[]

可以看到目前还没有任何账户,新建一个账户:

输入personal.newAccount(),然后输入两次密码即可

可以看到我们的新账户地址为:0xf1d65f66658a3dfa86b689ce084fd3234fc3b691,并且在keystore目录下生成了一个文件。

再次查看eth.accounts,刚刚创建的新用户已出现:

> eth.accounts
["0xf1d65f66658a3dfa86b689ce084fd3234fc3b691"]

在Host2上重复上述操作,创建另一个新用户:

==============================================
Shell on Host2
============================================== > eth.accounts
["0xf228360fbf872e4aca7f930a60b18c6f1f6ca19e"]

4.2 添加Peers

尽管两台Host现在运行同一条区块链,但由于我们预先关闭了peers自动发现,因此目前并没有Peers。在Host1上查看:

> admin.peers
[]

要添加在Host1上添加Host2,我们需要得到Host2的网络地址。在Host2的控制台中向上翻,找到区块链启动时,出现的一个Strated P2P networking 信息:

INFO [01-26|01:02:40.182] Started P2P networking                   self="enode://c81e35213c6fd2824dafdd174b24aa0bb36e7ce935819d2ecf22a19a53aea5e760caf32e20bf3818ab129eb89efaa33ed841a542cd7ea973b60e2b95ef3953c5@127.0.0.1:30303?discport=0"

其中self的值就是Host2的网络地址,注意应该将127.0.0.1改为192.168.0.180

enode://c81e35213c6fd2824dafdd174b24aa0bb36e7ce935819d2ecf22a19a53aea5e760caf32e20bf3818ab129eb89efaa33ed841a542cd7ea973b60e2b95ef3953c5@192.168.0.180:30303?discport=0

回到Host1,执行以下操作:

admin.addPeer("enode://c81e35213c6fd2824dafdd174b24aa0bb36e7ce935819d2ecf22a19a53aea5e760caf32e20bf3818ab129eb89efaa33ed841a542cd7ea973b60e2b95ef3953c5@192.168.0.180:30303?discport=0")

一段时间后,发现peercount=1,再次查看peers

如果此步迟迟不能发现新Peer,可以尝试在Host2上添加Host1

4.3 挖矿

在以太坊中,每挖出一个新区块,矿工将会获得一定的奖励。奖励将会流入coinbase账户中。如果genesis.json没有指定默认的coinbase账户,则会流入eth.accounts[0]中。下面我们开始模拟挖矿过程。

要使用某一个账户进行挖矿、交易等操作,首先需要解锁账户,方便起见,给Host1上的第一个账户地址设一个变量sender:

> sender = eth.accounts[0]
"0xf1d65f66658a3dfa86b689ce084fd3234fc3b691"
> personal.unlockAccount(sender)
Unlock account 0xf1d65f66658a3dfa86b689ce084fd3234fc3b691
Passphrase:
true

然后开始挖矿:

miner.start(1)

其中参数1指进程数,可按Host性能设置。由于我们在genesis.json中将difficulty设置得很小,理论上不会消耗很多时间。挖矿开始后,不断提示Generating DAG in progress,当percentage到达100%时,会看到挖掘出新区块。

Host1会将挖到的区块作为交易销售出去,在区块链上留下交易痕迹

来到Host2,会发现Host1提交的新区块被同步

适时停止挖矿:

miner.stop()

在Host1上查看账户sender的账户余额:

> miner.stop()
null
> eth.getBalance(sender)
34000000000000000000

查看目前区块链上挖出区块数量,在Host1和Host2上理论上应该出现相同的结果:

> eth.blockNumber
17

这个数字和之前显示的INFO最后一个挖出的区块number对应:

INFO [01-26|12:34:00.697]  mined potential block                  number=17 hash="5ac61c…ee83ca"

4.4 转账

Host1上的第一个账户0xf1d65f66658a3dfa86b689ce084fd3234fc3b691,变量名为sender

Host2上的第一个账户0xf228360fbf872e4aca7f930a60b18c6f1f6ca19e,设置新的变量名为receiver

> receiver = "0xf228360fbf872e4aca7f930a60b18c6f1f6ca19e"

设置转账的amount,转出1个ETH,在以太坊上进行交易,需要将ETH 单位转为Wei 单位:

> amount = web3.toWei(1, "ether")

执行sendTransaction 操作:

> eth.sendTransaction({from: sender, to: receiver, value: amount})

如果出现Error: authentication needed: password or unlock,可能时时间过长,sender 账户又被加锁,重新解锁即可。

sendTransaction 执行之后,Host2 中的receiver 账户并不会立刻受到1ETH(即1000000000000000000Wei),之前提到过,要在区块链中留下数据,必须通过挖矿产生新区块,提交到区块链中。因此要使转账生效,我们需要开始挖矿,将交易数据打包到新区块中。

在此之前,先来看一下等待队列中的交易,输入eth.pendingTransactions

其中包含两个新参数gas 和gasPrice,是需要付给确认这笔交易的矿工的工资。

开始挖矿:

> miner.start(1)

挖到第一个区块就可以停止挖矿了:

> miner.stop()

在Host1 上挖到了新区块:

INFO [01-26|13:59:12.443]  mined potential block                  number=18 hash="675837…edf7ca"
INFO [01-26|13:59:13.060] Successfully sealed new block number=19 sealhash="58e4be…89b373" hash="15d1f0…7ca475" elapsed=638.999ms
INFO [01-26|13:59:13.060] block reached canonical chain number=12 hash="7c0bcf…76cec9"
INFO [01-26|13:59:13.088] Commit new mining work number=20 sealhash="18f1a8…de77c4" uncles=0 txs=0 gas=0 fees=0 elapsed=28.006ms

在Host2 上找到这个已经同步来的区块:

INFO [01-26|13:59:13.690] Imported new chain segment               blocks=1 txs=1 mgas=0.021 elapsed=7.991ms  mgasps=2.628 number=18 hash="675837…edf7ca" dirty=4.72KiB

此时在Host2 上查看receiver 的余额:

> receiver = "0xf228360fbf872e4aca7f930a60b18c6f1f6ca19e"
> eth.getBalance(receiver)
1000000000000000000

在Host1 上查看sender 余额:

> eth.getBalance(sender)
43000000000000000000

5. 总结

该篇章中我们使用Geth 生成了一条区块链,并在两个Host 上,用两个用户完成了挖矿和转账操作。下一篇章我们会着重理解以太坊的工作方式,入门智能合约。

作为以太坊初学者,本文很可能有概念理解上的错误,欢迎各位批评指正。

其他参考资料:

区块链入门(3):在以太坊私有网络中建立节点集群,并发生交易 - 88911562 - 博客园 (cnblogs.com)

私有链挖矿的时候,这个generating DAG好慢 有什么方法加快这个速度-链客区块链技术开发者社区 (liankexing.com)

以太坊基本概念与实验环境搭建 · float's blog (gitee.io)

使用Geth 构建以太坊区块链并模拟挖矿过程的更多相关文章

  1. geth搭建以太坊私链及常用操作

    一.下载安装geth客户端 https://www.ethereum.org/ 二.搭建私有链 1.准备创世区块配置文件 要运行私有链,我们就需要定义自己的创世区块,创世区块信息写在一个json格式的 ...

  2. 以太坊区块链Java(EthereumJ)学习笔记:概述

    本系列文章介绍以太坊区块链基于Java语言的解决方案.通过介绍EthereumJ定义的主要模块和Class,希望为大家学习和使用EthereumJ提供一些帮助. 整体架构 以太坊的Java解决方案主要 ...

  3. 区块链--Ubuntu上搭建以太坊私有链

    1.搭建私链所需环境 操作系统:ubuntu16.04,开虚拟机的话要至少4G,否则会影响测试挖矿时的速度 软件: geth客户端 Mist和Ethereum Wallet:https://githu ...

  4. 区块链学习(四)truffle部署编译智能合约以太坊私有链

    前面我们介绍了以太坊私有链的搭建以及多节点私有链网络,这次我们介绍如何使用truffle框架来部署编译智能合约到我们之前搭建的私有链网络中. 搭建环境及需使用的工具:ubuntu18.04  Truf ...

  5. 以太坊公链Geth同步

    1.安装所需基础工具 yum update -y && yum install git wget bzip2 vim gcc-c++ ntp epel-release nodejs c ...

  6. 以太坊联盟链 parity 节点搭建

    https://www.cnblogs.com/sumingk/articles/9097996.html 上一篇文章介绍了以太坊私有链 geth节点的搭建,本篇介绍下企业级应用 联盟链搭建,运用pa ...

  7. 使用 Go-Ethereum 1.7.2搭建以太坊私有链

    目录 [toc] 1.什么是Ethereum(以太坊) 以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约.开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球 ...

  8. 转:使用 Go-Ethereum 1.7.2搭建以太坊私有链

    使用 Go-Ethereum 1.7.2搭建以太坊私有链 目录 [toc] 1.什么是Ethereum(以太坊) 以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约.开源的底 ...

  9. Mac环境搭建以太坊私有链

    原文地址: 石匠的blog 为了测试以太坊智能合约,最方便的是在本地搭建一个以太坊私有链.在mac上搭建环境主要需要以下步骤. geth安装 geth是go-ethereum的简写,是一个用go语言编 ...

随机推荐

  1. MySQL高质量博文链接集合

    1. 『浅入浅出』MySQL 和 InnoDB https://draveness.me/mysql-innodb.html

  2. Sping高质量博文链接集合

    1. Spring事务传播行为详解 https://segmentfault.com/a/1190000013341344

  3. Docker consul的容器服务更新与发现(超详细配图)

    Docker consul的容器服务更新与发现 1.概述 2.部署 1.概述: (1)什么是服务注册与发现: 服务注册与发现是微服务架构中不可或缺的重要组件.起初服务都是单节点的,不保障高可用性,也不 ...

  4. CSS3带你实现3D转换效果

    前言 在css3中允许使用3D转换来对元素进行格式化,在原本只是2D转化的平面中引入了Z轴.在这之前我们讲解了css3中的2D转换,也就是二维空间变换,本篇的3D转换就是基于原来的2D转换而来,与2D ...

  5. sublime运行错误

      这是由于没有保存文档导致   说明: [Finished in 19.4s with exit code 1]-表示执行时间 [shell_cmd: python3 -u "/Volum ...

  6. 为什么大厂前端监控都在用GIF做埋点?

    什么是前端监控? 它指的是通过一定的手段来获取用户行为以及跟踪产品在用户端的使用情况,并以监控数据为基础,为产品优化指明方向,为用户提供更加精确.完善的服务. 如果这篇文章有帮助到你,️关注+点赞️鼓 ...

  7. ICLR 2018 | Deep Gradient Compression: Reducing the Communication Bandwidth for Distributed Training

    为了降低大规模分布式训练时的通信开销,作者提出了一种名为深度梯度压缩(Deep Gradient Compression, DGC)的方法.DGC通过稀疏化技术,在每次迭代时只选择发送一部分比较&qu ...

  8. Zookeeper应用之一:数据发布与订阅初体验

    Zookeeper到底是什么?可以从Zookeeper提供的功能来理解.本篇小作文就是使用其提供的功能之一:数据发布与订阅. 需求:服务端开启多个实例提供服务,客户端使用服务.如果服务端某个服务下线或 ...

  9. 定制Centos7.9镜像

    Ps:因为工作内容:有一部份是需要重装系统:系统版本镜像为centos7.9.可每次装完都需要下载一些基础包:最近因为设备过多:网卡名称太乱:导致做后续配置太繁琐:不规整:索性自己定制个系统: 搭建基 ...

  10. CobaltStrike逆向学习系列(15):CS功能分析-BOF

    这是[信安成长计划]的第 15 篇文章 0x00 目录 0x01 BOF功能分析 0x02 BOF功能执行 0x03 写在最后 其实在看过 RDI 与 DotNet 功能执行之后,BOF 的执行基本就 ...