以太坊的共识机制

以太坊 同时被 2 个专栏收录
13 篇文章 0 订阅
30 篇文章 0 订阅

在开始之前,我们补充一点基础知识。

 

第一个概念是哈希。简单理解,哈希是一个函数。它的作用是将任意长度的数据作为输入,转变为固定长度的一个字符串作为输出。这个函数有两个主要特点

  1. 过程不可逆
  2. 对输入做微小改动,输出就会完全不一样。

哈希函数有好多种,但都满足上面的特点。几乎任何加密货币都会用到哈希算法,以太坊采用的哈希算法是ethash算法

 

第二个补充知识是,以太坊的区块结构。一个以太坊区块包含区块头和区块内容

区块内容就是区块所包含的交易列表。而区块头中包含了如下信息:

前一个区块的哈希、区块序号(n)、随机数(nonce)、目标值(target)、时间戳(timestamp)、难度值(difficulty)、矿工地址(address)等内容

 

好了,介绍完上述基础,我们正式开始本文的内容。

 

以太坊共有四个阶段,即Frontier(前沿)、Homestead(家园)、Metropolis(大都会)、Serenity(宁静)。以太坊前三个阶段采用的是POW共识机。第四个阶段将采用自己创建的POS机制,名为Casper投注共识,这种机制增加了惩罚机制,并基于POS的思想在记账节点中选取验证人。

 

首先介绍以太坊前三阶段使用的POW机制。我们在上节课中讲到,POW机制的基本原理是下面这个公式:

计算值<目标值

 

下面我们具体来看。在以太坊中

f(h, n) <M / d

 

我们先看目标值

M / d

其中M是一个常数,数值非常非常大,取2^256-1

d是当前区块的难度值,

d=pd + pd//2048*max( 1-(t-pt)//10,-99 ) + int(  2** (n//100000-2)  )

其中,pd:前一个区块的难度值

t:当前区块的时间戳

pt:前一个区块的时间戳

n:当前区块的区块序号

其中//为整数除法运算符,a//b,即先计算a/b,然后取不大于a/b的最大整数。

调整难度的目的,是为了使挖矿时间保持在10-19s期间内,如果低于10s增大挖矿难度,如果大于19s将减小难度。另外,计算出的当前区块难度不应低于以太坊创世区块难度,即131072

 

难度系数变大,目标值M / d就越小,所以要计算出满足要求的计算值就越难,这就是难度系数的意思。

 

再看计算值f(h, n)f()这个函数表示一个概念函数,代表一系列的复杂运算。其中输入参数,hn分别是,区块头Header的哈希值、以及Header中的随机数Nonce

计算机的整个挖矿过程,大致可以认为是计算机不断调整尝试Nonce的值,再将计算出的f(h, n)与目标值比较。这就是工作量证明,证明你一直在进行计算工作。因为我们默认,只有你在不算尝试计算,才能找到那个对的nonce。虽然这其中有一定的运气成分,但我们现实生活中也有很多地方是看结果来证明你的工作量,这很好理解啊,你拿到了文凭,我就默认你花过时间学习了。

这就是以太坊的pow过程,具体的源代码,详见文末。

 

好,我们接下来看以太坊第四阶段的共识机制casper。这就是pos的一种。但它有自己的特点:

在有些情况下,矿工的币不但不会增加,反而会减少。为什么呢,我们来看看

 

在casper共识机制中,矿工要拿出保证金对他认为的大概率胜出的区块进行下注。如果赌对了,他们就可以拿回保证金外加区块中的交易费用,也许还会有一些新发的货币;如果下注没有迅速达成一致,他们只能拿回部分保证金,相当于损失了一些保证金。因此数个回合之后矿工的下注分布就会收敛。一旦结果出来,那些选错的矿工就会输掉他们的保证金。此外如果矿工过于显著的改变下注,例如先是赌某个块有很高概率胜出,然后又改赌另外一个块有高概率胜出,他将被严惩。如此朝三暮四的人在区块链中也是不受欢迎的啊。这条规则确保了矿工只有在非常确信其他人也认为某个块有高概率胜出时才下注。我们通过这个机制来确保不会出现下注先收敛于一个结果然后又收敛到另外一个结果的情况。(将该段的情况简单体现在一个PPT页面里)。这就是casper的大致工作机理,由于以太坊目前还没有发布第四个版本,更多细节以后有机会再交流。

 

 

 

源代码:

func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) {

    // Extract some data from the header

    var (

        header = block.Header()

        hash   = header.HashNoNonce().Bytes()

        //target,即M / d,即(2^256-1)/Difficulty

        target = new(big.Int).Div(maxUint256, header.Difficulty)

 

        number  = header.Number.Uint64()

        dataset = ethash.dataset(number)

    )

    // Start generating random nonces until we abort or find a good one

    var (

        attempts = int64(0)

        nonce    = seed

    )

    logger := log.New("miner", id)

    logger.Trace("Started ethash search for new nonces", "seed", seed)

    for {

        select {

        case <-abort:

            // Mining terminated, update stats and abort

            logger.Trace("Ethash nonce search aborted", "attempts", nonce-seed)

            ethash.hashrate.Mark(attempts)

            return

 

        default:

            // We don‘t have to update hash rate on every nonce, so update after after 2^X nonces

            attempts++

            if (attempts % (1 << 15)) == 0 {

                ethash.hashrate.Mark(attempts)

                attempts = 0

            }

            //hashimotoFullRAND(h, n)所代表的一系列的复杂运算

            digest, result := hashimotoFull(dataset, hash, nonce)

            //result满足RAND(h, n)  <=  M / d

            if new(big.Int).SetBytes(result).Cmp(target) <= 0 {

                // Correct nonce found, create a new header with it

                header = types.CopyHeader(header)

                header.Nonce = types.EncodeNonce(nonce)

                header.MixDigest = common.BytesToHash(digest)

 

                // Seal and return a block (if still needed)

                select {

                case found <- block.WithSeal(header):

                    logger.Trace("Ethash nonce found and reported", "attempts", nonce-seed, "nonce", nonce)

                case <-abort:

                    logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce)

                }

                return

            }

            //不断变更Nonce

            nonce++

        }

    }

}

//代码位置consensus/ethash/sealer.go

 

想了解更多?关注我们就够了。

公众号:ipfscom
微信(Q):18191727
Q群:71789361
微信扫一扫,加入知识星球


 

  • 0
    点赞
  • 0
    评论
  • 7
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值