UNPKG

neo-convertor

Version:

A tool to convert neo smart contract data to human-readable one

539 lines (538 loc) 19.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const uint_1 = require("../uint"); const libs_1 = require("../libs"); class BigInteger { constructor(value) { this.fromString = (str, radix) => { if (radix === undefined) { radix = 10; } if (radix < 2 || radix > 36) { throw new RangeError(); } if (str.length === 0) { this._sign = 0; this._bits = []; return; } let bits_radix = [radix]; let bits_a = [0]; let first = str.charCodeAt(0); let withSign = first === 0x2b || first === 0x2d; this._sign = first === 0x2d ? -1 : +1; this._bits = []; for (let i = withSign ? 1 : 0; i < str.length; i++) { bits_a[0] = str.charCodeAt(i); if (bits_a[0] >= 0x30 && bits_a[0] <= 0x39) bits_a[0] -= 0x30; else if (bits_a[0] >= 0x41 && bits_a[0] <= 0x5a) bits_a[0] -= 0x37; else if (bits_a[0] >= 0x61 && bits_a[0] <= 0x7a) bits_a[0] -= 0x57; else throw new RangeError(); let bits_temp = new Array(); BigInteger.multiplyTo(this._bits, bits_radix, bits_temp); BigInteger.addTo(bits_temp, bits_a, this._bits); } this.clamp(); }; this.fromUint8Array = (arr, sign, littleEndian) => { if (sign === undefined) { sign = 1; } if (littleEndian === undefined) { littleEndian = true; } if (!littleEndian) { let arr_new = new Uint8Array(arr.length); for (let i = 0; i < arr.length; i++) arr_new[arr.length - 1 - i] = arr[i]; arr = arr_new; } let actual_length = BigInteger.getActualLength(arr); let bits = actual_length * 8; let units = Math.ceil(bits / BigInteger.DB); this._bits = []; for (let i = 0; i < units; i++) { let cb = i * BigInteger.DB; let cu = Math.floor(cb / 8); cb %= 8; this._bits[i] = ((arr[cu] | arr[cu + 1] << 8 | arr[cu + 2] << 16 | arr[cu + 3] << 24) >>> cb) & BigInteger.DM; } this._sign = sign < 0 ? -1 : +1; this.clamp(); }; this.fromUint64 = (i, sign) => { while (i.bits[0] != 0 || i.bits[1] != 0) { this._bits.push(i.toUint32() & BigInteger.DM); i = i.rightShift(BigInteger.DB); } this._sign = sign; this.clamp(); }; this.isZero = () => { return this._sign === 0; }; this.multiply = (other) => { return BigInteger.multiply(this, other); }; this.negate = () => { return BigInteger.create(-this._sign, this._bits); }; this.pow = (exponent) => { return BigInteger.pow(this, exponent); }; this.subtract = (other) => { return BigInteger.subtract(this, other); }; this.toInt32 = () => { if (this._sign == 0) return 0; if (this._bits.length == 1) return this._bits[0] * this._sign; return ((this._bits[0] | this._bits[1] * BigInteger.DV) & 0x7fffffff) * this._sign; }; this.toString = (radix) => { if (radix === undefined) { radix = 10; } if (this._sign == 0) return "0"; if (radix < 2 || radix > 36) throw new RangeError(); let s = ""; for (let bi = this; bi._sign != 0;) { let r = BigInteger.divRem(bi, radix); let rem = Math.abs(r.remainder.toInt32()); if (rem < 10) rem += 0x30; else rem += 0x57; s = String.fromCharCode(rem) + s; bi = r.result; } if (this._sign < 0) s = "-" + s; return s; }; this.toUint8Array = (littleEndian, length) => { if (littleEndian === void 0) { littleEndian = true; } if (this._sign == 0) return new Uint8Array(length || 1); var cb = Math.ceil(this._bits.length * BigInteger.DB / 8); var array = new Uint8Array(length || cb); for (var i = 0; i < array.length; i++) { var offset = littleEndian ? i : array.length - 1 - i; var cbits = i * 8; var cu = Math.floor(cbits / BigInteger.DB); cbits %= BigInteger.DB; if (BigInteger.DB - cbits < 8) array[offset] = (this._bits[cu] >>> cbits | this._bits[cu + 1] << (BigInteger.DB - cbits)) & 0xff; else array[offset] = this._bits[cu] >>> cbits & 0xff; } length = length || BigInteger.getActualLength(array); if (length < array.length) array = array.subarray(0, length); return array; }; this.add = (other) => { return BigInteger.add(this, other); }; this.bitLength = () => { let l = this._bits.length; if (l === 0) { return 0; } return --l * BigInteger.DB + BigInteger.bitLengthInternal(this._bits[l]); }; this.compareTo = (other) => { return BigInteger.compare(this, other); }; this.clamp = () => { var l = this._bits.length; while (l > 0 && (this._bits[--l] | 0) === 0) this._bits.pop(); while (l > 0) this._bits[--l] |= 0; if (this._bits.length == 0) this._sign = 0; }; this._sign = 0; this._bits = new Array(); if (typeof value === "number") { if (!isFinite(value) || isNaN(value)) { throw new RangeError(); } var parts = BigInteger.getDoubleParts(value); if (parts.man.equals(uint_1.Uint64.Zero) || parts.exp <= -64) { return; } if (parts.exp <= 0) { this.fromUint64(parts.man.rightShift(-parts.exp), parts.sign); } else if (parts.exp <= 11) { this.fromUint64(parts.man.leftShift(parts.exp), parts.sign); } else { parts.man = parts.man.leftShift(11); parts.exp -= 11; let units = Math.ceil((parts.exp + 64) / BigInteger.DB); let cu = Math.ceil(parts.exp / BigInteger.DB); let cbit = cu * BigInteger.DB - parts.exp; for (let i = cu; i < units; i++) { this._bits[i] = parts.man.rightShift(cbit + (i - cu) * BigInteger.DB).toUint32() & BigInteger.DM; } if (cbit > 0) { this._bits[cu - 1] = (parts.man.toUint32() << (BigInteger.DB - cbit)) & BigInteger.DM; } this._sign = parts.sign; this.clamp(); } } else if (typeof value === "string") { this.fromString(value); } else if (value instanceof ArrayBuffer) { this.fromUint8Array(new Uint8Array(value)); } else if (value instanceof Uint8Array) { this.fromUint8Array(value); } } } BigInteger.DB = 26; BigInteger.DM = (1 << BigInteger.DB) - 1; BigInteger.DV = BigInteger.DM + 1; BigInteger.getDoubleParts = (dbl) => { let uu = new Uint32Array(2); new Float64Array(uu.buffer)[0] = dbl; let result = { sign: 1 - ((uu[1] >>> 30) & 2), man: new uint_1.Uint64(uu[0], uu[1] & 0x000FFFFF), exp: (uu[1] >>> 20) & 0x7FF, fFinite: true }; if (result.exp === 0) { if (!result.man.equals(uint_1.Uint64.Zero)) { result.exp = -1074; } } else if (result.exp === 0x7FF) { result.fFinite = false; } else { result.man = result.man.or(new uint_1.Uint64(0, 0x00100000)); result.exp -= 1075; } return result; }; BigInteger.MinusOne = new BigInteger(-1); BigInteger.One = new BigInteger(1); BigInteger.Zero = new BigInteger(0); BigInteger.fromString = (str, radix) => { if (radix === void 0) { radix = 10; } let bi = new BigInteger(0); bi.fromString(str, radix); return bi; }; BigInteger.fromUint8Array = (arr, sign, littleEndian) => { if (sign === undefined) { sign = 1; } if (littleEndian === undefined) { littleEndian = true; } let bi = new BigInteger(0); bi.fromUint8Array(arr, sign, littleEndian); return bi; }; BigInteger.getActualLength = (arr) => { let actual_length = arr.length; for (let i = arr.length - 1; i >= 0; i--) if (arr[i] != 0) { actual_length = i + 1; break; } return actual_length; }; BigInteger.mod = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_x._sign == 0) return bi_x; if (bi_y._sign == 0) return bi_y; if (bi_x._sign == 1 && bi_x._bits == null) return bi_y; if (bi_x._sign == -1 && bi_x._bits == null) return bi_y.negate(); if (bi_y._sign == 1 && bi_y._bits == null) return bi_x; if (bi_y._sign == -1 && bi_y._bits == null) return bi_x.negate(); let bits_r = new Array(); BigInteger.multiplyTo(bi_x._bits, bi_y._bits, bits_r); return BigInteger.create((bi_x._sign > 0) == (bi_y._sign > 0) ? +1 : -1, bits_r); }; BigInteger.multiply = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_x._sign == 0) return bi_x; if (bi_y._sign == 0) return bi_y; if (bi_x._sign == 1 && bi_x._bits == null) return bi_y; if (bi_x._sign == -1 && bi_x._bits == null) return bi_y.negate(); if (bi_y._sign == 1 && bi_y._bits == null) return bi_x; if (bi_y._sign == -1 && bi_y._bits == null) return bi_x.negate(); let bits_r = new Array(); BigInteger.multiplyTo(bi_x._bits, bi_y._bits, bits_r); return BigInteger.create((bi_x._sign > 0) == (bi_y._sign > 0) ? +1 : -1, bits_r); }; BigInteger.multiplyTo = (x, y, r, offset) => { if (offset === undefined) { offset = 0; } if (r === undefined) { r = new Array(); } if (x.length > y.length) { let t = x; x = y; y = t; } for (let i = x.length + y.length - 2; i >= 0; i--) { r[i + offset] = 0; } for (let i = 0; i < x.length; i++) { if (x[i] === 0) { continue; } for (let j = 0; j < y.length; j++) { let c = x[i] * y[j]; if (c === 0) { continue; } let k = i + j; do { c += r[k + offset] || 0; r[k + offset] = c & BigInteger.DM; c = Math.floor(c / BigInteger.DV); k++; } while (c > 0); } } }; BigInteger.parse = (str) => { return BigInteger.fromString(str); }; BigInteger.pow = (value, exponent) => { let bi_v = typeof value === "number" ? new BigInteger(value) : value; if (exponent < 0 || exponent > 0x7fffffff) throw new RangeError(); if (exponent == 0) return BigInteger.One; if (exponent == 1) return bi_v; if (bi_v._sign == 0) return bi_v; if (bi_v._bits.length == 1) { if (bi_v._bits[0] == 1) return bi_v; if (bi_v._bits[0] == -1) return (exponent & 1) != 0 ? bi_v : BigInteger.One; } let h = BigInteger.bitLengthInternal(exponent); let bi_new = BigInteger.One; for (let i = 0; i < h; i++) { let e = 1 << i; if (e > 1) bi_v = BigInteger.multiply(bi_v, bi_v); if ((exponent & e) != 0) bi_new = BigInteger.multiply(bi_v, bi_new); } return bi_new; }; BigInteger.subtract = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_x._sign == 0) return bi_y.negate(); if (bi_y._sign == 0) return bi_x; if ((bi_x._sign > 0) != (bi_y._sign > 0)) return BigInteger.add(bi_x, bi_y.negate()); let c = BigInteger.compareAbs(bi_x, bi_y); if (c == 0) return BigInteger.Zero; if (c < 0) return BigInteger.subtract(bi_y, bi_x).negate(); let bits_r = new Array(); BigInteger.subtractTo(bi_x._bits, bi_y._bits, bits_r); return BigInteger.create(bi_x._sign, bits_r, true); }; BigInteger.subtractTo = (x, y, r) => { if (r == null) r = []; var l = Math.min(x.length, y.length); var c = 0, i = 0; while (i < l) { c += x[i] - y[i]; r[i++] = c & BigInteger.DM; c >>= BigInteger.DB; } if (x.length < y.length) while (i < y.length) { c -= y[i]; r[i++] = c & BigInteger.DM; c >>= BigInteger.DB; } else while (i < x.length) { c += x[i]; r[i++] = c & BigInteger.DM; c >>= BigInteger.DB; } return c < 0; }; BigInteger.add = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_x._sign == 0) return bi_y; if (bi_y._sign == 0) return bi_x; if ((bi_x._sign > 0) != (bi_y._sign > 0)) return BigInteger.subtract(bi_x, bi_y.negate()); let bits_r = new Array(); BigInteger.addTo(bi_x._bits, bi_y._bits, bits_r); return BigInteger.create(bi_x._sign, bits_r); }; BigInteger.addTo = (x, y, r) => { if (x.length < y.length) { let t = x; x = y; y = t; } let c = 0, i = 0; while (i < y.length) { c += x[i] + y[i]; r[i++] = c & BigInteger.DM; c >>>= BigInteger.DB; } while (i < x.length) { c += x[i]; r[i++] = c & BigInteger.DM; c >>>= BigInteger.DB; } if (c > 0) r[i] = c; }; BigInteger.bitLengthInternal = (w) => { return (w < 1 << 15 ? (w < 1 << 7 ? (w < 1 << 3 ? (w < 1 << 1 ? (w < 1 << 0 ? (w < 0 ? 32 : 0) : 1) : (w < 1 << 2 ? 2 : 3)) : (w < 1 << 5 ? (w < 1 << 4 ? 4 : 5) : (w < 1 << 6 ? 6 : 7))) : (w < 1 << 11 ? (w < 1 << 9 ? (w < 1 << 8 ? 8 : 9) : (w < 1 << 10 ? 10 : 11)) : (w < 1 << 13 ? (w < 1 << 12 ? 12 : 13) : (w < 1 << 14 ? 14 : 15)))) : (w < 1 << 23 ? (w < 1 << 19 ? (w < 1 << 17 ? (w < 1 << 16 ? 16 : 17) : (w < 1 << 18 ? 18 : 19)) : (w < 1 << 21 ? (w < 1 << 20 ? 20 : 21) : (w < 1 << 22 ? 22 : 23))) : (w < 1 << 27 ? (w < 1 << 25 ? (w < 1 << 24 ? 24 : 25) : (w < 1 << 26 ? 26 : 27)) : (w < 1 << 29 ? (w < 1 << 28 ? 28 : 29) : (w < 1 << 30 ? 30 : 31))))); }; BigInteger.compare = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_x._sign >= 0 && bi_y._sign < 0) return +1; if (bi_x._sign < 0 && bi_y._sign >= 0) return -1; let c = BigInteger.compareAbs(bi_x, bi_y); return bi_x._sign < 0 ? -c : c; }; BigInteger.compareAbs = (x, y) => { if (x._bits.length > y._bits.length) return +1; if (x._bits.length < y._bits.length) return -1; for (let i = x._bits.length - 1; i >= 0; i--) if (x._bits[i] > y._bits[i]) return +1; else if (x._bits[i] < y._bits[i]) return -1; return 0; }; BigInteger.create = (sign, bits, clamp) => { if (clamp === undefined) { clamp = false; } let bi = new BigInteger(1); bi._sign = sign; bi._bits = bits; if (clamp) bi.clamp(); return bi; }; BigInteger.divRem = (x, y) => { let bi_x = typeof x === "number" ? new BigInteger(x) : x; let bi_y = typeof y === "number" ? new BigInteger(y) : y; if (bi_y._sign == 0) throw new RangeError(); if (bi_x._sign == 0) return { result: BigInteger.Zero, remainder: BigInteger.Zero }; if (bi_y._sign == 1 && bi_y._bits == null) return { result: bi_x, remainder: BigInteger.Zero }; if (bi_y._sign == -1 && bi_y._bits == null) return { result: bi_x.negate(), remainder: BigInteger.Zero }; let sign_result = (bi_x._sign > 0) == (bi_y._sign > 0) ? +1 : -1; let c = BigInteger.compareAbs(bi_x, bi_y); if (c == 0) return { result: sign_result > 0 ? BigInteger.One : BigInteger.MinusOne, remainder: BigInteger.Zero }; if (c < 0) return { result: BigInteger.Zero, remainder: bi_x }; let bits_result = new Array(); let bits_rem = new Array(); libs_1.copyArray(bi_x._bits, 0, bits_rem, 0, bi_x._bits.length); let df = bi_y._bits[bi_y._bits.length - 1]; for (let i = bi_x._bits.length - 1; i >= bi_y._bits.length - 1; i--) { let offset = i - bi_y._bits.length + 1; let d = bits_rem[i] + (bits_rem[i + 1] || 0) * BigInteger.DV; let max = Math.floor(d / df); if (max > BigInteger.DM) max = BigInteger.DM; let min = 0; while (min != max) { let bits_sub_1 = new Array(offset + bi_y._bits.length); for (let i_1 = 0; i_1 < offset; i_1++) bits_sub_1[i_1] = 0; bits_result[offset] = Math.ceil((min + max) / 2); BigInteger.multiplyTo(bi_y._bits, [bits_result[offset]], bits_sub_1, offset); if (BigInteger.subtractTo(bits_rem, bits_sub_1)) max = bits_result[offset] - 1; else min = bits_result[offset]; } let bits_sub = new Array(offset + bi_y._bits.length); for (let i_2 = 0; i_2 < offset; i_2++) bits_sub[i_2] = 0; bits_result[offset] = min; BigInteger.multiplyTo(bi_y._bits, [bits_result[offset]], bits_sub, offset); BigInteger.subtractTo(bits_rem, bits_sub, bits_rem); } return { result: BigInteger.create(sign_result, bits_result, true), remainder: BigInteger.create(bi_x._sign, bits_rem, true) }; }; exports.BigInteger = BigInteger;