Skip to content

Instantly share code, notes, and snippets.

View bluepnume's full-sized avatar

Daniel Brain bluepnume

  • OneText
  • San Jose
View GitHub Profile
type MemPool = Array<{|
fee : number,
signedTransaction : string
|}>;
type BitcoinNodeType = {|
getPublicKey : () => Promise<string>,
run : () => Promise<void>,
send : (receiver : string, amount : number, fee : number) => Promise<void>,
getBlockChain : () => BlockChainType,
const getBalances = async () : Promise<Counter> => {
const balances = new Counter();
for (let { miner, reward, transactions } of root.getLongestChainAsValues()) {
balances.add(miner, reward);
for (let { receiver, amount, fee, sender } of transactions) {
balances.add(miner, fee);
balances.add(receiver, amount);
balances.subtract(sender, amount);
const addBlock = async (hashedBlock : string) => {
const verifiedBlock = await verifyHashAndUnpack(hashedBlock);
const verifiedTransactions = await asyncMap(verifiedBlock.transactions, verifySignatureAndUnpack);
const fullyVerifiedBlock = {
...verifiedBlock,
transactions: verifiedTransactions
};
const headNode = root.findValueByID(fullyVerifiedBlock.parentid);
const doesHashPassDifficulty = (hash : string, difficulty : number) : boolean => {
return (parseInt(hash, 36) % difficulty) === 0;
}
const calculateNewReward = (headBlock : BlockType) => {
return Math.floor(INITIAL_REWARD / (2 ** Math.floor(headBlock.index / REWARD_HALVING_SCHEDULE)));
};
const calculateNewDifficulty = (headBlock : BlockType, previousHeadBlock : ?BlockType) : number => {
if (!previousHeadBlock) {
return headBlock.difficulty;
}
return (headBlock.time - previousHeadBlock.time) > BLOCK_TIME
? headBlock.difficulty - 1
: headBlock.difficulty + 1;
};
const createBlock = async (publicKey : string, transactions : Array<string>) : Promise<?string> => {
const headBlock = root.getLongestBranchNode().getValue();
const newTransactions = await asyncFilter(transactions, verifyPackedSignature);
const newDifficulty = (headBlock.elapsed) > BLOCK_TIME
? headBlock.difficulty - 1
: headBlock.difficulty + 1;
const newReward = divisibleBy(headBlock.index, REWARD_HALVING_SCHEDULE)
export const BLOCK_TIME = 1000;
export const INITIAL_REWARD = 1024;
export const REWARD_HALVING_SCHEDULE = 20;
export const BLOCK_SIZE_LIMIT = 10;
export const GENESIS_BLOCK : BlockType = {
id: 'GENESIS',
const root = TreeNode(GENESIS_BLOCK);
export type BlockChainType = {|
addBlock : (hashedBlock : string) => Promise<void>,
createBlock : (publicKey : string, transactions : Array<string>) => Promise<?string>,
getBalances : () => Promise<Counter>
|};
export function BlockChain() : BlockChainType {
const createBlock = async (publicKey, transactions) : Promise<?string> => {
};