Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #149 from dvf/dvf/js
Browse files Browse the repository at this point in the history
Minimal JS Implementation
  • Loading branch information
dvf committed May 10, 2019
2 parents 28d3ee8 + a4afa98 commit 1369cac
Show file tree
Hide file tree
Showing 5 changed files with 2,986 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -102,3 +102,5 @@ ENV/

# PyCharm
.idea/

node_modules/
102 changes: 102 additions & 0 deletions js/blockchain.js
@@ -0,0 +1,102 @@
const crypto = require("crypto");


class Blockchain {
constructor() {
this.chain = [];
this.pendingTransactions = [];
this.newBlock();
this.peers = new Set();
}

/**
* Adds a node to our peer table
*/
addPeer(host) {
this.peers.add(host);
}

/**
* Adds a node to our peer table
*/
getPeers() {
return Array.from(this.peers);
}

/**
* Creates a new block containing any outstanding transactions
*/
newBlock(previousHash, nonce = null) {
let block = {
index: this.chain.length,
timestamp: new Date().toISOString(),
transactions: this.pendingTransactions,
previousHash,
nonce
};

block.hash = Blockchain.hash(block);

console.log(`Created block ${block.index}`);

// Add the new block to the blockchain
this.chain.push(block);

// Reset pending transactions
this.pendingTransactions = [];
}

/**
* Generates a SHA-256 hash of the block
*/
static hash(block) {
const blockString = JSON.stringify(block, Object.keys(block).sort());
return crypto.createHash("sha256").update(blockString).digest("hex");
}

/**
* Returns the last block in the chain
*/
lastBlock() {
return this.chain.length && this.chain[this.chain.length - 1];
}

/**
* Determines if a hash begins with a "difficulty" number of 0s
*
* @param hashOfBlock: the hash of the block (hex string)
* @param difficulty: an integer defining the difficulty
*/
static powIsAcceptable(hashOfBlock, difficulty) {
return hashOfBlock.slice(0, difficulty) === "0".repeat(difficulty);
}

/**
* Generates a random 32 byte string
*/
static nonce() {
return crypto.createHash("sha256").update(crypto.randomBytes(32)).digest("hex");
}

/**
* Proof of Work mining algorithm
*
* We hash the block with random string until the hash begins with
* a "difficulty" number of 0s.
*/
mine(blockToMine = null, difficulty = 4) {
const block = blockToMine || this.lastBlock();

while (true) {
block.nonce = Blockchain.nonce();
if (Blockchain.powIsAcceptable(Blockchain.hash(block), difficulty)) {
console.log("We mined a block!")
console.log(` - Block hash: ${Blockchain.hash(block)}`);
console.log(` - nonce: ${block.nonce}`);
return block;
}
}
}
}

module.exports = Blockchain;
37 changes: 37 additions & 0 deletions js/index.js
@@ -0,0 +1,37 @@
const Blockchain = require("./blockchain");
const {send} = require("micro");

const blockchain = new Blockchain();


module.exports = async (request, response) => {
const route = request.url;

// Keep track of the peers that have contacted us
blockchain.addPeer(request.headers.host);

let output;

switch (route) {
case "/new_block":
output = blockchain.newBlock();
break;

case "/last_block":
output = blockchain.lastBlock();
break;

case "/get_peers":
output = blockchain.getPeers();
break;

case "/submit_transaction":
output = blockchain.addTransaction(transaction);
break;

default:
output = blockchain.lastBlock();

}
send(response, 200, output);
};

0 comments on commit 1369cac

Please sign in to comment.