基于POA搭建ETH联盟链

基于POA共识机制搭建ETH联盟链

共识机制比较

PoW(Proof-of-Work)

众所周知的比特币以及其它基于PoW的加密货币,最大的缺陷之一就是会遭遇51%攻击(虽然难度较大),虽然区块链是不可变的,并且记录无法更改,但是攻击者可能会实施其它攻击,如拒绝服务攻击,从而导致应用瘫痪。

另外,PoW的计算消耗了大量的电力资源,以太坊一直致力研究PoW的替代方案,例如PoS,这解决了电力问题,但它更多地针对的是公链。

对于私链,工作证明根本没有意义。

PoS(Proof-of-Stake)

以太坊很快过渡到了PoS算法,此算法解决了公链工作证是且的问题,想要成为矿工的人会将一些以太币存入智能合约中,如果矿工被认为是恶意的,那么这部分以太币将会被锁定。

因为没有竞争来解决难以解决的数学问题,所以不必总是发行新币,矿工将从交易中获得回报。

这种算法确实解决了过度用电的问题,并确实在一定程度上可以防止51%攻击。

对于私链,PoS可能比Pow更 好,但它仍然没有为我们提供所需的控制和安全级别,因为如果他们提交了足够的以太币做为押金,那么公链上的任何人都可以成为矿工。

PoA(Proof-of-Authority)

PoA是区块链世界中的一个新概念,在这个概念中,您拥有许多预先批准的授权节点(称为审查者,即通常意义上的矿工)。

您要添加任何新节点,必须由当前已有的审查者投票,这使您可以完全控制哪一些节点可以做为审查者。

以太坊的PoA协议称为Clique,它适用于私链,但不适用于公链。

因此本次搭建的智子链是基于POA共识机制

环境准备

硬件环境

推荐:ubuntu16.04 4核8G 500G硬盘

最低:ubuntu16.04 2核4G 500G硬盘

软件环境

  1. go语言环境
  2. 以太坊源码
  3. puppeth工具

正式部署

1.安装 go-ethereum,下载 go 的源码

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

2.编译go

cd go-ethereum && make geth

3.创建四个文件夹

执行完成后在build/bin的目录下会生成可执行文件geth,创建四个
文件夹n1,n2,s1,s2,n 用作普通节点,用于后期节点间发起交易,s作为授权节点,s1 设置为创世块指定的授权节点;s2作为后期加入信任名单授权节点。
image

4.建立智子链帐号

为每个节点建立一个智子链账户。指令geth --datadir ./data account new是指使用当前目录下的data目录当作geth存放资料的地方,并且创一个新的Account。在刚刚创建的n1, n2, s1, s2 目录下分别运行相同指令来创建一个账户,如下图所示:
基于POA搭建ETH联盟链_第1张图片

n2,s1,s2以同样的方法创建账户,注意:一定要记住自己的密码和各个账号的Public address of the key,后面会用到。

5.初始化创世块

Clique 是将授权节点的相关信息放在Block Header中,必须设置创世块才可以让授权机制生效。

在 1.6 之后的以太坊中提供了初始化创世块的工具:puppeth, 请选择含有 Geth & Tools 的版本下载,下载地址:https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.9.8-d62e9b28.tar.gz。

puppeth 是个互动式的程序,直接启动照着指示输入相关信息。设置 Private chain 名称(名称里不允许有-,空格),假定为 poatest,如下:
基于POA搭建ETH联盟链_第2张图片

设定新的创世块,选择2->1:
基于POA搭建ETH联盟链_第3张图片

选择共识机制,选2:
image

设置生产出一个Block的时间,在这里设5 秒,可自行选择,如下图:
image

指定授权节点,使用上面的s1的address,如下图:
image

给账户设置一些ether。我选了node1和signer1的address,可自行选择,如下图:
image

Network Id,直接用random随机生成即可,如下图:
基于POA搭建ETH联盟链_第4张图片

导出初始块,如下图:
基于POA搭建ETH联盟链_第5张图片

