Skip to content

Instantly share code, notes, and snippets.

@amaranter
Created August 13, 2017 21:51
Show Gist options
  • Save amaranter/4c1734fa2ca587a68e8cd9698444647d to your computer and use it in GitHub Desktop.
Save amaranter/4c1734fa2ca587a68e8cd9698444647d to your computer and use it in GitHub Desktop.
Merkle Tree Implementation with Javascript and CryptoJS (SHA-256)
var MerkleTree = require('./MerkleTree.js'),
transaction = ['1', '2', '3', '4'],
tree = new MerkleTree(transaction);
tree.createTree();
console.log('>>> Log: ', tree.getOldTransaction());
console.log('>>> Root Hash: ', tree.getRootHash());
/**
* MerkleTree Implementation
* @version 1.0.0
* @author Ronny Amarante <me@amaranter.com>
*/
var SHA256 = require("crypto-js/sha256");
function MerkleTree(transactions) {
this.transactions = transactions;
this._oldTransaction = {};
}
MerkleTree.prototype = {
getOldTransaction: function() { return this._oldTransaction; },
getRootHash: function() {
var idx = Object.keys(this._oldTransaction)[Object.keys(this._oldTransaction).length-1]
return this._oldTransaction[idx];
},
createTree: function() {
var transactions = this.transactions,
temp = [];
for (var idx = 0; idx < this.transactions.length; idx += 2) { /** Iterate using 2 step's */
var tr = this.transactions[idx],
hash = { l: '', r: '' },
pos_idx = parseInt(idx)+1,
pos_right;
hash["l"] = this._oldTransaction[tr] = String(SHA256(tr)); /** Apply SHA-256 hash to left pair transaction */
(pos_idx != this.transactions.length) ? pos_right = this.transactions[pos_idx] : pos_right = ''; /** Declare value of right pair */
if (pos_right != '') { /** Verify existence of right pair */
hash["r"] = String(SHA256(pos_right)); /** Apply SHA-256 hash to right pair transaction */
this._oldTransaction[this.transactions[pos_idx]] = hash["r"] ; /** Persist log */
temp.push(hash["l"] + hash["r"]); /** Persist merge of both hash's */
} else {
temp.push(hash["l"]); /** Persist merge of left pair if donst have right pair */
}
}
if (this.transactions.length != 1) {
this.transactions = temp; /** Store changes of transactions */
this.createTree(); /** Invoke recursive */
}
}
}
module.exports = MerkleTree;
var assert = require('chai').assert,
MerkleTree = require('../lib/MerkleTree.js');
describe('MerkleTree', function() {
describe('Even Number transaction for ["a", "b", "c", "d"]', function() {
it('should return return the correct Root Hash', function(){
var tree = new MerkleTree(['a', 'b', 'c', 'd']);
tree.createTree();
assert.equal(tree.getRootHash(),'58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd');
});
});
describe('Odd Number transaction for ["a", "b", "c", "d", "e"]', function() {
it('should return return the correct Root Hash', function(){
var tree = new MerkleTree(['a', 'b', 'c', 'd', 'e']);
tree.createTree();
assert.equal(tree.getRootHash(),'d6246621103b5050cf32df614c5017e91853d47a19fe5d3e7c68a8f4588f5b66');
});
});
});
 Log:  { 
  '1': '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b',
  '2': 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35',
  '3': '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce',
  '4': '4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a',
  '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4bd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35': '33b675636da5dcc86ec847b38c08fa49ff1cace9749931e0a5d4dfdbdedd808a',
  '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a': '13656c83d841ea7de6ebf3a89e0038fea9526bd7f686f06f7a692343a8a32dca',
  '33b675636da5dcc86ec847b38c08fa49ff1cace9749931e0a5d4dfdbdedd808a13656c83d841ea7de6ebf3a89e0038fea9526bd7f686f06f7a692343a8a32dca': '85df8945419d2b5038f7ac83ec1ec6b8267c40fdb3b1e56ff62f6676eb855e70' 
 }
 Root Hash:  '85df8945419d2b5038f7ac83ec1ec6b8267c40fdb3b1e56ff62f6676eb855e70'
{
"name": "merkle-tree",
"version": "1.0.0",
"description": "Merkle Tree implementation",
"scripts": {
"start": "node lib/main.js",
"test": "mocha test/MerkleTreeTest.js"
},
"author": "@amaranter",
"license": "MIT",
"devDependencies": {
"chai": "^4.1.1",
"crypto-js": "^3.1.9-1",
"mocha": "^3.5.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment