sensible-sdk
Version:
Sensible-SDK
186 lines (185 loc) • 7.63 kB
JavaScript
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;
;