Skip to content

POW and Minting

gc87 edited this page Aug 7, 2018 · 2 revisions

概述

源文件
miner.h、miner.cpp CMinerWork、CMiner

主要变量及函数

变量

变量名称 类型 描述
CMinerWork vchWorkData vector 需要惊醒hash的工作量数据
hashPrev uint256 前一区块的hash
nPrevTime int64 前一区块的产生时间
nAlgo int 算法标识,1:POWA_BLAKE512
nBits int hash结果的长度

函数

方式获取工作量数据(json-rpc)

bool CMiner::GetWork()

返回值

{
    "prevblockhash" : "17f820812707cf8c18f91a01054d28514c06bf7ddf604d9e33a766cc9e1b29a8",
    "prevblocktime" : 1531419134,
    "algo" : 1,
    "bits" : 37,
    "data" : "01000100309a475ba8291b9ecc66a7339e4d60df7dbf064c51284d05011af9188ccf07278120f8174300000000000000000000000000000000000000000000000000000000000000000001250000000000000000000000000000000000000000000000000000000000000000"
}

prevblockhash:前一区块的hash;

prevblocktime:前一区块的产生时间戳;

algo:hash算法标识;

bits:当前hash难度度量;

data:需要hash的数据;

以上数据每次获取并解析之后对CMiner.workCurrent的对应字段赋值,供后续POW算法使用。

定时获取需要工作量数据

void CMiner::LaunchFetcher()

循环调用GetWork通过json-rpc获取工作量数据,每一次获取间隔为30s。

提交工作量证明数据(json-rpc)

bool CMiner::SubmitWork(const vector<unsigned char>& vchWorkData)

通过json-rpc提交工作量证明的数据。

启动挖矿

void CMiner::LaunchMiner()

函数内部声明了变量work用于循环同步GetWork函数中设置的workCurrent。

work.vchWorkData[4]到work.vchWorkData[8]之间的数据作为uint_32类型被变量nTime引用,并随着对nTimer的操作而改变。

work.vchWorkData的末32字节数据作为uint256类型被变量nNonce引用,并随着对nNonce的操作而改变。

nTime作为GetHashTarget函数的参数,可以动态计算出一个当前难度的uint256类型数字(32字节),作为后续的POW过程是否找到合适的解的度量,例如当前由GetHashTarget函数计算出的数字为:0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,当实际的POW过程计算出的hash小于或等于该度量时,说明找到了合适的解,比如:0x00006cf57237a44938e8815c8bca1494233191c6893529ce954066c01aa6a502即为一个满足的工作量证明结果。

nNonce在循环的POW计算过程中自增,nTime和nNonce的变化共同导致了work.vchWorkData的数据变化,间接导致了POW计算过程中hash函数对work.vchWorkData计算结果的变化。

每次循环中POW计算的结果与上面所说的hashTarget对比,满足条件则立即调用SubmitWork函数提交计算结果(当前work.vchWorkData),不满足条件则进入下一轮计算。

POW计算所使用的单向散列函数为crypto_generichash_blake2b,来源于开源项目libsudium,该函数被自定义为产生uint256类型的结果(32字节)。

Hash目标函数

uint256 CMiner::GetHashTarget(const CMinerWork& work,int64 nTime)

该函数可以动态调节POW过程的难度。如果nTime -work.nPrevTime的结果小于60s,则返回work.nBit + 1(转换为uint256),否则通过nBits -= (nTime - work.nPrevTime - 60) / 60计算一个不大于16的值(nBits),将0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff按位右移nBits位,并将其作为返回值(uint256)。

整理者 日期
Chun Gao 2018.08.06