zcash的難度調(diào)整算法在zcash的協(xié)議文檔(Protocol Specification)p37愉镰,6.4.3 Dif culty adjustment中有詳細(xì)描述,在源碼中的實(shí)現(xiàn)位于
https://github.com/zcash/zcash/blob/master/src/pow.cpp 的CalculateNextWorkRequired中卿啡,由于源碼中的實(shí)現(xiàn)分散于各個(gè)相關(guān)文件墨缘,現(xiàn)使用C語言集中實(shí)現(xiàn)與解釋如下
常量定義
static int64_t pow_averaging_window = 17;
static int64_t pow_max_adjust_down = 32;
static int64_t pow_max_adjust_up = 16;
static int64_t pow_target_spacing = 150;
static int pow_median_blockspan = 11;
staic double pow_limit = 0.0;
if(testnet)
pow_limit = pow(2, 251) - 1;
else
pow_limit = pow(2, 243) - 1;
實(shí)現(xiàn)及解釋
int64_t get_actual_timespan(uint32_t height)
{
uint64_t timestamps[11] = {0};
uint64_t timestamps2[11] = {0};
//獲取前當(dāng)前塊的前11個(gè)塊及height - pow_averaging_window前11塊的中位數(shù)(注意是降序排列)時(shí)間之差
get_block_times(height, timestamps);
get_block_times(height - pow_averaging_window, timestamps2);
return get_median_time(timestamps) - get_median_time(timestamps2);
}
double get_nextblock_target(bool testnet, uint32_t height)
{
double mean_target = 0.0;
if (height <= pow_averaging_window) {
mean_target = pow_limit;
} else {
sds nbits[17];
//當(dāng)前塊的前17塊的難度
get_block_nbits(height, nbits);
//求得平均值
mean_target = get_mean_target(nbits);
}
int64_t actual_timespan = get_actual_timespan(height);
int64_t averaging_window_timespan = pow_averaging_window * pow_target_spacing;
actual_timespan = averaging_window_timespan + (actual_timespan - averaging_window_timespan) / 4;
int64_t min_actual_timespan = (averaging_window_timespan * (100 - pow_max_adjust_up)) / 100;
int64_t max_actual_timespan = (averaging_window_timespan * (100 + pow_max_adjust_down)) / 100;
if (actual_timespan < min_actual_timespan) {
actual_timespan = min_actual_timespan;
}
if (actual_timespan > max_actual_timespan) {
actual_timespan = max_actual_timespan;
}
printf("averaging_window_timespan:%ld, mean_target * actual_timespan:%lf\n", averaging_window_timespan, mean_target * actual_timespan);
double target = mean_target * actual_timespan / averaging_window_timespan;
if (target > pow_limit)
target = pow_limit;
printf("target:%lf\n", target);
return floor(target);
}
數(shù)據(jù)壓縮(會(huì)省略后幾位非零數(shù)字)贩汉,得到nbit,此時(shí)得到的數(shù)據(jù)才會(huì)跟鏈上的數(shù)據(jù)相等
至于怎么得到nbits革屠,請(qǐng)查閱
http://www.reibang.com/p/169458321386