# 第二章 工作量证明和挖矿

### 工作量证明拼图和难易度

const hashMatchesDifficulty = (hash: string, difficulty: number): boolean => {
const hashInBinary: string = hexToBinary(hash);
const requiredPrefix: string = '0'.repeat(difficulty);
return hashInBinary.startsWith(requiredPrefix);
};


class Block {

public index: number;
public hash: string;
public previousHash: string;
public timestamp: number;
public data: string;
public difficulty: number;
public nonce: number;

constructor(index: number, hash: string, previousHash: string,
timestamp: number, data: string, difficulty: number, nonce: number) {
this.index = index;
this.previousHash = previousHash;
this.timestamp = timestamp;
this.data = data;
this.hash = hash;
this.difficulty = difficulty;
this.nonce = nonce;
}
}


### 挖矿

const findBlock = (index: number, previousHash: string, timestamp: number, data: string, difficulty: number): Block => {
let nonce = 0;
while (true) {
const hash: string = calculateHash(index, previousHash, timestamp, data, difficulty, nonce);
if (hashMatchesDifficulty(hash, difficulty)) {
return new Block(index, hash, previousHash, timestamp, data, difficulty, nonce);
}
nonce++;
}
};


### 难易度共识

• BLOCK_GENERATION_INTERVAL： 定义 一个区块产出的 频率(比特币中该值是设置成10分钟的， 即每10分钟产出一个区块)
• DIFFICULTY_ADJUSTMENT_INTERVAL: 定义 修改难易度以适应网络不断增加或者降低的网络算力(hashRate, 即每秒能计算的哈希的数量)的 频率(比特币中是设置成2016个区块， 即每2016个区块，然后根据这些区块生成的耗时，做一次难易度调整)

// in seconds
const BLOCK_GENERATION_INTERVAL: number = 10;

// in blocks


const getDifficulty = (aBlockchain: Block[]): number => {
const latestBlock: Block = aBlockchain[blockchain.length - 1];
if (latestBlock.index % DIFFICULTY_ADJUSTMENT_INTERVAL === 0 && latestBlock.index !== 0) {
} else {
return latestBlock.difficulty;
}
};

const getAdjustedDifficulty = (latestBlock: Block, aBlockchain: Block[]) => {
const timeExpected: number = BLOCK_GENERATION_INTERVAL * DIFFICULTY_ADJUSTMENT_INTERVAL;
const timeTaken: number = latestBlock.timestamp - prevAdjustmentBlock.timestamp;
if (timeTaken < timeExpected / 2) {
} else if (timeTaken > timeExpected * 2) {
} else {
}
};


### 时间戳校验

• 新区块时间戳比当前时间最晚不晚过1分钟，那么我们认为该区块有效。
• 新区块时间戳比前一区块的时间戳最早不早过1分钟，那么我们任务该区块在区块链中是有效的。
const isValidTimestamp = (newBlock: Block, previousBlock: Block): boolean => {
return ( newBlock.timestamp - 60 < getCurrentTimestamp() )
&& ( previousBlock.timestamp - 60 < newBlock.timestamp );
};


### 验证测试

• 安装运行
npm install
npm run node1
npm run node2

• 挖矿

• 难易度调整

• 选择最大累积难易度的链

### 小结

posted @ 2019-06-23 14:02  天地会珠海分舵  阅读(443)  评论(0编辑  收藏  举报