UNPKG

merkletreets

Version:

merkletree for freeserver

169 lines 5.39 kB
"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