scryptlib
Version:
Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.
176 lines • 5.94 kB
JavaScript
;
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