UNPKG

parkingsv-contract

Version:

ParkingSV library

243 lines 7.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.num2bin = exports.getPreimage = exports.toHex = exports.signTx = exports.getValidatedHexString = exports.hexStringToBytes = exports.bytesToHexString = exports.bytes2Literal = exports.literal2Asm = exports.int2Asm = exports.bool2Asm = exports.DEFAULT_SIGHASH_TYPE = exports.DEFAULT_FLAGS = exports.bsv = void 0; var bsv = require("bsv"); exports.bsv = bsv; var BN = bsv.crypto.BN; var Interpreter = bsv.Script.Interpreter; exports.DEFAULT_FLAGS = // @ts-ignore Interpreter.SCRIPT_VERIFY_MINIMALDATA | // @ts-ignore Interpreter.SCRIPT_ENABLE_SIGHASH_FORKID | // @ts-ignore Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES | // @ts-ignore Interpreter.SCRIPT_ENABLE_MONOLITH_OPCODES; // @ts-ignore exports.DEFAULT_SIGHASH_TYPE = // @ts-ignore bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID; function bool2Asm(str) { if (str === 'true') { return 'OP_TRUE'; } if (str === 'false') { return 'OP_FALSE'; } throw new Error("invalid str '" + str + "' to convert to bool"); } exports.bool2Asm = bool2Asm; /** * decimal int to little-endian signed magnitude */ function int2Asm(str) { if (!/^-?(0x)?\d+$/.test(str)) { throw new Error("invalid str '" + str + "' to convert to int"); } // @ts-ignore var number = new BN(str, 10); // @ts-ignore if (number.eqn(-1)) { return 'OP_1NEGATE'; } // @ts-ignore if (number.gten(0) && number.lten(16)) { return 'OP_' + str; } // @ts-ignore var m = number.toSM({ endian: 'little' }); return m.toString('hex'); } exports.int2Asm = int2Asm; /** * convert literals to script ASM format */ function literal2Asm(l) { // bool if (l === 'false') { return ['OP_FALSE', 'bool']; } if (l === 'true') { return ['OP_TRUE', 'bool']; } // hex int if (/^0x[0-9a-fA-F]+$/.test(l)) { return [int2Asm(l), 'int']; } // decimal int if (/^-?\d+$/.test(l)) { return [int2Asm(l), 'int']; } // bytes var m = /^b'([\da-fA-F]+)'$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'bytes']; } // PrivKey // 1) decimal int m = /^PrivKey\((-?\d+)\)$/.exec(l); if (m) { return [m[1], 'PrivKey']; } // 2) hex int m = /^PrivKey\((0x[0-9a-fA-F]+)\)$/.exec(l); if (m) { return [m[1], 'PrivKey']; } // PubKey m = /^PubKey\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'PubKey']; } // Sig m = /^Sig\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'Sig']; } // Ripemd160 m = /^Ripemd160\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'Ripemd160']; } // Sha1 m = /^Sha1\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'Sha1']; } // Sha256 m = /^Sha256\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'Sha256']; } // SigHashType m = /^SigHashType\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'SigHashType']; } // OpCodeType m = /^OpCodeType\(b'([\da-fA-F]+)'\)$/.exec(l); if (m) { return [getValidatedHexString(m[1]), 'OpCodeType']; } throw new Error("<" + l + "> can't be casted to asm format, only support sCrypt native types"); } exports.literal2Asm = literal2Asm; function bytes2Literal(bytearray, type) { switch (type) { case 'bool': // @ts-ignore return BN.fromBuffer(bytearray, { endian: 'little' }) > 0 ? 'true' : 'false'; case 'int': // @ts-ignore return BN.fromSM(bytearray, { endian: 'little' }).toString(); case 'bytes': return "b'" + bytesToHexString(bytearray) + "'"; default: return "b'" + bytesToHexString(bytearray) + "'"; } } exports.bytes2Literal = bytes2Literal; function bytesToHexString(bytearray) { return bytearray.reduce(function (o, c) { return o += ('0' + (c & 0xFF).toString(16)).slice(-2); }, ''); } exports.bytesToHexString = bytesToHexString; function hexStringToBytes(hex) { getValidatedHexString(hex); return hex.split('') .reduce(function (o, c, i) { if (i % 2 === 0) { o.push(c); } else { o[o.length - 1] += c; } return o; }, new Array()) .map(function (b) { return parseInt(b, 16); }); } exports.hexStringToBytes = hexStringToBytes; function getValidatedHexString(hex, allowEmpty) { if (allowEmpty === void 0) { allowEmpty = true; } var ret = hex.trim(); if (ret.length < 1 && !allowEmpty) { throw new Error("can't be empty string"); } if (ret.length % 2) { throw new Error('should have even length'); } if (ret.length > 0 && !(/^[\da-f]+$/i.test(ret))) { throw new Error('should only contain [0-9] or characters [a-fA-F]'); } return ret; } exports.getValidatedHexString = getValidatedHexString; function signTx(tx, privateKey, lockingScriptASM, inputAmount, inputIndex, sighashType, flags) { if (inputIndex === void 0) { inputIndex = 0; } if (sighashType === void 0) { sighashType = exports.DEFAULT_SIGHASH_TYPE; } if (flags === void 0) { flags = exports.DEFAULT_FLAGS; } if (!tx) { throw new Error('param tx can not be empty'); } if (!privateKey) { throw new Error('param privateKey can not be empty'); } if (!lockingScriptASM) { throw new Error('param lockingScriptASM can not be empty'); } if (!inputAmount) { throw new Error('param inputAmount can not be empty'); } // @ts-ignore return bsv.Transaction.sighash.sign(tx, privateKey, sighashType, inputIndex, // @ts-ignore bsv.Script.fromASM(lockingScriptASM), new bsv.crypto.BN(inputAmount), flags).toTxFormat(); } exports.signTx = signTx; function toHex(x) { return x.toString('hex'); } exports.toHex = toHex; function getPreimage(tx, inputLockingScriptASM, inputAmount, inputIndex, sighashType, flags) { if (inputIndex === void 0) { inputIndex = 0; } if (sighashType === void 0) { sighashType = exports.DEFAULT_SIGHASH_TYPE; } if (flags === void 0) { flags = exports.DEFAULT_FLAGS; } // @ts-ignore return bsv.Transaction.sighash.sighashPreimage(tx, sighashType, inputIndex, bsv.Script.fromASM(inputLockingScriptASM), new bsv.crypto.BN(inputAmount), flags); } exports.getPreimage = getPreimage; // 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 // TODO: handle bigint function num2bin(n, dataLen) { if (n === 0) { return "00".repeat(dataLen); } // @ts-ignore var num = BN.fromNumber(n); var s = num.toSM({ endian: 'little' }).toString('hex'); var byteLen_ = s.length / 2; if (byteLen_ > dataLen) { throw new Error(n + " cannot fit in " + dataLen + " byte[s]"); } if (byteLen_ === dataLen) { return s; } var paddingLen = dataLen - byteLen_; var lastByte = s.substring(s.length - 2); var rest = s.substring(0, s.length - 2); var m = parseInt(lastByte, 16); if (n < 0) { // reset sign bit m &= 0x7F; } var mHex = m.toString(16); if (mHex.length < 2) { mHex = '0' + mHex; } var padding = n > 0 ? '00'.repeat(paddingLen) : '00'.repeat(paddingLen - 1) + '80'; return rest + mHex + padding; } exports.num2bin = num2bin; //# sourceMappingURL=utils.js.map