ctrl+c退出,可以看到当前目录有一个poatest.json文件,如下图:
image

创世块poatets.json文件里参数的意义,如下:

参数 解释
mixhash 与 nonce 配合用于挖矿,由上一个区块的一部分生成的 hash。注意他和 nonce 的设置需要满足以太坊的 Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的 条件。
nonce nonce 就是一个 64 位随机数,用于挖矿,注意他和 mixhash 的设置需要满足以太 坊的 Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
difficulty 设置当前区块的难度,如果难度过大,cpu 挖矿就很难,这里设置较小难度。
alloc 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要 预置有币的账号,需要的时候自己创建即可以。
coinbase 矿工的账号,随便填。
timestamp 设置创世块的时间戳。
parentHash 上一个区块的 hash 值,因为是创世块,所以这个值是 0。
extraData 附加信息,在 POA 挖矿中。
gasLimit 该值设置对 GAS 的消耗总量限制,用来限制区块能包含的交易信息总和,因为我 们是私有链,所以填最大。

6.初始化私有链

使用 geth init 指令,分别初始化 4 个节点的 datadir

geth --datadir n1/data/ init geth-alltools/poatest.json

geth --datadir n2/data/ init geth-alltools/poatest.json

geth --datadir s1/data/ init geth-alltools/poatest.json

geth --datadir s2/data/ init geth-alltools/poatest.json

初始化完成之后,在每个文件夹中会生成两个子文件夹
image

geth 用来存储区块链的数据信息,keystore 用来存储账户信息。

启动各个节点:

以控制台形式启动:geth --datadir n1/data --networkid 66300 --port 3000 console

运行在后台:nohup geth --datadir n1/data --networkid 66300 --port 3000 &

连接控制台:geth attach --datadir n1/data

注意:s1为挖矿节点启动时需要解锁,–password指定密码文件 ,–unlock解锁账户

7.建立data目录

datadir先前的步骤已经在每个节点各自的目录下都建立了data目录,networkid geths之间一定都要用同一个值才可以互相通信,比如实验中的66300. Portgeths 之间通信时,监听的一个port,由于四个节点都在本机,所以这里必须指定不同的值,使用 n1 对应 3000, n2 对应 3002, s1 对应 3003, s2 对应 3004.
geth参数含义如下:

参数 解释
identity 区块链的标示,随便填写,用于标示目前网络的名字
init 指定创世块文件的位置,并创建初始块
datadir 设置当前区块链网络数据存放的位置
port 网络监听端口
rpc 启动 rpc 通信,可以进行智能合约的部署和调试
rpcapi 设置允许连接的 rpc 的客户端,一般为 db,eth,net,web3
networkid 设置当前区块链的网络 ID,用于区分不同的网络,是一个数字
console 启动命令行模式,可以在 Geth 中执行命令

启动节点时,信息中的enode需要记录,后面建立节点间的通信需要用到。

7.建立节点之间的通信

目前各个节点虽然已经启动,但是各个节点之间仍然处于孤立状态。各节点启动后无法相互通信的,所以geth要连上对方的节点就必须先设置好enode://@:,复制刚刚启动node1时出现的enode信息,将[::]替换为127.0.0.1,这样就可以让其他节点加入。如上面提示的的红色提示所见, n1 的 enode 为:enode://498d3960afb904231c54044b0ed5c6c19a3241460ba06a46170dd5a22f00009735b6515008c6a87c164e41d24446801a523d83050d3bc4da16150bbc91ebb0fa@127.0.0.1:3000

在n2,s1,s2的geth console界面下分别运行如下指令建立节点间的通信:admin.addPeer(“enode://498d3960afb904231c54044b0ed5c6c19a3241460ba06a46170dd5a22f00009735b6515008c6a87c164e41d24446801a523d83050d3bc4da16150bbc91ebb0fa@127.0.0.1:3000”)

完成后,在 node1 的 geth console 输入 admin.peers 应该要看到三个节点资讯,如下:(每个id 对应其他节点的 encode 字段信息)
基于POA搭建ETH联盟链_第6张图片

8.开始挖矿

按照实验的设计,在本实验中 s1 为挖矿节点,我们下面开始进行模拟挖矿,在 s1 的console 界面,键入 miner.start(),geth 就会开始挖矿了,在 s1 的 输出日志nohup.out 会出现正在mining 的信息,如下图:

由上图可看出挖矿节点每5秒出一个块。

9.交易转账

按照我们的预设,在 n1 和 s1 上是已经初始化了余额的。查询如下图:
基于POA搭建ETH联盟链_第7张图片
默认账户是Locked状态,需要先解锁为unlock状态,才可以进行账户间的转账,解锁过程如下图:
基于POA搭建ETH联盟链_第8张图片

基于POA搭建ETH联盟链_第9张图片

转账后查询账户余额:
基于POA搭建ETH联盟链_第10张图片

10.加入新可信节点

s2 是一开始未设定在创世块中信任列表的节点,如果这时候让它启动miner,会遇到一个未授权的错误,如下:
基于POA搭建ETH联盟链_第11张图片

回到已经在授权名单内的节点的console界面下,将新的节点加入,如下:
image

重新启动s1,s2两个节点,进入控制台执行miner.start()发现两节点均提示Signed recently, must wait for others(由于两节点没有建立通信),因此在signer1中通过admin.addPeer()添加signer2,使二者可以通信,如下:
image

最后在s1,s2上执行miner.start(),两节点开始交替挖矿。如下:
基于POA搭建ETH联盟链_第12张图片

基于POA搭建ETH联盟链_第13张图片

加入第三个信任节点:

启动节点后,首先跟其他节点建立连接admin.addPeer(enode://7267113574d0c7f9c2d0859e5f552f172d2add8e4d31c76861494b7815baea170058b01b35c97dcb638dc57f8b0395127e77f25469d75092eb5abcca497cb57c@172.31.33.187:3000)

然后在s1,s2上分别多新加入的s3进行授权:clique.propose(“0x3f9a3A33884FF903c0924EDD384A2AF1657f926B”,true)

重启s3节点,重新连接后将s3与s1,s2建立连接,在s1,s2上分别执行admin.addPeer(“enode://cd1226502cf4805b2bec5766290717db8ae941b7629aac08668014a32bc1996fd31801fb7f6ce4504593a5a505310379156b47689f33a77df9c5ac426db79e47@127.0.0.1:3004”)

最后在s3节点执行miner.start()开始挖矿,此时s1,s2,s3三个节点交替挖矿。

加入普通节点,先生成一个新账户,再初始化私有链,然后启动该节点,在该节点里与其他节点建立连接即可,截图如下:
基于POA搭建ETH联盟链_第14张图片

image

clique命令及其意义:

list sealers clique.getSigners()

list propositions: clique.proposals

discard a proposition: clique.discard(“0x1234234234234”)

add a new sealer: clique.propose(“0x1234243214312”, true)

remove a sealer: clique.propose(“0x1234243214312”, false)

删除一个信任节点时,先remove a sealer,再discard a proposition

Tips:在终端不关闭的情况下,重新启动geth进入console界面,通过admin.peers查看链接信息,发现之前添加的节点信息都存在;但是,关闭终端后,重新打开一个新的终端,启动geth进入console界面,通过admin.peers查看链接信息,会发现是空的,需要重新运行admin.addPeer()添加,这一点一定要注意!!!

通过clique.discard(signer_address)删除信任节点。通过clique.propose(signer_address,true)添加信任节点,通过实验发现,无法立即生效,需要一半以上的信任节点的投票。一般要在当前所有的信任节点的终端中都执行clique.propose(),并且在各信任节点的终端都同时挖矿,各自挖出几个块后,新添加的信任节点就可已挖矿了。

引用:
https://blog.csdn.net/shangsongwww/article/details/89063564

你可能感兴趣的:(区块链-ETH,区块链,运维,服务器,linux)