【区块链】02.区块链从0到1—搭建ETH私有链

By | 5月 26, 2023

前面提到最近在学习区块链,在Linux部署区块链时先准备GO运行环境,下面记录如何实现在Ubuntu一步一步部署ETH私有链。

安装geth客户端

打开终端,依次执行以下命令
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get install ethereum

预计下载半小时

下载安装完成后,执行命令,看到如下内容即安装成功

搭建私有链的data目录并进入

ubuntu@VM-20-9-ubuntu:/home$ sudo mkdir /home/private_eth

ubuntu@VM-20-9-ubuntu:/home$ cd private_eth/

ubuntu@VM-20-9-ubuntu:/home/private_eth$

创建第一个创世块文件genesis.json,上传到上方目录

安装geth客户端

  1. 打开终端,依次执行以下命令

sudo apt-get update
  189  sudo apt-get install software-properties-common
  190  sudo add-apt-repository -y ppa:ethereum/ethereum
  191  sudo add-apt-repository -y ppa:ethereum/ethereum-dev
  192  sudo apt-get install ethereum

预计下载半小时

下载安装完成后,执行命令,看到如下内容即安装成功

ubuntu@VM-20-9-ubuntu:~$ geth -h

创建私有链的data目录并进入

ubuntu@VM-20-9-ubuntu:/home$ sudo mkdir /home/private_eth
ubuntu@VM-20-9-ubuntu:/home$ cd private_eth/
ubuntu@VM-20-9-ubuntu:/home/private_eth$ 

创建第一个创世块文件genesis.json,上传到上方目录

创世块文件genesis.json 的内容如下:

