Skip to content

BlockChain

Using Deno

blockChain.ts

ts
import { createHash } from "node:crypto";

/**
 * Generate SHA-256
 * @param {string} message
 * @returns {string}
 */
const generateHash = (message: string): string => {
  return createHash("sha256").update(message).digest("hex");
};

class Block {
  timeStamp: string;
  data: string[];
  prevHash: string;
  hash: string;

  constructor(timeStamp = "", data: string[] = []) {
    this.timeStamp = timeStamp;
    this.data = data;
    this.prevHash = "";
    this.hash = this.getHash();
  }

  getHash(): string {
    return generateHash(this.timeStamp + JSON.stringify(this.data) + this.prevHash);
  }

  toString(): string {
    return `[BLOCK]
    TimeStamp:     ${this.timeStamp}
    Data:          ${JSON.stringify(this.data)}
    Previous Hash: ${this.prevHash}
    Hash:          ${this.hash}
    `;
  }
}

class BlockChain {
  chain: Block[];

  constructor() {
    this.chain = [this.getGenesisBlock()];
  }

  getGenesisBlock(): Block {
    const now = new Date().getTime().toString();
    return new Block(now);
  }

  getLastBlock(): Block {
    return this.chain[this.chain.length - 1];
  }

  addNewBlock(newBlock: Block) {
    newBlock.prevHash = this.getLastBlock().hash;
    newBlock.hash = newBlock.getHash();

    // I M M U T A B I L I T Y
    const frozenBlock = Object.freeze(newBlock);
    this.chain.push(frozenBlock);
  }

  isValid(): boolean {
    for (let i = 1; i < this.chain.length; i++) {
      const currentBlock = this.chain[i];
      const prevBlock = this.chain[i - 1];

      if (currentBlock.hash !== currentBlock.getHash() || prevBlock.hash !== currentBlock.prevHash) {
        return false;
      }
    }

    return true;
  }
}

blockChain.test.ts

deno test blockChain.test.ts

ts
import { assertEquals } from "jsr:@std/assert";

Deno.test("BlockChain", () => {
  const now = new Date();
  const blockChain = new BlockChain();

  const firstBlock = new Block(now.getTime().toString(), ["Hello World"]);
  blockChain.addNewBlock(firstBlock);

  assertEquals(blockChain.getLastBlock().hash, firstBlock.hash);

  const secondBlock = new Block(now.setMinutes(now.getMinutes() + 30).toString(), ["Lorem Ipsum"]);
  blockChain.addNewBlock(secondBlock);

  assertEquals(blockChain.getLastBlock().hash, secondBlock.hash);

  const thirdBlock = new Block(now.setHours(now.getHours() + 12).toString(), ["Dolor Sit Amet"]);
  blockChain.addNewBlock(thirdBlock);

  assertEquals(blockChain.getLastBlock().hash, thirdBlock.hash);
  assertEquals(blockChain.isValid(), true);
});

Released under the MIT License.