Created
July 12, 2020 09:27
-
-
Save sudo-vaibhav/16a7c65d4668be7e56e93f53a87fe457 to your computer and use it in GitHub Desktop.
blockchain code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//setup for the server and other third party node modules | |
const port = process.env.PORT || 3000 | |
const express = require("express") | |
const app = express() | |
// this will allow cross-domain access | |
const cors = require("cors") | |
app.use(cors()) | |
//for parsing json content in requests | |
const bodyParser = require('body-parser') | |
app.use(bodyParser.json()) | |
//this will help assign a unique id to each block | |
const { | |
v4: uuidv4 | |
} = require('uuid') | |
//Block class | |
class Block { | |
constructor(proposerId, data) { | |
this.proposer = proposerId | |
this.data = data | |
this.approvals = [proposerId] //obviously a proposer will approve his own block | |
this.blockId = uuidv4() //assigns a unique id to each proposal for tracking later | |
} | |
} | |
//Blockchain class | |
class Blockchain { | |
constructor() { | |
this.chain = [] | |
this.nodes = {} | |
this.proposalBuffer = [] | |
} | |
stake(block) { | |
this.nodes[block.proposer].balance -= STAKE_AMOUNT | |
this.proposalBuffer.push(block) | |
} | |
runConsensus() { | |
console.log("running consensus algorithm now!") | |
this.proposalBuffer.forEach(proposal => { | |
let approvalsCount = proposal.approvals.length | |
let nodesCount = Object.keys(this.nodes).length | |
let approvalRatio = (approvalsCount / nodesCount) | |
if (approvalRatio > CONSENSUS_THRESHOLD) { | |
this.addBlock(proposal) | |
//now reward the proposer | |
console.log("proposal approved!!", proposal) | |
this.nodes[proposal.proposer].balance += REWARD_AMOUNT | |
} else { | |
//the block doesn't get added and proposer gets less amount of tokens back | |
console.log("proposal rejected!!", proposal) | |
this.nodes[proposal.proposer].balance += PENALIZED_AMOUNT | |
} | |
}) | |
//now we clear the buffer as it has run its course now | |
this.proposalBuffer = [] | |
} | |
addBlock(block) { | |
this.chain.push(block) | |
} | |
addNode(node) { | |
if (this.nodes[node.id]) { | |
return false //means another node with same id already exists | |
} else { | |
this.nodes[node.id] = node // adding a new node and allocating it the initial balance | |
return true | |
} | |
} | |
} | |
//Node class (each medical organisation will be a node on the network) | |
class Node { | |
constructor(id, blockchain) { | |
this.id = id | |
this.balance = INITIAL_BALANCE | |
//now get this node added to blockchain network | |
blockchain.addNode(this) | |
} | |
propose(data) { | |
let block = new Block(this.id, data) | |
blockchain.stake(block) | |
return block.blockId // returns the uuid of proposed block | |
} | |
} | |
let blockchain = new Blockchain() | |
app.post("/proposeblock", (req, res) => { | |
const { | |
id, | |
data | |
} = req.body | |
try { | |
const blockId = blockchain.nodes[id].propose(data) | |
res.status(200).send({ | |
blockId | |
}) | |
} catch { | |
res.status(404).send("user not found") | |
} | |
}) | |
app.post("/addNode", (req, res) => { | |
const { | |
id | |
} = req.body | |
let node = new Node(id, blockchain) | |
res.status(200).send("OK") | |
}) | |
//for adding a | |
app.post("/approve", (req, res) => { | |
const { | |
id, | |
blockId | |
} = req.body | |
for (let proposal of blockchain.proposalBuffer) { | |
if (proposal.blockId == blockId) { | |
console.log(proposal.approvals) | |
if (!proposal.approvals.includes(id)) { | |
proposal.approvals.push(id) | |
} | |
break | |
} | |
} | |
res.status(200).send("OK") | |
}) | |
app.get("/runconsensus", (req, res) => { | |
blockchain.runConsensus() | |
res.status(200).send(blockchain) | |
}) | |
app.get("/blockchain", (req, res) => { | |
res.status(200).send(blockchain) | |
}) | |
app.get("/", (req, res) => { | |
res.redirect("/blockchain") | |
}) | |
app.listen(port, () => { | |
console.log(`listening on port ${port}`) | |
setInterval(() => { | |
// maintains the blockchain periodically by rewarding valuable | |
// contributions and penalizing the wrong ones by deducting the staked amount | |
blockchain.runConsensus() | |
}, THIRTY_MINUTES) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment