Permalink
Browse files

Added logic for generating a merkle tree, and it works!

  • Loading branch information...
ihatecsv committed May 27, 2017
1 parent 45df8e4 commit 905ce15d259ee236a00eafd57b016e2381c61a3e
Showing with 89 additions and 4 deletions.
  1. +89 −4 index.js
@@ -1,21 +1,85 @@
var crypto = require('crypto');
function compareNode(a, b) {
if (a.getHash() < b.getHash())
return -1;
if (a.getHash() > b.getHash())
return 1;
return 0;
}
var sha256 = function(string){
return crypto.createHash('sha256').update(string).digest('base16').toString('hex');
}
class MerkleNode {
constructor(transaction, parentNode, childNode0, childNode1, transaction) {
constructor(parentNode, childNode0, childNode1, transaction) {
this.parentNode = parentNode;
this.childNodes = [];
this.childNodes[0] = childNode0;
this.childNodes[1] = childNode1;
this.transaction = transaction;
}
computeHash() {
if(this.childNodes[0] == null){
this.hash = sha256(JSON.stringify(transaction));
if(this.transaction != null){
this.hash = sha256(JSON.stringify(this.transaction));
}else{
this.hash = sha256(childNodes[0].hash + childNodes[1].hash);
this.hash = sha256(this.childNodes[0].hash + this.childNodes[1].hash);
}
}
setParentNode(parentNode){
this.parentNode = parentNode;
}
setChildNode(index, childNode){
this.childNodes[index] = childNode;
}
getHash() {
return this.hash;
}
}
class MerkleTree {
constructor(){
this.leveledHashes = [];
this.rootHash = "";
}
getRootHash(){
return this.rootHash;
}
genTree(transactions){
transactions.sort();
var cL = 0;
var root = false;
this.leveledHashes[cL] = [];
for(var i = 0; i < transactions.length; i++){ //go through each transaction,
var newNode = new MerkleNode(null, null, null, transactions[i]); //add each one to a new merkle node
newNode.computeHash(); //compute the hash
this.leveledHashes[cL].push(newNode); //push to the current (bottom) level of the tree
}
this.leveledHashes[cL].sort(compareNode); //sort the base row
while(!root){ //while we're below the root node
cL++; //increase our current level
this.leveledHashes[cL] = [];
if(this.leveledHashes[cL-1].length % 2 != 0){ //if the number of hashes in the previous level is not even
this.leveledHashes[cL-1].push(this.leveledHashes[cL-1][this.leveledHashes[cL-1].length-1]); //duplicate the last hash
}
for(var i = 0; i < this.leveledHashes[cL-1].length; i++){ //loop through the hashes in the previous level
if(i%2 == 0){ //if the index is even
var newNode = new MerkleNode(null, this.leveledHashes[cL-1][i], this.leveledHashes[cL-1][i+1], null); //make a new node at the current level, with children of the two below nodes.
newNode.computeHash(); //compute hash from children
this.leveledHashes[cL-1][i].setParentNode(newNode); //set children to ref parent
this.leveledHashes[cL-1][i+1].setParentNode(newNode); //set children to ref parent
this.leveledHashes[cL].push(newNode); //add the new node to the current level
}
}
if(this.leveledHashes[cL].length == 1){
root = true;
this.rootHash = this.leveledHashes[cL][0].getHash();
}
}
}
}
@@ -40,7 +104,28 @@ class Block {
}
}
var exampleTransactions = [
new Transaction(null, "fre332", 0.0025, 1214416, true),
new Transaction("fr332", "blfah", 0.0025, 1214416, false),
new Transaction("blfah", "gsdfg", 0.0025, 1214416, false),
new Transaction("afdaf", "kdilv", 0.0025, 1214416, false),
new Transaction("asfkw", "drake", 0.0025, 1214416, false),
new Transaction("dkkp9", "go3hb", 0.0025, 1214416, false),
new Transaction("dweih", "djnjn", 0.0025, 1214416, false),
new Transaction("eee5f", "3jkkj", 0.0024, 1214416, false),
new Transaction("39ifm", "n3udu", 0.0025, 1214416, false),
new Transaction("3kmmd", "3ikm3", 0.0025, 1214416, false),
new Transaction("disal", "5ktkt", 0.0025, 1214416, false),
new Transaction("fdsjk", "329iv", 0.0025, 1214416, false),
new Transaction("sdfnm", "2kjni", 0.0025, 1214416, false)
];
//var preGenesisHash = "0000000000000000000000000000000000000000000000000000000000000000";
var newTree = new MerkleTree();
newTree.genTree(exampleTransactions);
console.log(newTree.getRootHash());
//var time = Math.round((new Date()).getTime() / 1000);
//var testBlock = new Block(preGenesisHash, transactions, time);

0 comments on commit 905ce15

Please sign in to comment.