这可能是全网最简单的POS共识机制算法
共识算法是区块链非常重要的一种算法,简单来说,共识算法就是为了使网络中的节点得到一致的认可。就比如说合作双方达成一致,共同遵守某个合约。
传统的分布式系统中,由于有着中心服务器进行统一管理,各个子服务器只需要跟着中心服务器进行操作即可。而区块链作为一种去中心化分布式系统,并没有传统意义上的中心服务器,因此传统的分布一致性算法并不适用于区块链网络。每个服务器都可以是中心服务器,那么这样就需要一种新的算法来维护系统中的一致性了。现在区块链中,主流的共识算法一般为三种:POW,POS和DPOS。
工作量证明(Proof Of Work)
工作量证明算法之前已经提到过,在实现微型区块链时用的就是pow算法,这是最传统最经典的共识算法,应用在比特币中。它的原理就是寻找一个以若干个0为开头的哈希串。举个例子,给定字符串“blockchain”,我们给出的工作量要求是,可以在这个字符串后面连接一个称为nonce的整数值串,对连接后的字符串进行sha256哈希运算,如果得到的哈希结果(以十六进制的形式表示)是以若干个0开头的,则验证通过。为了达到这个工作量证明的目标,我们需要不停地递增nonce值,对得到的新字符串进行sha256哈希运算。
原理非常的简单,也可以说是只需要算就行了。
这样也存在一个问题,那就是它只要求算力,不要求理解区块链的本身,也就造成了现如今比特币的大量矿机无脑挖矿。就像演唱会的黄牛,买票只为了获取它的利益,并不在意演唱会本身的内容。为了避免这种靠纯运算的共识机制,相继提出来很多新的共识算法。
权益证明(Proof Of Stake)
今天重点讲讲POS机制。
权益证明,它提出来币龄的概念,币龄 = 持有的货币数 * 持有时间,比如说我有100币,持有了30天,那么我的币龄就是3000。币龄越大的节点呢获取记账权(也就是生成区块)的概率越大。每次记完账之后,该节点的币龄就清空。当然,刚获取的币不能直接参与币龄计算,一般是30天之后开始计算币龄。
那么这样会产生一个问题:囤币来获取绝对记账权。为了防止这种情况发生,会设置一个最大概率,一般设置90天时获得最大记账概率,之后不再增加。
但是POS本质上还是类似POW的暴力计算,只不过币多的人更有可能挖到矿,降低了POW的全网一致难度,谁算力强谁记账的局限性。
具体来看代码怎么实现它的吧:
导入所需包:
package mainimport ("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)
}
权益证明算法:
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()
}
看看打印结果吧:
可以看到啊,addr1记前四笔账的时候难度都是20,第五笔的时候,由于之前延迟了11秒,开始计算币龄,难度减小到了15,第六笔账由addr2记账,难度又回到了20,同时看币池,参与币龄计算的币的Time统一到第5笔记账时间,也就是刷新了币龄。
当然啊,真实环境中肯定不是顺序记账,每个节点都会竞争记账权,最先计算出满足难度的hash串的节点优先记账,并向全网广播,开始下一次记账权争夺。
好了,今天到这里了~下次讲讲更有效率的共识算法,也是三大主流算法的最后一个:DPOS。
如果对区块链感兴趣,可以关注下面这个公众号哦,推送的全是区块链干货~
这可能是全网最简单的POS共识机制算法相关推荐
- pos共识机制_OK区块链60讲 | 第17集:什么是PoS共识机制
什么是PoS共识机制https://www.zhihu.com/video/1196092110837805056 <OK区块链60讲>是由OKEx&新浪科技联合出品的区块链科普动 ...
- POS共识机制竟然漏洞这么多 | 分析POS共识机制的原理带来的思考
序言 上文深入比特币.以太坊源码带你解读POW共识机制我们学习探讨了POW共识机制,看完得童鞋们应该就知道POW是有几大缺点的:出块慢,共识时间长.开销大等等,那么有没有其它的共识机制能够解决这些问题 ...
- 通俗讲解:PoW共识机制与以太坊的关系、Ghost协议 及 Casper PoS共识机制的变种...
作者:林冠宏 / 指尖下的幽灵 掘金:juejin.im/user/587f0d- 博客:www.cnblogs.com/linguanh/ GitHub : github.com/af9133374 ...
- 通俗讲解:PoW共识机制与以太坊的关系、Ghost协议 及 PoS共识机制的变种---Casper...
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- pos共识机制_PoS共识机制是什么?其优缺点分别是什么?
PoS共识机制的全称是Proof of Stake.PoS机制通过计算每个节点所占代币的比例和时间,等比例的降低挖矿难度,从而加快找随机数的速度.以太坊采用的PoS则是Casper投注共识,通过保证金 ...
- 以太坊的POS共识机制(二)理解 Serenity :Casper
Original post by Vitalik Buterin, on December 28th, 2015 特别感谢Vlad Zamfir,他提出了按块达成共识这个想法,并且说服我认同它和Cas ...
- go语言实现PoS共识机制
1.新建main.go文件 package mainimport ("bufio""crypto/sha256""encoding/hex" ...
- 区块链共识机制:POW、POS、DPOS、PBFT、POOL
共识机制作为区块链的关键技术之一,在业务吞吐量.交易速度.不可篡改性.准入门槛等等方面发挥重要的作用. 区块链是去中心化的,没有中心记账节点,所以需要全网对账本达成共识.目前有POW.POS.DPOS ...
- 区块链共识机制技术二——POS(权益证明)共识机制
前言 由于区块链是去中心化分散网络,所以必须设计一套维护系统的运作顺序和公平性的机制,即共识机制,用来决定谁取得区块链的记账权并获得系统新币奖励.比特币的POW共识机制是一种多劳多得的模式,其优点是算 ...
最新文章
- Mac Os 基本命令行
- python壁纸4k_【python日常学习】爬取4K桌面壁纸
- text-size-adjust: none并没有什么用
- php post nginx 400,Nginx静态文件响应POST请求 提示405错误的解决方法
- 【渝粤教育】国家开放大学2018年秋季 0630-21T环境法学 参考试题
- Axios的Vue插件(添加全局请求/响应拦截器)
- CentOS 6快捷安装RabbitMQ教程
- git管理工具_使用包管理工具
- 滑动窗口算法_从一道题讲解滑动窗口算法该如何实现
- JavaScript 事件相关
- python的类和对象例题_Python类、类对象和实例对象、组合、绑定详细讲解
- 红外遥控NEC协议总结
- 程序的静态链接,动态链接和装载
- hping 详解_hping3使用
- android 截屏分享权限,android 截屏+保存图片+权限
- 实践小笔记(1) --- DBSCAN
- springboot疫情防控下基于微信小程序的食堂订餐系统毕业设计源码261620
- 女友的生日礼物能随便嘛?Python小妙招:制作一款出圈九宫格抽奖小程序。
- python走迷宫_Python使用Tkinter实现机器人走迷宫
- CrowdHuman数据集转成VOC格式并训练模型