第一行代码:以太坊(1)-建立本身的私有区块链

本文会利用以太坊客户端(geth)搭建一个私有区块链,并在这个私有区块链上挖矿,经过本文的案例,读者能够更深刻理解区块链、以太坊、挖矿的理论。css

经过阅读本文,您能够:linux

  • 掌握搭建以太坊开发环境的方法
  • 掌握geth的基本使用方法
  • 了解如何启动JavaScript控制台
  • 掌握创建一个私有区块链的步骤
  • 掌握如何在私有区块链上挖矿

1. 以太坊(Ethereum)开发环境搭建

在玩以太坊以前,首先要搭建以太坊的开发环境。第一步就是安装geth。那么geth是什么呢?geth(或称为go-ethereum)是以太坊节点的一个实现。也就是说,geth是一个客户端,用于链接以太坊网络。从geth的名 字能够看出,geth是用go语言实现的一个以太坊节点。那么为何须要这个节点呢?android

这是由于以太坊网络由多个节点组成,这些节点多是用不一样技术实现的。如geth就是官方的以太坊节点。经过这些节点能够用命令行方式直接访问区块链网络,如广播交易,发布智能合约等,但对于大多数用户来讲,都是非程序员出身,让他们经过命令行方式去操做以太坊网络是不可能的,因此就要求有图形化的操做界面来操做以太坊网络。但geth这样的节点是作不到的,所以,就须要像web3.js,web3.py这样的程序库,再配合JavaScript、Python实现可视化的以太坊客户端,但这些库是没法直接链接进以太坊网络的,他们只能链接像geth这样的以太坊节点,而后经过一塔发节点访问以太坊网络,因此geth其实同时起到客户端和服务端的做用。也就是说,geth是以太坊网络的客户端,是web3.js的服务端。nginx

安装geth也很是容易,能够直接到下面的官网下载不一样平台的geth安装程序。git

https://ethereum.github.io/go-ethereum/downloads程序员

访问上面的Url,会看到页面上面显示以下图所示的下载按钮。github

image.png

目前geth的最新版本是1.8.3,支持Linux、Mac OS X和Windows平台,读者能够根据实际状况下载相应平台的geth安装程序,也能够直接下载源代码(最后一个按钮),而后编译和安装geth,不过这种方式只适合于专业人员,对于初学者,并不推荐使用这种方式。web

(1)安装Windows版geth

Windows版安装程序是一个exe文件(geth-windows-amd64-1.8.3-329ac18e.exe或相似的文件名),直接双击安装便可。双击该文件会显示以下图所示的安装界面。apache

image.png

单击“I Agree”按钮会显示以下图所示的选择组件界面。json

image.png

建议读者将Geth和Development tools都选上,不然在用到相关工具时还须要安装。而后单击“Next”按钮进入下一个安装界面。该界面主要用于指定geth的安装目录,默认安装目录是“C:\Program Files\Geth”,若是读者不想将geth安装到这个目录,能够修改为其余目录,如“D:\geth”效果以下图所示。

image.png

接下来单击“Install”按钮开始安装geth。安装的过程会显示当前安装进度的百分比,直到最后显示“Completed”,表示已经安装成功,以下图所示。最后单击“Close”按钮关闭安装界面。

image.png

Windows版的geth其实就是一些exe文件,以下图所示。其中geth.exe是本书主要使用的工具。

image.png

安装完geth后,最好将geth.exe文件所在的目录加到PATH环境变量中,这样在任何目录下就均可以使用geth.exe文件。

(2)安装Mac OS X版geth

Mac OS X版安装程序是一个压缩文件(geth-darwin-amd64-1.8.3-329ac18e.tar.gz或相似的名字),将该压缩文件解压,会发现只有一个geth可执行文件,以下图所示。

image.png

若是要想下载Mac OS X版的geth相关工具,能够到图2-1所示页面下方选择相应的操做系统,下载Tools压缩包或安装程序(点击Geth&Tools 1.8.3便可下载相应操做系统的Tools),以下图所示。为了使用方便,能够将geth所在的路径加到/etc/profile文件的PATH变量中,而后执行source /etc/profile命令,让配置当即生效。这样在任何目录下均可以使用geth。

image.png

在Mac OS X下还可使用brew命令安装以太坊开发环境。

brew tap ethereum/ethereum brew install ethereum 

读者能够选择本身喜欢的方式在Mac OS X下安装以太坊开发环境。

(3)安装Linux版geth

Linux版的geth与Mac OS X版的geth差很少,安装程序一样是一个压缩文件(geth-linux-amd64-1.8.3-329ac18e.tar.gz或相似的文件名),将该压缩文件复制到Linux的某个目录,而后在Console中进入该目录,执行以下的命令对该文件解压。

tar zxvf geth-linux-amd64-1.8.3-329ac18e.tar.gz

解压后,仍然只有一个geth可执行文件,这个可执行文件是静态编译的,在任何Linux发行版上均可以独立执行。

在Linux下安装完geth后,最好将geth文件所在的路径添加到PATH变量中,设置的方法与Mac OS X相似。

2. 使用geth命令建立以太坊帐户

安装完geth,须要测试一下,能够在控制台输入geth version命令(用于查看geth的版本信息),若是输出相似下图所示的信息,表示geth已经安装成功。

image.png

在Windows下执行geth version命令,也会获得与图2-9相似的版本信息,只是部分信息稍有差别,以下图所示。

image.png

使用geth的第一步就是建立帐户。以太坊的帐户用40位十六进制的地址表示,以下面的十六进制数就是一个标准的以太坊帐户地址(前面的0x表示十六进制)。

0x24924f33a9c49d312a8d885ade76ece76b315982

第一次使用geth时,geth中没有任何帐户,因此首先须要使用geth命令建立以太坊帐户。在建立以太坊帐户以前,可使用下面的命令查看以太坊当前的帐户。

geth account list

执行上面的命令,会显示以下图所示的信息,很明显,没有任何帐户。

image.png

如今使用geth account new命令建立以太坊帐户,在建立的过程当中要求输入帐户的密码。若是最后输出了一个以太坊地址,就说明帐户建立成功了,以下图所示。该地址就是以太坊帐户。

image.png

可使用一样的方法多建立几个以太坊帐户。而后使用geth account list命令查看以太坊当前的帐户,会获得以下图所示的查询结果。根据查询结果显示,以太坊当前有3个帐户。

image.png

3. 删除以太坊帐户

geth并无直接提供删除以太坊帐户的命令,不过能够经过删除帐户本地文件的方式删除以太坊帐户(由于每个以太坊帐户对应一个文件)。根据上图所示的以太坊帐户信息,能够得知帐户文件的存储路径以下:

/Users/lining/Library/Ethereum/keystore

进入该目录,会看到以下图所示的3个文件,分别对应上一节创建的3个以太坊帐户。若是要删除某个以太坊帐户,只须要删除对应的文件便可,而后再次执行geth account
list命令,会发现与文件对应的以太坊帐户消失了。

image.png

在Windows中的操做与Mac OS X相同,只是保存帐户文件的路径不一样。在Windows下使用一样的方式建立3个以太坊帐户,而后使用geth account list命令列出全部的帐户,以下图所示。

image.png

从上图所示的帐户信息可知,保存帐户文件的路径以下:

C:\Users\androidguy\AppData\Roaming\Ethereum\keystore

其中androidguy是Windows用户名,请将其改为本身机器的用户名。

4. geth JavaScript控制台

geth能够经过JavaScript控制台和JavaScript代码访问以太坊网络。只须要执行geth console命令,就能够启动JavaScript控制台,在该控制台能够直接输入JavaScript代码,按Enter键会执行输入的JavaScript代码,不过有一个问题,就是geth命令同时也负责同步区块,以及其余工做,这样会产生大量的日志信息,这些日志信息会与JavaScript代码交替出现,很是烦人。效果以下图所示。

image.png

为了避免让日志信息在JavaScript控制台输出,可使用下面的命令启动JavaScript控制台,其中2表示日志管道,也就是将日志信息直接输出到geth.log文件。

geth console 2>>geth.log

执行上面的命令,会进入JavaScript控制台,在控制台中,除了输入的JavaScript代码和执行结果外,什么都不会输出,效果以下图所示。

image.png

在Windows下使用一样的操做会获得与Mac OS X下彻底同样的效果,以下图所示。

image.png

JavaScript控制台并非简简单单用来执行JavaScript代码的,其实这个控制台能够经过web3.js API直接访问以太坊网络。web3.js就是一套API,支持Web和Node.js。可能不少读者看到这些估计有些懵,一下抛出这么多概念,又是web3.js,又是Node.js。这些技术会在本书后面详细介绍,本节只要知道在JavaScript控制台可使用JavaScript代码访问以太坊网络就能够了。若是使用geth console命令进入JavaScript控制台,并不须要单独安装web3.js,直接就可使用web3.js的API。

在JavaScript控制台中内置了不少JavaScript对象,其中web3就是其中最重要的对象。当启动JavaScript控制台后,这些对象会自动建立,能够直接使用。例如,能够直接在JavaScript控制台中执行下面的JavaScript代码。

str = web3.fromAscii('ethereum') // 将'ethereum'按ASCII转换为十六进制数 web3.toDecimal('0xa') // 将十六进制数(0xa)转换为十进制数 // 判断地址是否有效 isAddress = web3.isAddress("0x8888f1f195afa192cfee860698584c030f4c9db1");

这些命令执行的效果以下图所示。在Windows中的JavaScript控制台也会获得彻底相同的效果。

image.png

使用web3.js API的方式有不少,除了在JavaScript控制台中使用web3.js API外,至少还能够在下面的环境中使用web3.js。

• 浏览器

• Node.js

• IPython

• Jupyter Notebook

5. 创建私有区块链与挖矿

本节会利用geth命令建立一个私有区块链,而后本身挖矿,能够经过这个操做过程更深刻理解以太坊和区块链的概念。

建立私有区块链的步骤以下:

(1)创建创世块

区块链是由若干个区块组成的。在私有链启动后,须要为区块链建立第一个区块(创世块),至关于数据结构中链表的头节点。不过以太坊并不知道如何建立这个创世块,须要咱们告诉以太坊如何建立,所以,首先须要创建一个创世块的描述文件,这个描述文件是JSON格式的,本例起名为block.json,代码以下:

block.json文件

文件位置:src/chapter2/block.json

{
    "config": { "chainId":15, "homesteadBlock":0 }, "difficulty":"20", "gasLimit":"2100000", "alloc":{ "7df9a875a174b3bc565e6424a0050ebc1b2d1d82":{"balance":"300000"}, "f41c74c9ae680c1aa78f42e5647a62f353b7bdde":{"balance":"400000"} } }

一个完整的区块描述文件很是复杂,本例只对区块进行了一些基本设置,这些设置项的描述以下:

• chainId:指定了独立的区块链网络 ID。网络 ID
在链接到其余节点的时候会用到,以太坊公网的网络 ID 是 1,为了避免与公有链网络冲突,运行私有链节点的时候要指定本身的网络 ID。不一样 ID 网络的节点没法相互链接。

• homesteadBlock:以太坊推出的第2个主要的区块发行版本,Frontier是第1个推出的区块发行版本(也是测试版本)。建议使用homesteadBlock,这里的0表示有效。

• difficulty:挖矿的难易程度,该值越小,挖矿越容易。也就是说,该值越小,挖矿须要的算力越小,在测试时,建议设置一个比较小的值,不然挖矿会须要很长时间。

• gasLimit:挖每一个区块须要消耗资源的上限,gas与以太币(ether)同样,都是以太坊中的单位。之因此将gas与ether分开,是为了防止ether的波动对挖每一个区块消耗资源的影响。

• alloc:为了测试挖矿,临时分配的帐户,其中balance表示当前帐户的余额,单位是Wei。

(2)初始化区块链

这一步须要使用以下的命令对区块链进行初始化。

geth init block.json --datadir test

其中test表示与区块链相关数据保存的目录,本例test与block.json文件在同一个目录下。执行上面的命令后,会在当前block.json文件所在的目录生成一个test子目录。test子目录的结构以下图所示。

image.png

很明显,在test目录下面还有两个子目录:geth和keystore。其中geth目录保存了同步区块链以及相关的数据,keystore目录保存了帐户文件。因为私有链刚建立,尚未建立帐户,因此keystore目录为空。
若是在Windows下执行前面初始化区块链的命令,会获得与Mac OS X下彻底同样的结果。读者能够本身在Windows作实验。

(3)启动以太坊客户端(geth)

在这一步使用下面的命令启动以太坊客户端(进入JavaScript控制台)。其中datadir命令行参数表示geth会使用test目录保存相关文件。

geth --datadir test console

(4) 将帐户与矿工绑定

负责挖矿的帐户称为矿工。miner是JavaScript控制台中内置的矿工对象,在Java可使用下面的命令将block.json文件中的两个地址中的一个与miner对象绑定。

miner.setEtherbase("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") 

(5)开始挖矿

在开始挖矿以前,可使用下面的命令查一下两个临时帐号的余额。

eth.getBalance("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") eth.getBalance("0xf41c74c9ae680c1aa78f42e5647a62f353b7bdde") 

查询结果分别是300000和400000。如今矿工(miner)已经和余额为300000的帐户绑定,接下来在JavaScript控制台执行以下的代码开始挖矿。

miner.start()

执行这行代码后,就会开始挖矿,若是要中止挖矿,须要在JavaScript控制台执行以下的代码。

miner.stop()

中止挖矿后,能够执行下面的代码查询当前区块链中的区块数,其中eth是JavaScript控制台内建的对象。在本例中一共挖了36个区块,也就是目前在网络中有一条由36个区块组成的区块链。

eth.blockNumber

再次使用下面的代码查询两个临时帐户的余额。

eth.getBalance("0x7df9a875a174b3bc565e6424a0050ebc1b2d1d82") eth.getBalance("0xf41c74c9ae680c1aa78f42e5647a62f353b7bdde")

咱们会发现与矿工(miner)绑定的帐户的余额变多了,多出的余额就是挖矿的奖励(以太币),以下图所示。

image.png

在Windows下执行一样的命令会得到相同的结果(挖了30个区块),以下图所示。

image.png

(6)控制挖矿数量

有时须要控制挖矿数量,也就是说,挖到指定数量的区块后自动终止挖矿,要达到这个目的,须要在JavaScript控制台执行下面的命令。

miner.start(3); admin.sleepBlocks(10); miner.stop();

其中start方法的参数表示挖矿使用的线程,默认值是CPU内核的数量,如CPU是双核的,那么线程数就是2。sleepBlocks方法的参数表示要挖的区块数,本例是10个区块。若是尚未挖完10个区块,那么sleepBlocks方法会处于阻塞状态,直到挖完10个区块,会继续执行下面的代码,也就是miner.stop(),这时挖矿就会结束。

相关文章
相关标签/搜索