{
  "config": {
    "chainId": 666,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "ethash": {}
  },
  "nonce": "0x0",
  "timestamp": "0x5ddf8f3e",
  "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x47b760",
  "difficulty": "0x00002",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": { },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

创世块文件genesis.json 的内容说明如下:

config

config是决定私链设置的核心配置。

chainId:链ID,用于标识当前这条链,主要用于重放保护。

homesteadBlock:以太坊“家园”版本启用的区块高度,homesteadBlock被设置为0则意味着我们将直接使用以太坊的“家园”版本,在以太坊主网中此设置为0.

eip150Block:第150号以太坊改进提案(EIP150)启用的区块高度,该提案主要用于解决因denial-of-service问题导致gas价格提高的问题主网中其启用高度为2463000。

eip155Block:EIP155提案启用的区块高度,该提案主要是为了预防重放攻击。

eip158Block:EIP158提案启用的区块高度,该提案的提出主要是为了改变以太坊客户端处理空账户的方式。在EIP158提案中以太坊客户端会将空账户视为不存在的对象,这能有效节省区块链上的存储空间。

byzantiumBlock:拜占庭硬分叉启用的区块高度,最大的改动是将出块奖励从5ETH减少到了3ETH,主网中该分叉的启用区块高度为4370000。

constantinopleBlock:君士坦丁堡硬分叉启用的区块高度,该分叉的目的是提高以太坊的运行效率,并移除/推迟难度炸弹,同时将出块奖励从拜占庭硬分叉后的3ETH减少为2ETH。主网中君士坦丁堡硬分叉的启用区块高度为7280000。

petersburgBlock:圣彼得堡硬分叉启用的区块高度,该硬分叉是为解决君士坦丁堡硬分叉中的安全漏洞问题,将EIP1283提案移除。主网中圣彼得堡和君士坦丁堡分叉同时激活,区块高度为7280000。

ethash:标识当前私链使用的共识算法为ethash。

mixhash

一个256为的哈希散列,结合nonce一同证明已在此区块上执行了足够量的计算(POW)。nonce和mixhash的组合必须满足黄皮书4.3.4中描述的数学条件,即区块头有效性(44)。它允许验证该区块是否被加密挖掘。

 nonce

一个用于标记发送方发送的交易数量的值,是一个64位哈希值,与mixhash值一起证明已在区块上进行了足够量的计算。

difficulty

出块难度,对应发现该区块的nonce期间所应用的难度级别,难度越高,矿工发现有效区块所需的计算就越多。该值主要用于控制出块时间,使得出块效率保持在目标范围之内。

alloc

预定义的钱包列表,可以通过该字段预先在指定钱包地址内预存一定数量得原生代币。这是以太坊预售期间所执行得特定功能。

coinbase

一个160位地址,用于标识出块奖励的收益地址。

timestamp

时间戳,相当于Unix中的time()函数的输出。引入时间戳的机制能够在时间方面实现出块的稳态,时间戳还允许验证出块顺序。(黄皮书,4.3.4.(43))。

parentHash

整个父块头的Keccak256位哈希(包括父块头的nonce和mixhash),若区块是创世区块,则该值为0。

extraData

一个可以自由设置的选项,最大32个byte。该字段用于将数据保存在区块链上

gasLimit

每个区块的gas消耗限制。每个区块所消耗的gas不能超过这个值。

初始化私有链的数据域,相关命令及初始化成功的效果如下图

/* 
 * --datadir:指定私链数据的存放目录.当要在同一计算机中创建其他私链节点时,可创建另外的文件夹,例如data2。
 * 然后通过--datadir data2区分不同的私链节点,如果未设置--datadir,则会读取以太坊主网的数据,
 * 默认位置在/root/.ethereum中。
 * */
$ geth --datadir /home/private_eth/ init genesis.json

执行如下命令,启动私有链:

## --datadir 表示当前区块链网络数据存放的位置
## --nodiscover 表示该链禁止被其他节点发现
## console 2>>geth.log 表示将日志输出到geth.log。可以打开另外一个控制台执行 tail -f 查看日志
geth --datadir /home/private_eth/  --networkid 13010 --nodiscover console 2>>geth.log

还有一种启动方式,其作用是启动PRC通信,最后实现的效果跟上方是一样的,启动命令如下:

# --http 打开rpc功能,用于api调用
# --http.addr xx.xx.xx.xx 设置rpc地址
# --http.port 8545 设置rpc端口 默认8545
# --http.api="db,eth,net,web3,personal,miner"  rpc接口权限
    
#由于我们将geth添加到了环境变量,所以可以直接geth使用,也可以./build/bin/geth使用


# 启动命令
ubuntu@VM-20-9-ubuntu:~$ 
geth  --datadir /home/private_eth/ --http  --http.addr=127.0.0.1 --http.api="db,eth,net,web3,personal,miner" --networkid 13010 --nodiscover --allow-insecure-unlock console 2>>geth.log

启动成功后,通过命令查看账户,因为是刚启动,所以账户肯定是空的

> eth.accounts
[]

在低版本的ETH中可以使用personal创建账户,但是高版本已经废弃了这个功能,直接使用会报错,可以通过geth命令创建账户

> personal.newAccount("101010")

# 退出控制台后直接用geth命令创建账户
ubuntu@VM-20-9-ubuntu:~$ geth account new
INFO [04-19|22:53:06.989] Maximum peer count                       ETH=50 LES=0 total=50
INFO [04-19|22:53:06.990] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password: 
Repeat password:
输出两次密码后,创建成功,返回一个账号地址

但是,geth创建账户的这个方法是有默认目录的,这个账户在geth console里面就找不到,所以需要将账户从默认目录移动至console对应的keystore文件夹。或者直接在创建账户的时候采用如下命令即可:

geth --datadir 数据目录 account new
ubuntu@VM-20-9-ubuntu:~$ geth --datadir /home/private_eth/ account new
INFO [04-19|22:57:24.475] Maximum peer count                       ETH=50 LES=0 total=50
INFO [04-19|22:57:24.475] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password: 
Repeat password: 

现在,已创建了一个区块链账号,下面看如何进行挖矿

# 设置挖矿的账户
> miner.setEtherbase("0xc9a3d1cf1471466f4ece1eb25f0bca2c0ad2899d")
True
## start的参数表示挖矿使用的线程数,若不写表示使用最大线程数。返回true或null表示执行成功
> miner.start()
> miner.start(2)
null
> miner.start()
null
> miner.stop
function()
> eth.getBalance(eth.accounts[0])
138000000000000000000
> 

挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做 coinbase,默认情况下 coinbase 是本地账户中的第一个账户。

此时显示的账户余额的单位是Wei,如果要转成以太币,可进行如下操作:

> web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")

至此,已完成在Linux服务器部署私有ETH区块链并实现挖矿,下回会讲下如何实现智能合约。

发表评论

您的电子邮箱地址不会被公开。