UNPKG

scryptlib

Version:

Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.

176 lines 5.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hash256 = exports.sha256 = exports.hash160 = exports.buildPublicKeyHashScript = exports.buildOpreturnScript = exports.writeVarint = exports.toLEUnsigned = exports.len = exports.invert = exports.xor = exports.or = exports.and = exports.bin2num = exports.num2bin = exports.unpack = exports.pack = void 0; const _1 = require("."); /** * bigint can be converted to string with pack * @category Bytes Operations */ function pack(n) { const num = new _1.bsv.crypto.BN(n); return num.toSM({ endian: 'little' }).toString('hex'); } exports.pack = pack; /** * ByteString can be converted to bigint using function unpack. * @category Bytes Operations */ function unpack(a) { return BigInt(bin2num(a)); } exports.unpack = unpack; // Converts a number into a sign-magnitude representation of certain size as a string // Throws if the number cannot be accommodated // Often used to append numbers to OP_RETURN, which are read in contracts // Support Bigint function num2bin(n, dataLen) { const num = new _1.bsv.crypto.BN(n); if (num.eqn(0)) { return '00'.repeat(dataLen); } const s = num.toSM({ endian: 'little' }).toString('hex'); const byteLen_ = s.length / 2; if (byteLen_ > dataLen) { throw new Error(`${n} cannot fit in ${dataLen} byte[s]`); } if (byteLen_ === dataLen) { return s; } const paddingLen = dataLen - byteLen_; const lastByte = s.substring(s.length - 2); const rest = s.substring(0, s.length - 2); let m = parseInt(lastByte, 16); if (num.isNeg()) { // reset sign bit m &= 0x7F; } let mHex = m.toString(16); if (mHex.length < 2) { mHex = '0' + mHex; } const padding = n > 0 ? '00'.repeat(paddingLen) : '00'.repeat(paddingLen - 1) + '80'; return rest + mHex + padding; } exports.num2bin = num2bin; //Support Bigint function bin2num(hex) { const lastByte = hex.substring(hex.length - 2); const rest = hex.substring(0, hex.length - 2); const m = parseInt(lastByte, 16); const n = m & 0x7F; let nHex = n.toString(16); if (nHex.length < 2) { nHex = '0' + nHex; } //Support negative number let bn = _1.bsv.crypto.BN.fromHex(rest + nHex, { endian: 'little' }); if (m >> 7) { bn = bn.neg(); } return BigInt(bn.toString()); } exports.bin2num = bin2num; function and(a, b) { const size1 = pack(a).length / 2; const size2 = pack(b).length / 2; const maxSize = Math.max(size1, size2); const ba = Buffer.from(num2bin(a, maxSize), 'hex'); const bb = Buffer.from(num2bin(b, maxSize), 'hex'); for (let i = 0; i < ba.length; i++) { ba[i] &= bb[i]; } return bin2num(ba.toString('hex')); } exports.and = and; function or(a, b) { const size1 = pack(a).length / 2; const size2 = pack(b).length / 2; const maxSize = Math.max(size1, size2); const ba = Buffer.from(num2bin(a, maxSize), 'hex'); const bb = Buffer.from(num2bin(b, maxSize), 'hex'); for (let i = 0; i < ba.length; i++) { ba[i] |= bb[i]; } return bin2num(ba.toString('hex')); } exports.or = or; function xor(a, b) { const size1 = pack(a).length / 2; const size2 = pack(b).length / 2; const maxSize = Math.max(size1, size2); const ba = Buffer.from(num2bin(a, maxSize), 'hex'); const bb = Buffer.from(num2bin(b, maxSize), 'hex'); for (let i = 0; i < ba.length; i++) { ba[i] ^= bb[i]; } return bin2num(ba.toString('hex')); } exports.xor = xor; function invert(a) { if (a === (0, _1.Int)(0)) { return a; } const size = pack(a).length / 2; const buffer = Buffer.from(num2bin(a, size), 'hex'); for (let i = 0; i < buffer.length; i++) { buffer[i] = ~buffer[i]; } return bin2num(buffer.toString('hex')); } exports.invert = invert; // Equivalent to the built-in function `len` in scrypt function len(hexstr) { return BigInt(hexstr.length / 2); } exports.len = len; // convert signed integer `n` to unsigned integer of `l` bytes, in little endian function toLEUnsigned(n, l) { // one extra byte to accommodate possible negative sign byte const m = num2bin(n, l + 1); // remove sign byte return m.slice(0, Number(len(m) - (0, _1.Int)(1))); } exports.toLEUnsigned = toLEUnsigned; // convert 'b' to a VarInt field, including the preceding length function writeVarint(b) { const n = len(b); let header = ''; if (n < 0xfd) { header = toLEUnsigned(n, 1); } else if (n < 0x10000) { header = 'fd' + toLEUnsigned(n, 2); } else if (n < 0x100000000) { header = 'fe' + toLEUnsigned(n, 4); } else if (n < 0x10000000000000000) { header = 'ff' + toLEUnsigned(n, 8); } return header + b; } exports.writeVarint = writeVarint; function buildOpreturnScript(data) { return _1.bsv.Script.fromASM(['OP_FALSE', 'OP_RETURN', data].join(' ')); } exports.buildOpreturnScript = buildOpreturnScript; function buildPublicKeyHashScript(pubKeyHash) { return _1.bsv.Script.fromASM(['OP_DUP', 'OP_HASH160', pubKeyHash, 'OP_EQUALVERIFY', 'OP_CHECKSIG'].join(' ')); } exports.buildPublicKeyHashScript = buildPublicKeyHashScript; // Equivalent to the built-in function `hash160` in scrypt function hash160(hexstr, encoding) { return _1.bsv.crypto.Hash.sha256ripemd160(Buffer.from(hexstr, encoding || 'hex')).toString('hex'); } exports.hash160 = hash160; // Equivalent to the built-in function `sha256` in scrypt function sha256(hexstr, encoding) { return _1.bsv.crypto.Hash.sha256(Buffer.from(hexstr, encoding || 'hex')).toString('hex'); } exports.sha256 = sha256; // Equivalent to the built-in function `hash256` in scrypt function hash256(hexstr, encoding) { return sha256(sha256(hexstr, encoding), encoding); } exports.hash256 = hash256; //# sourceMappingURL=builtins.js.map