JobPlus知识库 IT 大数据 文章
go-ethereum使用简介

前言

本篇文章简单介绍使用go-ethereum连接以太坊的主网和测试网以及一些基础开发须知,着重介绍如何搭建一个私网的以太坊,至于以太坊应用开发,有机会的话,将在后面的文章中重点介绍。

本篇文章中包含笔者花费大量心血理解并整理的配置和参数说明资料,望可以为诸位道友提供一些帮助。

安装

Go Ethereum可以安装的操作系统平台有Mac OS X,Windows以及Linux/Unix。

这里介绍在Linux上,从go-ethereum源码构建的安装流程。官方提到的Linux/Unix平台包括Ubuntu,Arch和FreeBSD。这里以Ubuntu为例。

编译环境准备

编译环境要求有 Go 和 C编译程序。安装方法如下:

apt-get install -y build-essential golang


获取源码并编译

获取源码

切换到你准备编译go-ethereum源码的目录,执行命令:

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


上述命令会clone go-ethereum的主干分支代码,该分支代码是持续开发代码,如果想要使用发布代码。这里以当时最新的发布代码 v1.8.7 为例: 
1. 下载代码

wget https://github.com/ethereum/go-ethereum/archive/v1.8.7.tar.gz


  1. 解压

tar zxvf v1.8.7.tar.gz


将解压后的代码移动到你准备编译go-ethereum源码的目录。

编译源码

当你准备好go-ethereum的源码后,进入go-ethereum源码工程顶级目录,执行命令:

make geth


(推荐)如果你想要编译出所有工具,执行:

make all


编译完成后,所有工具可以在 build/bin 目录下找到,将这些二进制文件取出来放到你选好的安装目录,或者就在原来的位置放着,这里我放到 /opt/xingweidong/eth/bin 目录下,接下来根据你的喜好设置系统环境变量,添加如下内容:

export ETH_HOME=/opt/xingweidong/eth

export PATH=$PATH:$ETH_HOME/bin


别忘了使用 source /etc/profile 或者其他你喜欢的方法更新你的环境变量信息。

运行geth

geth命令,主要的Ethereum CLI客户端,是Ethereum网(main-, test- 或 private网)的入口,有能力作为一个full node(默认)存档节点(保留所有历史数据)或者一个light node(现场检索数据)节点运行。经由暴露在HTTP, WebSocket 或 IPC传输的顶部的JSON RPC端点,它可以被其他过程用作Ethereum网的网关。

提示:查看 geth 所有命令行选项使用 geth –help 或者查看 CLI Wiki page。

Ethereum main网的full node

目前为止,大多数情况是人们想要简单地与Ethereum网进行交互:创建账户;转移资金;部署并与合约交互。对于这种特殊的使用情况,用户不关心以前的历史数据,所以我们能快速的同步当前的Ethereum网状态。执行命令:

geth console


命令作用: 
- 开始 geth 进入快速同步模式(默认模式,可以使用 –syncmode 选项改变同步模式),由于它为了避免处理整个Ethereum网的历史数据,会下载大量的事务数据,所以会占用大量CPU资源。 
- 启动 Geth 内在的交互式 JavaScript console,(经由 console 子命令)通过这个,你能调用所有官方 web3 methods 以及Geth自己的 management APIs。这个也是可选的,如果你离开,你能使用 geth attach 连接一个已经存在的 Geth 实例。

Ethereum test网的full node

向开发者过渡,如果你想要创造合约,你几乎肯定想要在没有任何真实资金的情况下做到这一点,直到你掌握整个系统。换句话说,代替连接到Ethereum main网,你会想要加入到一个 test网,它是和 main网完全等价的,只需要:

geth --testnet console


console子命令与上面的含义完全相同并且它们在一个测试网上也同样有用。如果你跳到这一步,请看上面对它们的解释。

然而,指定 –testnet 将重新配置你的 Geth 实例一小部分: 
- 代替使用默认数据目录(例如Linux上的 ~/.ethereum),Geth将会深入一层目录创建 testnet 子文件夹(在Linux上是 ~/.ethereum/testnet)。注意,在OSX和Linux上,这也意味着连接一个运行的testnet节点要求使用一个自定义的端点,因为 geth attach 默认将连接一个生产节点。例如:geth attach /testnet/geth.ipc。Windows用户不受影响。 
- 代替连接 Ethereum main网,客户端将连接到一个 test网,使用不同的P2P bootnodes,不同的网络ID和创世状态。

注意:尽管有一些内部安全措施防止main网和test网的交易互换,你也应该确认总是为测试资产和真实资产使用分开的账户。除非你手动移动账户,Geth将默认正确分开两个网络,并且在它们之间将不会有任何账户可用。

Rinkeby test网的full node

上述测试网络是基于ethash工作证明共识算法的跨客户端网络。因此,由于网络的低难度/安全性,它有一定的额外开销,并且更容易受到重组攻击。Go Ethereum还支持连接到称为Rinkeby的权威证明测试网络(由社区成员运营)。这个网络更轻,更安全,但只受到go-ethereum的支持。

geth --rinkeby console


配置

代替传递大量选项给 geth 二进制,你能传递一个配置文件经由:

geth --config /path/to/your_config.toml


为了理解这个文件的写法,你能使用 dumpconfig 子命令export你的现有配置:

geth --your-favourite-flags dumpconfigeg:

geth --testnet dumpconfig


注意:这个只在 geth v1.6.0以及以上版本有效。

Docker quick start

通过使用Docker,你可以在你的机器上快速启动Ethereum并运行:

docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \

           -p 8545:8545 -p 30303:30303 \

           ethereum/client-go


上述命令将以快速同步模式启动geth,并具有1GB的DB内存容量。它也将在你的home目录下创建一个永久卷来储存你的区块链和映射的默认端口。还有一个 alpine 标签可用于image的精简版本。

如果你想要从其他容器或主机访问RPC,不要忘了 –rpcaddr 0.0.0.0。默认情况下,geth 绑定本地接口并且不可从外访问RPC端点。

可编程接口 Geth nodes

作为一个开发者,你将想要及早开始经由你自己的程序而不是手动控制台与Geth和Ethereum网交互。为此,Geth已经内置支持一个基于APIs的JSON-RPC。它能够经由HTTP, WebSockets 和 IPC (unix sockets on unix based platforms, and named pipes on Windows)暴露。

IPC接口默认是激活的并暴露所有Geth支持的APIs,然而HTTP 和 WS接口需要手动激活并且由于安全原因只能暴露一个APIs子集。这些可以根据你的需要打开或关闭并被配置。


操作一个私网

维护你自己的私网是十分复杂的,因为在一个正规的网络中,大量配置的获取和授权需要手动设置。下面,我们建立一个简单的私网以太坊。

说明:为了使下面创建私网以太坊的步骤更加直白,笔者将默认使用以下的geth选项值(请自行查看选项含义): 
- –datadir /root/privatenet/.ethereum 
- –config config/privatenet.toml

在开始之前,笔者先介绍一下如何创建以太坊账户: 
- 创建主网以太坊账户,执行命令:

geth account new


  • 创建私网以太坊账户,执行命令:

geth --datadir /root/privatenet/.ethereum account new


按照提示输入账户密码即可。

注意:创建私网以太坊账户时,务必指定 –datadir 选项,否则会默认创建主网以太坊账户。

定义一个私有的创世状态

首先,你需要创造你的网络的所有节点需要意识到并同意的创世状态。这个由一个小JSON文件组成(例如,称它为 genesis.json):

{

  "config": {

        "chainId": 15,

        "homesteadBlock": 0,

        "eip155Block": 0,

        "eip158Block": 0

    },

  "alloc"      : {},

  "coinbase"   : "0x0000000000000000000000000000000000000000", 

  "difficulty" : "0x20000",

  "extraData"  : "",

  "gasLimit"   : "0x2fefd8",

  "nonce"      : "0x0000000000001993",

  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",

  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",

  "timestamp"  : "0x00"

}


参数说明(下表是笔者参考go-ethereum源码README和ethereum_yellow_paper整理所得,如有错误,请帮忙指正):

上面这些域应该可以满足大多数需求,不过我们建议改变 nonce 为一些随机值,这样你就能阻止不知名的远程节点访问你。如果你想要为了更早测试,预储备一些账户,你能在 alloc 域进行账户配置:

"alloc": {

  "0x0000000000000000000000000000000000000001": {"balance": "111111111"},

  "0x0000000000000000000000000000000000000002": {"balance": "222222222"}

 }


随着创世状态定义在上面的JSON文件,你应该在启动每个节点之前,优先初始化它,以确认所有区块链参数被正确设置:

geth --datadir /root/privatenet/.ethereum init genesis.json


启动bootstrap

当所有你想要运行的节点初始化到期望的创世状态,你将需要开始一个bootstrap节点,其他节点可以使用它在你的网络或因特网中找到彼此。干净的方式是配置并运行一个独立的bootnode: 
1. 每个ethereum节点,包括一个bootnode,通过一个enode标识符联系。这些标识符源自一个key。于是你将需要给bootnode这样一个key。因为我们当前没有这样的key,所以我们可以在bootnode启动前生成一个key(并存储它到一个文件):

bootnode -genkey bootnode.key


  1. 为了bootnode每次启动都使用相同的enode,需要在bootnode启动时指定一个key:

bootnode -nodekey bootnode.key


当bootnode上线,它将展示一个 enode URL,例如:

INFO [05-09|01:47:05] UDP listener up                          self=enode://75535ebac1f5b2a644edb134dbe91c6c288353be1a5301864edae529630b35c5ff0c0ae9e07b2bcdef578c3ac1b72b2cda105c061c2c77067f1fd8ec54d852b7@[::]:30301


其他节点可以使用这个 enode URL 连接它并交换对等信息。确认用你的外部访问IP替换展示的IP地址信息(很可能是 [::])去得到真正的 enode URL。例如:

