miner mines continuously,
moved to an account model, transactions working, querying working, more checking of valid data
This commit is contained in:
parent
59bb42be11
commit
9847b2056b
12 changed files with 663 additions and 365 deletions
|
@ -1,12 +1,20 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
const { DIFFICULTY, MINE_RATE } = require('../config');
|
||||
|
||||
function concatIfNotUndefined(concatTo, concatting) {
|
||||
if (typeof concatting !== "undefined") {
|
||||
concatTo += `${concatting}`;
|
||||
}
|
||||
}
|
||||
|
||||
class Block {
|
||||
constructor(timestamp, lastHash, hash, data, nonce, difficulty) {
|
||||
constructor(timestamp, lastHash, hash, reward, transactions, metadatas, nonce, difficulty) {
|
||||
this.timestamp = timestamp;
|
||||
this.lastHash = lastHash;
|
||||
this.hash = hash;
|
||||
this.data = data;
|
||||
this.reward = reward;
|
||||
this.transactions = transactions;
|
||||
this.metadatas = metadatas;
|
||||
this.nonce = nonce;
|
||||
if (difficulty === undefined) {
|
||||
this.difficulty = DIFFICULTY;
|
||||
|
@ -15,54 +23,90 @@ class Block {
|
|||
}
|
||||
}
|
||||
|
||||
static getTransactions(block) {
|
||||
if (typeof block.transactions !== "undefined" && block.transactions !== null) {
|
||||
return block.transactions;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
static getMetadatas(block) {
|
||||
if (typeof block.metadatas !== "undefined" && block.metadatas !== null) {
|
||||
return block.metadatas;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `Block -
|
||||
Timestamp : ${this.timestamp}
|
||||
Last Hash : ${this.lastHash.substring(0, 10)}
|
||||
Hash : ${this.hash.substring(0, 10)}
|
||||
Nonce : ${this.nonce}
|
||||
Difficulty: ${this.difficulty}
|
||||
Data : ${this.data}`;
|
||||
Timestamp : ${this.timestamp}
|
||||
Last Hash : ${this.lastHash.substring(0, 10)}
|
||||
Hash : ${this.hash.substring(0, 10)}
|
||||
Nonce : ${this.nonce}
|
||||
Difficulty : ${this.difficulty}
|
||||
Reward : ${this.reward}
|
||||
Transactions : ${this.transactions}
|
||||
Metadatas : ${this.metadatas}`;
|
||||
}
|
||||
|
||||
static genesis() {
|
||||
return new this('Genesis time', '-----', 'f1r57-h45h', [], 0, DIFFICULTY);
|
||||
return new this('Genesis time', '-----', 'f1r57-h45h', null, null, null, 0, DIFFICULTY);
|
||||
}
|
||||
|
||||
//returns false if hash doesn't match
|
||||
static checkHash(hash, timestamp, lastHash, data, nonce, difficulty) {
|
||||
const computedHash = Block.hash(timestamp, lastHash, data, nonce, difficulty);
|
||||
static hash(timestamp, lastHash, reward, transactions, metadatas, nonce, difficulty) {
|
||||
//backwards compatible hashing:
|
||||
//if we add a new type of thing to the chain, the hash of previous blocks won't change as if will be undefined
|
||||
let hashing = `${timestamp}${lastHash}${nonce}${difficulty}`;
|
||||
concatIfNotUndefined(hashing, reward);
|
||||
concatIfNotUndefined(hashing, transactions);
|
||||
concatIfNotUndefined(hashing, metadatas);
|
||||
|
||||
if (computedHash !== hash) {
|
||||
return ChainUtil.hash(hashing).toString();
|
||||
}
|
||||
|
||||
static blockHash(block) {
|
||||
return Block.hash(
|
||||
block.timestamp,
|
||||
block.lastHash,
|
||||
block.reward,
|
||||
block.transactions,
|
||||
block.metadatas,
|
||||
block.nonce,
|
||||
block.difficulty);
|
||||
}
|
||||
|
||||
//returns false if block's hash doesn't match internals
|
||||
static checkHash(block) {
|
||||
|
||||
const computedHash = Block.hash(
|
||||
block.timestamp,
|
||||
block.lastHash,
|
||||
block.reward,
|
||||
block.transactions,
|
||||
block.metadatas,
|
||||
block.nonce,
|
||||
block.difficulty);
|
||||
|
||||
if (computedHash !== block.hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hash.substring(0, difficulty) !== '0'.repeat(difficulty)) {
|
||||
if (block.hash.substring(0, block.difficulty) !== '0'.repeat(block.difficulty)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static hash(timestamp, lastHash, data, nonce, difficulty) {
|
||||
return ChainUtil.hash(`${timestamp}${lastHash}${data}${nonce}${difficulty}`).toString();
|
||||
}
|
||||
|
||||
static blockHash(block) {
|
||||
const { timestamp, lastHash, data, nonce, difficulty } = block;
|
||||
return Block.hash(timestamp, lastHash, data, nonce, difficulty);
|
||||
}
|
||||
|
||||
//returns false if block's hash doesn't match internals
|
||||
static checkBlock(block) {
|
||||
return Block.checkHash(block.hash, block.timestamp, block.lastHash, block.data, block.nonce, block.difficulty);
|
||||
}
|
||||
|
||||
static adjustDifficulty(lastBlock, currentTime) {
|
||||
let { difficulty } = lastBlock;
|
||||
difficulty = lastBlock.timestamp + MINE_RATE > currentTime ?
|
||||
difficulty + 1 : difficulty - 1;
|
||||
return Math.max(0, difficulty);
|
||||
let prevDifficulty = lastBlock.difficulty;
|
||||
if (lastBlock.timestamp + MINE_RATE > currentTime) {
|
||||
return prevDifficulty + 1;
|
||||
} else {
|
||||
return Math.max(0, prevDifficulty - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue