Skip to content

Commit

Permalink
feat(MerkleTree): add MerkleTree class
Browse files Browse the repository at this point in the history
  • Loading branch information
mappum committed Jan 5, 2016
1 parent ed0c5a6 commit 3541b25
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions lib/merkleTree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
var bitcore = require('bitcore')
var hash = bitcore.crypto.Hash.sha256sha256

var MerkleTree = module.exports = function () {
this.depth = 0
this._root = null
this.txids = []
this.matched = []
}

MerkleTree.fromMerkleBlock = function (block) {
var tree = new MerkleTree()
var hashes = block.hashes
var flags = block.flags

tree.depth = Math.ceil(Math.log(block.numTransactions) / Math.log(2))
var stack = []

for (var i = 0; i < flags.length; i++) {
var flag = flags[i]
var node
var depth = stack.length
var leaf = depth === tree.depth
var cursor = stack[stack.length - 1]

if (leaf) {
node = new Node(hashes.shift())
tree.txids.push(hash)
if (flag) tree.matched.push(hash)
} else {
node = new Node(flag ? null : hashes.shift())

if (cursor) {
var left = cursor.add(node)
if (!left && !flag) cursor = stack.pop()
}

if (flag) stack.push(node)
}

if (!i) tree._root = node
}

return tree
}

MerkleTree.prototype.root = function () {
return this._root.getHash()
}

var Node = function (hash) {
this.hash = hash
this.left = null
this.right = null
}
MerkleTree.Node = Node

Node.prototype.getHash = function () {
if (this.hash) return this.hash
var leftHash = this.left.getHash()
var rightHash = (this.right || this.left).getHash()
return hash(leftHash.concat(rightHash))
}

Node.prototype.add = function (child) {
var left = !this.left
this[left ? 'left' : 'right'] = child
return left
}

0 comments on commit 3541b25

Please sign in to comment.