enode://75535ebac1f5b2a644edb134dbe91c6c288353be1a5301864edae529630b35c5ff0c0ae9e07b2bcdef578c3ac1b72b2cda105c061c2c77067f1fd8ec54d852b7@192.168.1.214:30301

  • 1

保存这个准确的 enode URL 到你的一个文本中或者其他什么地方,下面需要用到。

注意:你也可以使用完全成熟的Geth节点作为引导节点,但这是不太推荐的方式。

定义一个配置文件

为了成员节点启动时使用的配置一致,需要写一个配置文件,例如 privatenet.toml(参考自 testnet 的配置, 执行命令 geth –testnet dumpconfig 可见):

# Note: this config doesn't contain the genesis block.

[Eth]

NetworkId = 3369

DatabaseCache = 768

GasPrice = 18000000000 


 [Eth.Ethash]

CacheDir = "ethash"

CachesInMem = 2

CachesOnDisk = 3

DatasetDir = "/root/privatenet/.ethash"

DatasetsInMem = 1

DatasetsOnDisk = 2 


 [Eth.TxPool]

NoLocals = false

Journal = "transactions.rlp"

Rejournal = 3600000000000

PriceLimit = 1

PriceBump = 10

AccountSlots = 16

GlobalSlots = 4096

AccountQueue = 64

GlobalQueue = 1024

Lifetime = 10800000000000 


 [Eth.GPO]

Blocks = 20

Percentile = 60 


 [Shh]

MaxMessageSize = 1048576

MinimumAcceptedPOW = 2e-01 


 [Node]

DataDir = "/root/privatenet/.ethereum"

IPCPath = "geth.ipc"

HTTPPort = 8545

HTTPVirtualHosts = ["localhost"]

HTTPModules = ["net", "web3", "eth", "shh"]

WSPort = 8546WSModules = ["net", "web3", "eth", "shh"] 


 [Node.P2P]

MaxPeers = 25

NoDiscovery = false

BootstrapNodes = ["enode://75535ebac1f5b2a644edb134dbe91c6c288353be1a5301864edae529630b35c5ff0c0ae9e07b2bcdef578c3ac1b72b2cda105c061c2c77067f1fd8ec54d852b7@1 92.168.1.214:30301"]

StaticNodes = []

TrustedNodes = []

ListenAddr = ":30303"

EnableMsgEvents = false 


 [Dashboard]

Host = "localhost"

Port = 8080

Refresh = 5000000000



配置说明(下表是笔者参考geth参数说明和go-ethereum相关配置项代码整理所得,如有错误,请帮忙指正):


在你的操作目录创建config文件夹,将写好的配置文件privatenet.toml移动到config目录里。

启动你的成员节点

以太坊的成员节点,之间是完全对等的,每个节点都可以有多个账户。

启动私网以太坊的成员节点:

geth --config config/privatenet.toml


连接到刚刚启动的或者已经在运行的node,开始一个交互式JavaScript环境:

geth attach privatenet/.ethereum/geth.ipc


官方说明: 当bootnode运转起来并且外部可达(你能尝试 telnet 去确认它的确可达),开始随后的Geth节点,为了对等发现,经由 –bootnodes 选项指向bootnode。保持你的私网的数据目录单独将很可能是明智的选择,所以也指定一个自定义的 –datadir 选项。

geth --datadir=path/to/custom/data/folder --bootnodes=<bootnode-enode-url-from-above>


注意:因为你的网络将被从main和test网完全切除,所以你将需要配置一个 miner 去处理交易并为你创造新块。

运行一个私有的miner

公共Ethereum网的mining是一个复杂的任务,因为它唯一可行的是使用GPUs,要求一个OpenCL 或 CUDA激活 ethminer 实例。更多信息请查阅 EtherMining subreddit和 Genoil miner 仓库。

然而在一个私网的设置,一个单一的 CPU miner实例是足够满足实际需求的,因为它不需要沉重的资源(考虑到运行在一个单一的线程上,也不需要多个)就能在一个正确的间隔内生产一个稳定的区块流(stable stream of blocks)。为mining开始一个Geth实例,指定你通常使用的选项运行它,通过以下方法扩展:

geth --config config/privatenet.toml --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000


这将开始mining区块并在一个单一CPU线程上交易,存入所有事件到一个 –etherbase 选项指定的账户,如果不指定账户,则会默认指定当前节点上的第一个账户。你能进一步调节mining,通过(–targetgaslimit)改变默认gas限制区块并且在(–gasprice)处接受价格交易。

另外,也可以在交互式JavaScript环境中控制mining实例: 
- 开始一个4线程的mining实例:

miner.start(4)


  • 停止mining实例:

miner.stop()


更多Mining相关信息,请参看Mining

至此,私网以太坊搭建完成,感谢阅读!


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
270人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

0 人收藏了这篇文章
腾讯云数据库性能卓越稳定可靠,为您解决数据库运维难题
广告
扫码APP

扫描使用APP

扫码使用

扫描使用小程序