geth基于PoA共识机制构建联盟链

1 PoA共识机制

PoW机制的缺陷

以太坊现阶段是基于PoW共识机制,PoW工作量证明机制就是区块链网络中一堆计算机通过计算随机数的Hash值,谁先找到这个随机数谁就赢的当前区块的记账权。PoW通过比拼算力,谁的算力大,谁就能够抢到记账权。这样导致网络大量算力用来计算毫无意义的随机数工作中去了,而真正用来打包和验证的算力就受到影响。

  • PoW机制存在51%算力共计问题。只要挖矿者掌握全网51%算力就能控制整个网络。
  • PoW机制消耗大量电力。
  • PoW机制造成了以太坊网络算力的损失,从而无法支持很高的tps。

PoA共识机制

所谓授权证明PoA(Proofof Authority),就是由一组授权节点来负责新区块的产生和区块验证。以太坊测试网(Kovan)便是采用PoA算法。以太坊源码中带有Clique共识算法即为一种PoA共识算法。

在PoA中,验证者(validator)是整个共识机制的关键。验证者不需要昂贵的显卡,也不需要足够的资产,但他必须具有已知的,并且已获得验证的身份。验证者通过放置这个身份来获得担保网络的权利,从而换取区块奖励。若是验证者在整个过程中有恶意行为,或与其他验证者勾结。那通过链上管理可以移除和替换恶意行为者。现有的法律反欺诈保障会被用于整个网络的参与者免受验证者的恶意行为。

PoA共识机制的特点

PoA是依靠预设好的授权节点(signers),负责产生block.可以由已授权的signer选举(投票超过50%)加入新的signer。即使存在恶意signer,他最多只能攻击连续块(数量是 (SIGNER_COUNT / 2) + 1) 中的1个,期间可以由其他signer投票踢出该恶意signer。可指定产生block的时间。


2 PoA联盟链搭建

扫描二维码关注公众号,回复: 2629621 查看本文章

准备工作

在ubuntu系统中首先安装geth客户端,这里使用geth 1.8.8版本。
然后建立三个文件夹,分别是bootdir,boot1,boot2三个文件夹。在bootdir文件夹中创建bootnode节点用来做p2p网络路由。使用命令 sudo bootnode --genkey boot.key来创建名为boot.key的key文件。

然后使用 sudo bootnode --nodekey boot.key 命令启动bootnode路由节点。

创建账户

使用puppeth来产生创世文件

puppeth是geth自带的程序,可以引导用户创建geth的创世文件。运行puppeth

 
  1. root@lzj-VirtualBox:/home/lzj/boot1# sudo puppeth

  2. +-----------------------------------------------------------+

  3. | Welcome to puppeth, your Ethereum private network manager |

  4. | |

  5. | This tool lets you create a new Ethereum network down to |

  6. | the genesis block, bootnodes, miners and ethstats servers |

  7. | without the hassle that it would normally entail. |

  8. | |

  9. | Puppeth uses SSH to dial in to remote servers, and builds |

  10. | its network components out of Docker containers using the |

  11. | docker-compose toolset. |

  12. +-----------------------------------------------------------+

  13.  
  14. Please specify a network name to administer (no spaces or hyphens, please)

  15. > lzj

  16.  
  17. Sweet, you can set this via --network=lzj next time!

  18.  
  19. INFO [06-23|17:10:34] Administering Ethereum network name=lzj

  20. INFO [06-23|17:10:34] No remote machines to gather stats from

  21.  
  22. What would you like to do? (default = stats)

  23. 1. Show network stats

  24. 2. Configure new genesis

  25. 3. Track new remote server

  26. 4. Deploy network components

  27. > 2

  28.  
  29. Which consensus engine to use? (default = clique)

  30. 1. Ethash - proof-of-work

  31. 2. Clique - proof-of-authority

  32. > 2

  33.  
  34. How many seconds should blocks take? (default = 15)

  35. > 2

  36.  
  37. Which accounts are allowed to seal? (mandatory at least one)

  38. > 0xd71ad920f80e6a1e06689a720f24b335f22d557e

  39. > 0x8bbc43acd355be0cecc61872e13e0a0e53c700b7

  40. > 0x

  41.  
  42. Which accounts should be pre-funded? (advisable at least one)

  43. > 0x0xd71ad920f80e6a1e06689a720f24b335f22d557e

  44. ERROR[06-23|17:11:33] Invalid address length, please retry

  45. > 0xd71ad920f80e6a1e06689a720f24b335f22d557e

  46. > 0x

  47.  
  48. Specify your chain/network ID if you want an explicit one (default = random)

  49. > 1500

  50. INFO [06-23|17:12:05] Configured new genesis block

  51.  
  52. What would you like to do? (default = stats)

  53. 1. Show network stats

  54. 2. Manage existing genesis

  55. 3. Track new remote server

  56. 4. Deploy network components

  57. > 2

  58.  
  59. 1. Modify existing fork rules

  60. 2. Export genesis configuration

  61. 3. Remove genesis configuration

  62. > 2

  63.  
  64. Which file to save the genesis into? (default = lzj.json)

  65. > genesis.json

  66. INFO [06-23|17:12:27] Exported existing genesis block

  67.  
  68. What would you like to do? (default = stats)

  69. 1. Show network stats

  70. 2. Manage existing genesis

  71. 3. Track new remote server

  72. 4. Deploy network components

  73. > ^C

  74. root@lzj-VirtualBox:/home/lzj/boot1# ls

  75. genesis.json keystore

  76. root@lzj-VirtualBox:/home/lzj/boot1#

将在boot1目录下产生genesis.json文件,将这个文件拷贝到boot2目录下去

初始化boot1和boot2俩个节点

 
  1. /home/lzj/boot1# sudo geth --datadir ./ init genesis.json

  2. /home/lzj/boot2# sudo geth --datadir ./ init genesis.json

启动boot1节点

boot1节点启动挖矿

boot1节点这个时候挖出了区块1,在等待其它节点加入。

启动boot2节点

因为在同一台机器上,所以要注意boot2的port端口和rpc端口跟boot1的有所不同。

boot2启动挖矿

boot1节点:

boot2节点:

可以看到俩个节点都在挖矿,每个区块产生间隔2s,每个节点挖矿间隔4s。

3 发起交易

在boot1节点再新建一个账户,从账号0给新建账号1转账:

> eth.sendTransaction({from:eth.coinbase,to:eth.accounts[1],value:web3.toWei(100,"ether")})

查询账号1的余额:

 
  1. web3.fromWei(eth.getBalance(eth.accounts[1])

  2. 100

然后再boot2新建一个账号,从boot1的账号1给boot2的新建账号转账:

eth.sendTransaction({from:eth.accounts[1],to:"0xa114e1381cfa44d66682cbff4e7aa5f788c44a64",value:web3.toWei(10,"ether")})

查询boot1的账户余额:

 
  1. > web3.fromWei(eth.getBalance(eth.accounts[1]))

  2. 89.999622

查询boot2的账户1余额:

 
  1. > web3.fromWei(eth.getBalance("0xa114e1381cfa44d66682cbff4e7aa5f788c44a64"))

  2. 10

可见从从boot1的账号0给账号1转账100ether的交易成功,此时boot1的账号1有钱100ether。从boot1的账号1给boot2的账号1转账10ether的交易也成功了,boot2的账号1收到了10ether,转账后boot1的账号1只剩下89.9996222ether,说明转账是收取了gas费用。

4 新加节点并提名挖矿

新建目录boot3,拷贝创世文件genesis.json到该目录,然后按照前面的放方法启动节点

创建新账号

初始化节点

lzj@lzj-VirtualBox:~/boot3$ sudo geth --datadir ./ init genesis.json

启动节点

开始同步了:

这个时候由于boot3节点的账号不在genesis.json指定的验证节点列表里,所以无法挖矿,验证一下:

报了未授权的错误: 

WARN [06-25|10:45:09] Block sealing failed                     err=unauthorized

现在共有3个节点,所以需要一半以上的节点提名节点3的根账号,它才能被加入验证人列表。在boot1节点和boot2节点提名boot3的根账号:

> clique.propose("0x5b5bb21eb5dede180d97fd014e3d4fb277b08dee",true)

这个时候boot3挖矿成功了:

5 踩坑记录

(1)启动节点挖矿时,需要带上标志--syncmode "full",否则汇报错误:

Clique : Discarded bad propagated block#1 when syncing

(2)启动节点挖矿时,需要在启动时带上 --unlock "账号",否则会在挖矿一定时间后会报挖矿失败,需要解锁的错误。

猜你喜欢

转载自blog.csdn.net/weixin_39634961/article/details/81283782
今日推荐