UNPKG

sensible-sdk

Version:

Sensible-SDK

186 lines (185 loc) 7.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dumpTx = exports.sign = exports.numberToBuffer = exports.P2PKH_UNLOCK_SIZE = exports.PLACE_HOLDER_PUBKEY = exports.PLACE_HOLDER_SIG = exports.CONTRACT_TYPE = exports.getVarPushdataHeader = exports.isNull = exports.getDustThreshold = void 0; const scryptlib_1 = require("scryptlib"); const bsv = require("../bsv"); const TokenUtil = require("./tokenUtil"); function getDustThreshold(lockingScriptSize) { return 1; // return 3 * Math.ceil((250 * (lockingScriptSize + 9 + 148)) / 1000); } exports.getDustThreshold = getDustThreshold; function isNull(val) { if (typeof val == "undefined" || val == null || val == "undefined") { return true; } else { return false; } } exports.isNull = isNull; function getVarPushdataHeader(n) { let header = ""; if (n == 0) { } else if (n == 1) { //不处理这种情况,这里只考虑长脚本 } else if (n < 76) { // Use direct push header = (0, scryptlib_1.toHex)(TokenUtil.getUInt8Buf(n)); } else if (n <= 255) { header = "4c" + (0, scryptlib_1.toHex)(TokenUtil.getUInt8Buf(n)); } else if (n <= 65535) { header = "4d" + (0, scryptlib_1.toHex)(TokenUtil.getUInt16Buf(n)); } else { header = "4e" + (0, scryptlib_1.toHex)(TokenUtil.getUInt32Buf(n)); } return Buffer.from(header, "hex"); } exports.getVarPushdataHeader = getVarPushdataHeader; var CONTRACT_TYPE; (function (CONTRACT_TYPE) { CONTRACT_TYPE[CONTRACT_TYPE["P2PKH"] = 0] = "P2PKH"; CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT"] = 1] = "BCP01_NFT"; CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT_GENESIS"] = 2] = "BCP01_NFT_GENESIS"; CONTRACT_TYPE[CONTRACT_TYPE["BCP01_NFT_UNLOCK_CONTRACT_CHECK"] = 3] = "BCP01_NFT_UNLOCK_CONTRACT_CHECK"; CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN"] = 4] = "BCP02_TOKEN"; CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_GENESIS"] = 5] = "BCP02_TOKEN_GENESIS"; CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_TRANSFER_CHECK"] = 6] = "BCP02_TOKEN_TRANSFER_CHECK"; CONTRACT_TYPE[CONTRACT_TYPE["BCP02_TOKEN_UNLOCK_CONTRACT_CHECK"] = 7] = "BCP02_TOKEN_UNLOCK_CONTRACT_CHECK"; CONTRACT_TYPE[CONTRACT_TYPE["OTHER"] = 8] = "OTHER"; })(CONTRACT_TYPE = exports.CONTRACT_TYPE || (exports.CONTRACT_TYPE = {})); exports.PLACE_HOLDER_SIG = "41682c2074686973206973206120706c61636520686f6c64657220616e642077696c6c206265207265706c6163656420696e207468652066696e616c207369676e61747572652e00"; exports.PLACE_HOLDER_PUBKEY = "41682c2074686973206973206120706c61636520686f6c64657220616e64207769"; exports.P2PKH_UNLOCK_SIZE = 1 + 1 + 72 + 1 + 33; function numberToBuffer(n) { let str = n.toString(16); if (str.length % 2 == 1) { str = "0" + str; } return Buffer.from(str, "hex"); } exports.numberToBuffer = numberToBuffer; function sign(tx, sigHashList, sigList) { sigHashList.forEach(({ inputIndex, contractType, sighashType }, index) => { let input = tx.inputs[inputIndex]; let { publicKey, sig } = sigList[index]; publicKey = new bsv.PublicKey(publicKey); let _sig = bsv.crypto.Signature.fromString(sig); _sig.nhashtype = sighashType; if (contractType == CONTRACT_TYPE.P2PKH) { const signature = new bsv.Transaction.Signature({ publicKey, prevTxId: input.prevTxId, outputIndex: input.outputIndex, inputIndex: inputIndex, signature: _sig, sigtype: sighashType, }); input.setScript(bsv.Script.buildPublicKeyHashIn(signature.publicKey, signature.signature.toDER(), signature.sigtype)); } else { let _sig2 = _sig.toTxFormat(); let oldSigHex = Buffer.concat([ numberToBuffer(exports.PLACE_HOLDER_SIG.length / 2), Buffer.from(exports.PLACE_HOLDER_SIG, "hex"), ]).toString("hex"); let newSigHex = Buffer.concat([ numberToBuffer(_sig2.length), _sig2, ]).toString("hex"); let oldPubKeyHex = Buffer.concat([ numberToBuffer(exports.PLACE_HOLDER_PUBKEY.length / 2), Buffer.from(exports.PLACE_HOLDER_PUBKEY, "hex"), ]).toString("hex"); const pubkeyBuffer = publicKey.toBuffer(); let newPubKeyHex = Buffer.concat([ numberToBuffer(pubkeyBuffer.length), pubkeyBuffer, ]).toString("hex"); input.setScript(new bsv.Script(input.script .toHex() .replace(oldSigHex, newSigHex) .replace(oldPubKeyHex, newPubKeyHex))); } }); } exports.sign = sign; function satoshisToBSV(satoshis) { return (satoshis / 100000000).toFixed(8); } function dumpTx(tx, network = "mainnet") { const version = tx.version; const size = tx.toBuffer().length; const inputAmount = tx.inputs.reduce((pre, cur) => cur.output.satoshis + pre, 0); const outputAmount = tx.outputs.reduce((pre, cur) => cur.satoshis + pre, 0); let feePaid = inputAmount - outputAmount; const feeRate = (feePaid / size).toFixed(4); console.log(` ============================================================================================= Summary txid: ${tx.id} Size: ${size} Fee Paid: ${satoshisToBSV(feePaid)} Fee Rate: ${feeRate} sat/B Detail: ${tx.inputs.length} Inputs, ${tx.outputs.length} Outputs ---------------------------------------------------------------------------------------------- ${tx.inputs .map((input, index) => { let type = ""; if (input.output.script.isPublicKeyHashOut()) { type = "standard"; } else if (input.output.script.isSafeDataOut()) { type = "OP_RETURN"; } else { type = "nonstandard"; } let str = ` =>${index} ${type == "standard" ? input.output.script.toAddress(network).toString() : type == "OP_RETURN" ? "OP_RETURN" + " ".repeat(34 - 9) : "nonstandard" + " ".repeat(34 - 11)} ${satoshisToBSV(input.output.satoshis)} BSV lock-size: ${input.output.script.toBuffer().length} unlock-size: ${input.script.toBuffer().length} via ${input.prevTxId.toString("hex")} [${input.outputIndex}] `; return str; }) .join("")} Input total: ${satoshisToBSV(tx.inputs.reduce((pre, cur) => pre + cur.output.satoshis, 0))} BSV ---------------------------------------------------------------------------------------------- ${tx.outputs .map((output, index) => { let type = ""; if (output.script.isPublicKeyHashOut()) { type = "standard"; } else if (output.script.isSafeDataOut()) { type = "OP_RETURN"; } else { type = "nonstandard"; } let str = ` =>${index} ${type == "standard" ? output.script.toAddress(network).toString() : type == "OP_RETURN" ? "OP_RETURN" + " ".repeat(34 - 9) : "nonstandard" + " ".repeat(34 - 11)} ${satoshisToBSV(output.satoshis)} BSV size: ${output.script.toBuffer().length} `; return str; }) .join("")} Output total: ${satoshisToBSV(tx.outputs.reduce((pre, cur) => pre + cur.satoshis, 0))} BSV ============================================================================================= `); } exports.dumpTx = dumpTx;