Block Hash算法
Block头部信息的构成:
nHeight+1) % nInterval != 0) {
// 未达到周期个数,无需调节
return pindexLast->nBits;
}
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++) pindexFirst = pindexFirst->pprev;
// 计算本次2016个块的实际产生时间
// Limit adjustment step
int64 nActualTimespan = pindexLast->GetBlockTime() – pindexFirst->GetBlockTime();
// 限定幅度,最低为1/4,最高为4倍
if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// 根据最近2016个块的时间,重新计算目标难度
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;
return bnNew.GetCompact();
Block字段详解
1、Version,版本号,很少变动,一般用于软件全网升级时做标识
2、hashPrevBlock,前向Block Hash值,该字段强制多个Block之间形成链接
3、hashMerkleRoot,交易Hash树的根节点Hash值,起校验作用,保障Block在网络传输过程中的数据一致性,有新交易加入即发生变化
4、Time,Unix时间戳,每秒自增一,标记Block的生成时间,同时为block hash探寻引入一个频繁的变动因子
5、Bits,可以推算出难度值,用于验证block hash难度是否达标
6、Nonce,随机数,在上面数个字段都固定的情况下,不停地更换随机数来探寻
最为关键的字段是hashPrevBlock,该字段使得Block之间链接起来,形成一个巨大的“链条”。Block本是稀松平常的数据结构,但以链式结构组织起来后却使得它们具有非常深远的意义:
1、形成分支博弈,使得算力总是在主分支上角逐
2、算力攻击的概率难度呈指数上升(泊松分布)
每个block都必须指向前一个block,否则无法验证通过。追溯至源头,便是高度为零的创世纪块(Genesis Block),这里是Block Chain的起点,其前向block hash为零,或者说为空。