权益证明,它提出来币龄的概念,币龄 = 持有的货币数 * 持有时间,比如说我有100币,持有了30天,那么我的币龄就是3000。币龄越大的节点呢获取记账权(也就是生成区块)的概率越大。每次记完账之后,该节点的币龄就清空。当然,刚获取的币不能直接参与币龄计算,一般是30天之后开始计算币龄。

那么这样会产生一个问题:囤币来获取绝对记账权。为了防止这种情况发生,会设置一个最大概率,一般设置90天时获得最大记账概率,之后不再增加。

但是POS本质上还是类似POW的暴力计算,只不过币多的人更有可能挖到矿,降低了POW的全网一致难度,谁算力强谁记账的局限性。

实验步骤:
本实验将通过go语言实现最简单的POS共识机制算法

  1. 实验准备
    新建文件pos.go,并使用vs code编辑器打开。

    导入所需包:
 package main import ("bytes""crypto/sha256""encoding/binary""fmt""math""math/big""math/rand""time")

定义常量设置最大最小概率,这里由于不可能等30天之后再计算币龄,我设置10秒之后开始计算,并且防止数据过大,按分钟计时:

 const (dif         = 2INT64_MAX   = math.MaxInt64MaxProbably = 255MinProbably = 235MaxCoinAge  = 10Minute      = 60)

定义币的数据结构和一个币池,这里币中提出了地址Address概念,一般理解为钱包地址,一般一个钱包属于一个用户,表明这个币的所有权是这个地址对应的用户:

type Coin struct {Time    int64Num     intAddress string}     var CoinPool []Coin

定义区块和链:

type Block struct {PrevHash  []byteHash      []byteData      stringHeight    int64Timestamp int64Coin      CoinNonce     intDif       int64}type BlockChain struct {Blocks []Block}

init函数,设置随机数种子和币池初始化,会在main函数开始前自动执行:

 func init() {rand.Seed(time.Now().UnixNano())CoinPool = make([]Coin, 0)}

生成创世块,传入的参数是区块上的数据data和挖矿地址addr,这里每个区块的币随机给出1到5,币池增加创世块的币:

  func GenesisBlock(data string, addr string) *BlockChain {var bc BlockChainbc.Blocks = make([]Block, 1)newCoin := Coin{Time:    time.Now().Unix(),Num:     1 + rand.Intn(5),Address: addr,}bc.Blocks[0] = Block{PrevHash:  []byte(""),Data:      data,Height:    1,Timestamp: time.Now().Unix(),Coin:      newCoin,Nonce:     0,}bc.Blocks[0].Hash, bc.Blocks[0].Nonce, bc.Blocks[0].Dif = ProofOfStake(dif, addr, bc.Blocks[0])CoinPool = append(CoinPool, newCoin)return &bc}

生成新区块函数,还是一样,prevHash对应上一个节点的Hash,随机给出1-5币奖励,记录该币的所有者地址addr,币池增加新区块的币:

func GenerateBlock(bc *BlockChain, data string, addr string) {prevBlock := bc.Blocks[len(bc.Blocks)-1]newCoin := Coin{Time:    time.Now().Unix(),Num:     1 + rand.Intn(5),Address: addr,}b := Block{PrevHash:  prevBlock.Hash,Data:      data,Height:    prevBlock.Height + 1,Timestamp: time.Now().Unix(),}b.Hash, b.Nonce, b.Dif = ProofOfStake(dif, addr, b)b.Coin = newCoinbc.Blocks = append(bc.Blocks, b)CoinPool = append(CoinPool, newCoin)}
  1. 权益证明算法
    POS机制的核心算法:设置的是10s之后开始计算币龄,根据币龄coinAge调整当前难度Dif以获取真实难度realDif。挖矿还是类似POW寻找一个nonce加在尾部,寻找到第一个满足真实难度realDif的sha256哈希串:
