src/lib/ccp-block.js
import { getDifficulty } from '../utils';
import {isValid} from './../schemas';
import {trymore} from 'crypto-io-utils';
import {read} from 'crypto-io-fs';
import events from './bus';
import {validateTransactions, createRewardTransaction} from './transaction';
import {calculateBlockHash} from './hash';
import {BlockError, TransactionError} from './errors.js';
/**
* validate block
*
* @param {object} previousBlock
* @param {object} block
* @param {number} difficulty
* @param {number} unspent
*/
export const validateBlock = (previousBlock, block, difficulty, unspent) => {
if (!isValid('block', block)) throw BlockError('data');
if (previousBlock.index + 1 !== block.index) throw BlockError('index');
if (previousBlock.hash !== block.prevHash) throw BlockError('prevhash');
if (calculateBlockHash(block) !== block.hash) throw BlockError('hash');
if (blockDifficulty(block) > difficulty) throw BlockError('difficulty');
return validateTransactions(block.transactions, unspent);
};
/**
* Create genesis block
*
* @return {object} {index, prevHash, time, transactions, nonce}
*/
export const genesisBlock = () => {
const block = {
index: 0,
prevHash: '0',
time: Math.floor(new Date().getTime() / 1000),
transactions: [],
nonce: 0
};
block.hash = calculateBlockHash(block);
return block;
};
/**
* Get hash difficulty
*
* @param {*} hash
* @return {number}
*/
export const difficulty = (hash) => {
return parseInt(hash.substring(0, 8), 16);
};
/**
* Get hash difficulty from block
*
* @param {*} hash
* @return {number}
*/
export const blockDifficulty = ({hash}) => {
return difficulty(hash);
};
/**
* Create new block
*
* @param transactions {array}
* @param lastBlock {object}
* @param address {string}
* @return {index, prevHash, time, transactions, nonce}
*/
export const block = (transactions, lastBlock, address) => {
transactions = transactions.slice();
transactions.push(createRewardTransaction(address, lastBlock.index + 1));
const block = {
index: lastBlock.index + 1,
prevHash: lastBlock.hash,
time: Math.floor(new Date().getTime() / 1000),
transactions,
nonce: 0,
};
block.hash = calculateBlockHash(block);
return block;
};
export default block;