UNPKG

iota.lib.js

Version:
178 lines (132 loc) 4.78 kB
var Curl = require("../curl/curl"); var Kerl = require("../kerl/kerl"); var Converter = require("../converter/converter"); var tritAdd = require("../helpers/adder"); /** * * @constructor bundle **/ function Bundle() { // Declare empty bundle this.bundle = []; } /** * * **/ Bundle.prototype.addEntry = function(signatureMessageLength, address, value, tag, timestamp, index) { for (var i = 0; i < signatureMessageLength; i++) { var transactionObject = new Object(); transactionObject.address = address; transactionObject.value = i == 0 ? value : 0; transactionObject.obsoleteTag = tag; transactionObject.tag = tag; transactionObject.timestamp = timestamp; this.bundle[this.bundle.length] = transactionObject; } } /** * * **/ Bundle.prototype.addTrytes = function(signatureFragments) { var emptySignatureFragment = ''; var emptyHash = '999999999999999999999999999999999999999999999999999999999999999999999999999999999'; var emptyTag = '9'.repeat(27); var emptyTimestamp = '9'.repeat(9); for (var j = 0; emptySignatureFragment.length < 2187; j++) { emptySignatureFragment += '9'; } for (var i = 0; i < this.bundle.length; i++) { // Fill empty signatureMessageFragment this.bundle[i].signatureMessageFragment = signatureFragments[i] ? signatureFragments[i] : emptySignatureFragment; // Fill empty trunkTransaction this.bundle[i].trunkTransaction = emptyHash; // Fill empty branchTransaction this.bundle[i].branchTransaction = emptyHash; this.bundle[i].attachmentTimestamp = emptyTimestamp; this.bundle[i].attachmentTimestampLowerBound = emptyTimestamp; this.bundle[i].attachmentTimestampUpperBound = emptyTimestamp; // Fill empty nonce this.bundle[i].nonce = emptyTag; } } /** * * **/ Bundle.prototype.finalize = function() { var validBundle = false; while(!validBundle) { var kerl = new Kerl(); kerl.initialize(); for (var i = 0; i < this.bundle.length; i++) { var valueTrits = Converter.trits(this.bundle[i].value); while (valueTrits.length < 81) { valueTrits[valueTrits.length] = 0; } var timestampTrits = Converter.trits(this.bundle[i].timestamp); while (timestampTrits.length < 27) { timestampTrits[timestampTrits.length] = 0; } var currentIndexTrits = Converter.trits(this.bundle[i].currentIndex = i); while (currentIndexTrits.length < 27) { currentIndexTrits[currentIndexTrits.length] = 0; } var lastIndexTrits = Converter.trits(this.bundle[i].lastIndex = this.bundle.length - 1); while (lastIndexTrits.length < 27) { lastIndexTrits[lastIndexTrits.length] = 0; } var bundleEssence = Converter.trits(this.bundle[i].address + Converter.trytes(valueTrits) + this.bundle[i].obsoleteTag + Converter.trytes(timestampTrits) + Converter.trytes(currentIndexTrits) + Converter.trytes(lastIndexTrits)); kerl.absorb(bundleEssence, 0, bundleEssence.length); } var hash = []; kerl.squeeze(hash, 0, Curl.HASH_LENGTH); hash = Converter.trytes(hash); for (var i = 0; i < this.bundle.length; i++) { this.bundle[i].bundle = hash; } var normalizedHash = this.normalizedBundle(hash); if(normalizedHash.indexOf(13 /* = M */) != -1) { // Insecure bundle. Increment Tag and recompute bundle hash. var increasedTag = tritAdd(Converter.trits(this.bundle[0].obsoleteTag), [1]); this.bundle[0].obsoleteTag = Converter.trytes(increasedTag); } else { validBundle = true; } } } /** * Normalizes the bundle hash * **/ Bundle.prototype.normalizedBundle = function(bundleHash) { var normalizedBundle = []; for (var i = 0; i < 3; i++) { var sum = 0; for (var j = 0; j < 27; j++) { sum += (normalizedBundle[i * 27 + j] = Converter.value(Converter.trits(bundleHash.charAt(i * 27 + j)))); } if (sum >= 0) { while (sum-- > 0) { for (var j = 0; j < 27; j++) { if (normalizedBundle[i * 27 + j] > -13) { normalizedBundle[i * 27 + j]--; break; } } } } else { while (sum++ < 0) { for (var j = 0; j < 27; j++) { if (normalizedBundle[i * 27 + j] < 13) { normalizedBundle[i * 27 + j]++; break; } } } } } return normalizedBundle; } module.exports = Bundle;