merkletreets
Version:
merkletree for freeserver
169 lines • 5.39 kB
JavaScript
"use strict";
/**
* 默克尔树
* Copyright(C) 2018 liumurong
*/
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
}
Object.defineProperty(exports, "__esModule", { value: true });
var crypto = __importStar(require("crypto"));
/**
* MerkleTree
*/
var MerkleTree = /** @class */ (function () {
/**
* MerkleTree
* @param opts 选项
*/
function MerkleTree(opts) {
if (opts === void 0) { opts = { leafcount: 0 }; }
this.leaves = new Array(opts.leafcount).fill(this.hashFunc("0x")); // 默认填充0x字符
this._depth = 0;
this.rows = [];
}
/**
* 添加节点
* @param data 叶子节点数据
* @param hashed 是否是Hash值
*/
MerkleTree.prototype.addLeaf = function (data, hashed) {
if (hashed === void 0) { hashed = false; }
if (hashed === true) {
this.leaves.push(data.toString());
return;
}
this.leaves.push(this.hashFunc(data));
};
/**
* 更新叶子节点
* @param index 叶子节点索引
* @param data 数据
* @param hashed 数据是否直接是Hash值
*/
MerkleTree.prototype.updateLeaf = function (index, data, hashed) {
if (hashed === void 0) { hashed = false; }
var leafLength = this.leaves.length;
if (leafLength <= index) {
return;
}
this.leaves[index] = hashed === true ? data.toString() : this.hashFunc(data);
};
/**
* 重新计算整棵树
* 当更新过叶子节点或者添加新节点之后需要重新更新整棵树
* 使用leafcount初始化的树也需要调用此方法
*/
MerkleTree.prototype.update = function () {
var depth = this.depth(true);
this.rows = new Array(depth);
this.rows[depth] = this.leaves;
for (var i = depth - 1; i >= 0; i--) {
this.rows[i] = this.getNodes(this.rows[i + 1]);
}
};
/**
* 据叶子节点获取上一级节点
* @param leaves 叶子节点
*/
MerkleTree.prototype.getNodes = function (leaves) {
var remainder = leaves.length % 2;
var nodes = [];
for (var i = 0; i < leaves.length - 1; i = i + 2) {
nodes[i / 2] = this.hashFunc(leaves[i] + leaves[i + 1]);
}
if (remainder === 1) {
// 将最后一个节点提升等级,并未复制一个新的
nodes[((leaves.length - remainder) / 2)] = leaves[leaves.length - 1];
}
return nodes;
};
/**
* 获取Root节点
*/
MerkleTree.prototype.root = function () {
return this.getTreeNode(0, 0);
};
/**
* 获取树节点
* @param depth 深度
* @param index 索引(本层)
*/
MerkleTree.prototype.getTreeNode = function (depth, index) {
if (depth < 0 || depth > this.depth()) {
return null;
}
var levelNodes = this.getLevelNodes(depth);
if (index < 0 || index >= levelNodes.length) {
return null;
}
var nextLevelNodes = this.getLevelNodes(depth + 1);
var nextLevelIndex = index * 2;
return {
hash: levelNodes[index],
depth: depth,
index: index,
left: {
hash: nextLevelNodes[nextLevelIndex],
depth: depth + 1,
index: nextLevelIndex,
left: null,
right: null
},
right: nextLevelIndex + 1 >= nextLevelNodes.length ? null : {
hash: nextLevelNodes[nextLevelIndex + 1],
depth: depth + 1,
index: nextLevelIndex + 1,
left: null,
right: null
}
};
};
/**
* 树高
* @param force 强制刷新树高
*/
MerkleTree.prototype.depth = function (force) {
if (force === void 0) { force = false; }
if (!this._depth || force === true) {
var pow = 0;
while (Math.pow(2, pow) < this.leaves.length) {
pow++;
}
this._depth = pow;
}
return this._depth;
};
/**
* 获取此级别的所有节点
* @param level 级别
*/
MerkleTree.prototype.getLevelNodes = function (level) {
if (level >= this.rows.length) {
return [];
}
return this.rows[level];
};
/**
* 获取叶子节点的hash值
* @param index 叶子节点的索引
*/
MerkleTree.prototype.getLeafHash = function (index) {
return this.leaves[index];
};
/**
* 计算数据的Hash值,采用sha256算法
* @param data 数据
*/
MerkleTree.prototype.hashFunc = function (data) {
var hash = crypto.createHash("sha256");
return hash.update(data).digest("hex");
};
return MerkleTree;
}());
exports.MerkleTree = MerkleTree;
//# sourceMappingURL=merkletree.js.map