func IntToHex(num int64) []byte {buff := new(bytes.Buffer)err := binary.Write(buff, binary.BigEndian, num)if err != nil {panic(err)}return buff.Bytes()}func ProofOfStake(dif int, addr string, b Block) ([]byte, int, int64) {var coinAge int64var realDif int64realDif = int64(MinProbably)curTime := time.Now().Unix()for k, i := range CoinPool {if i.Address == addr && i.Time+MaxCoinAge < curTime {//币龄增加, 并设置上限var curCoinAge int64if curTime-i.Time < 3*MaxCoinAge {curCoinAge = curTime - i.Time} else {curCoinAge = 3 * MaxCoinAge}coinAge += int64(i.Num) * curCoinAge//参与挖矿的币龄置为0CoinPool[k].Time = curTime}}if realDif+int64(dif)*coinAge/Minute > int64(MaxProbably) {realDif = MaxProbably} else {realDif += int64(dif) * coinAge / Minute}target := big.NewInt(1)target.Lsh(target, uint(realDif))nonce := 0for ; nonce < INT64_MAX; nonce++ {check := bytes.Join([][]byte{b.PrevHash,[]byte(b.Data),IntToHex(b.Height),IntToHex(b.Timestamp),IntToHex(int64(nonce)),},[]byte{})hash := sha256.Sum256(check)var hashInt big.InthashInt.SetBytes(hash[:])if hashInt.Cmp(target) == -1 {return hash[:], nonce, 255 - realDif}}return []byte(""), -1, 255 - realDif}

再写个打印区块和打印币池函数:

 func Print(bc *BlockChain) {for _, i := range bc.Blocks {fmt.Printf("PrevHash: %x\n", i.PrevHash)fmt.Printf("Hash: %x\n", i.Hash)fmt.Println("Block's Data: ", i.Data)fmt.Println("Current Height: ", i.Height)fmt.Println("Timestamp: ", i.Timestamp)fmt.Println("Nonce: ", i.Nonce)fmt.Println("Dif: ", i.Dif)}}func PrintCoinPool() {for _, i := range CoinPool {fmt.Println("Coin's Num: ", i.Num)fmt.Println("Coin's Time: ", i.Time)fmt.Println("Coin's Owner: ", i.Address)}}

写个main函数测试看看,虚拟两个地址,当然,真实区块链的地址不可能这么简单,需要使用公钥生成地址算法。
给addr1先记账,获取一定币,等待可以计算币龄时再次记账,再给新地址addr2记账,看看难度对比:

    func main() {addr1 := "192.168.1.1"addr2 := "192.168.1.2"bc := GenesisBlock("reigns", addr1)GenerateBlock(bc, "send 1$ to alice", addr1)GenerateBlock(bc, "send 1$ to bob", addr1)GenerateBlock(bc, "send 2$ to alice", addr1)time.Sleep(11 * time.Second)GenerateBlock(bc, "send 3$ to alice", addr1)GenerateBlock(bc, "send 4$ to alice", addr2)Print(bc)PrintCoinPool()}

查看打印结果:

PrevHash:
Hash: 000002ef0acef37ede164d80ed8ae2cb712fd14b3ff9fb155af6e5f953e58bff
Block's Data:  reigns
Current Height:  1
Timestamp:  1591982949
Nonce:  2561632
Dif:  20
PrevHash: 000002ef0acef37ede164d80ed8ae2cb712fd14b3ff9fb155af6e5f953e58bff
Hash: 0000055e4d37559923cdbc5693d66752c9bba19b64ba1a93610a3c4531174eab
Block's Data:  send 1$ to alice
Current Height:  2
Timestamp:  1591982954
Nonce:  4042915
Dif:  20
PrevHash: 0000055e4d37559923cdbc5693d66752c9bba19b64ba1a93610a3c4531174eab
Hash: 0000747cc3ae3a6bed3d29a8f996e7946cdc9aec40d4a46cce9737b736b2859a
Block's Data:  send 1$ to bob
Current Height:  3
Timestamp:  1591982966
Nonce:  20853
Dif:  16
PrevHash: 0000747cc3ae3a6bed3d29a8f996e7946cdc9aec40d4a46cce9737b736b2859a
Hash: 0000044ec9d575112cede61b3924ad5d83bcbe871520141ae903f5cbe7d0f004
Block's Data:  send 2$ to alice
Current Height:  4
Timestamp:  1591982966
Nonce:  1306376
Dif:  20
PrevHash: 0000044ec9d575112cede61b3924ad5d83bcbe871520141ae903f5cbe7d0f004
Hash: 0000e1c3323d955940188536908424b25ec3e7e7bd09c7eee7b00b5be7c689ee
Block's Data:  send 3$ to alice
Current Height:  5
Timestamp:  1591982980
Nonce:  6648
Dif:  14
PrevHash: 0000e1c3323d955940188536908424b25ec3e7e7bd09c7eee7b00b5be7c689ee
Hash: 0000019be7a6d4d2c1530473f352410988b66f263b267a45556ab9a2ad8774db
Block's Data:  send 4$ to alice
Current Height:  6
Timestamp:  1591982980
Nonce:  71126
Dif:  20
Coin's Num:  4
Coin's Time:  1591982980
Coin's Owner:  192.168.1.1
Coin's Num:  5
Coin's Time:  1591982980
Coin's Owner:  192.168.1.1
Coin's Num:  2
Coin's Time:  1591982980
Coin's Owner:  192.168.1.1
Coin's Num:  2
Coin's Time:  1591982980
Coin's Owner:  192.168.1.1
Coin's Num:  2
Coin's Time:  1591982980
Coin's Owner:  192.168.1.1
Coin's Num:  1
Coin's Time:  1591982980
Coin's Owner:  192.168.1.2

权益证明(Proof Of Stake)——Go语言实验相关推荐

  1. 以太坊 权益证明(五)

    权益证明 Proof of Stake,比特币和以太坊目前都是基于工作量的证明,这种共识机制收到了一个普遍的批评就是浪费电. 下图显示比特币能耗随时间变化的情况,y轴是TWh是TeraWatt Hou ...

  2. Go学习之编码实现区块链 - 【权益证明PoS】

    在上一篇讲到如何快速实现一个简单的区块链,相信朋友们已经对其有了一个基础的认识.接下来,我们在此基础上进行重构,加入当下热议的一项技术,就是权益证明(Proof of Stake)的代码实现.在实现之 ...

  3. 权益证明问题 —— Proof of Stake FAQ

    ethereum wiki 中的汉语繁体翻译实在是读不通顺,还不如看英文,顺便翻译下.原文:Proof of Stake FAQ 什么是权益证明 权益证明(Proof of Stake,PoS)是一种 ...

  4. 【译】The missing explanation of Proof of Stake Version 3

    在每一个加密货币中,都必须有一些共识机制来保持整个分布式网络的同步. 当比特币首次推出时,它推出了工作证明(PoW)系统. PoW是通过反复加密散列一块数据(块头)来完成的. 由于单向哈希如何工作. ...

  5. 区块链共识算法:PoS即权益证明 DPoS委托授权的权益证明

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 随着比特币价格暴涨,基于比特币的区块链技术引起各方关注,其核心就是共识算法.随着区块链技术的发展共识算法也在不断创新与发 ...

  6. EOS共识机制——DPoS代理权益证明

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 区块链共识机制与它的演进,是由于区块链式去中心化而且分布式的系统,必须要有一套放诸四海皆准类似宪法的规则,来规范如何证明 ...

  7. 区块链去中心化的生命之源:“DPOS(委托权益证明)共识机制”

    区块链去中心化的生命之源:"DPOS(委托权益证明)共识机制" 原创2018-04-24[水伯]战略忽悠局政委水伯 移动网络时代唯一壁垒就是认知,周二有约给思想洗澡让认知破壁! D ...

  8. 共识协议(8)NPOS提名权益证明

    1. NPOS提名权益证明( Nominated Proof of Stake) 1.1 验证者 中继链的全节点,中继链会在验证人池中通过随机分组把验证人指定给不同的平行链.验证人会接受来自收集人打包 ...

  9. 共识机制-权益证明 PoS

    共识机制-权益证明 PoS 什么是权益证明 权益证明( Proof of Stake,PoS )最早在2013年被提出,并在 Peercoin 系统中实现,类似于现实生活中的股东机制,拥有股份越多的人 ...

最新文章

  1. git 快速复制一个新项目
  2. 云原生解决什么问题?
  3. Python计算医疗数据训练集、测试集的对应的临床特征:训练集(测试集)的阴性和阳性的样本个数、连续变量的均值(标准差)以及训练测试集阳性阴性的p值、离散变量的分类统计、比率、训练测试集阳性阴性的p值
  4. selenium自动化测试浏览器驱动安装(属于转载文章)
  5. 密码篇——非对称加密
  6. 「五大常用算法」一文图解分治算法和思想
  7. 简单的Android对文件进行读写操作
  8. [编程技巧] C++字符串初始化的优化写法
  9. centos下安装fastdfs(笔记系列)
  10. 安装JDK失败,再次安装时出现已经安装过了的,解决办法
  11. keras 深度神经网络模型的搭建
  12. CRC32的C语言源代码
  13. easydarwin 安装_linux环境安装部署easydarwin流媒体服务器详细教程
  14. TPC-DS标准规范(2)
  15. 基于蓝墨云班课的翻转课堂实践
  16. ​KAKA NFT | 潮物来袭!烤仔英雄系列NFT盲盒即将发售~
  17. 大数据之Hadoop3简单入门(一)(通俗易懂)
  18. 时间复杂度(算法的渐进时间复杂度)
  19. FastStone Capture安装包正版激活码使用说明
  20. common 模块的简介

热门文章

  1. 手机web遇到的问题及解决方法
  2. 优质的冰川 雪地cc0高清摄影图片素材推荐,不容错过
  3. word中如何从第N页开始设置页码并且前面的页不显示页码
  4. 【转】应届毕业生要知道的几个小东西,,三方协议,,报到证,,干部身份
  5. tomcat配置技巧(转载)
  6. AcWing 868. 筛质数 (线性筛法)
  7. linux下apache服务起不来,Linux系统下Apache服务器启动失败的解决办法 - Apache - 数安时代(GDCA)SSL证书官网...
  8. 12306网站,真服了!
  9. 开学季蓝牙耳机怎么选?蓝牙耳机性价比排行
  10. 字少,事大!华为鸿蒙系统真来了!18级台风也来助阵!