@okxweb3/coin-bitcoin
Version:
@okxweb3/coin-bitcoin is a Bitcoin SDK for building Web3 wallets and applications. It supports BTC, BSV, DOGE, LTC, and TBTC, enabling private key management, transaction signing, address generation, and inscriptions like BRC-20, Runes, CAT, and Atomicals
176 lines • 6.36 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.countAdjustedVsize = exports.convertScriptSigAsm = exports.countScriptSigops = void 0;
const ops_1 = require("./bitcoinjs-lib/ops");
const txBuild_1 = require("./txBuild");
const coin_base_1 = require("@okxweb3/coin-base");
const bitcoin = __importStar(require("./bitcoinjs-lib"));
function countScriptSigops(script, isRawScript = false, witness = false) {
if (!script?.length) {
return 0;
}
let sigops = 0;
sigops += (script.match(/OP_CHECKSIG/g)?.length || 0);
if (isRawScript) {
sigops += 20 * (script.match(/OP_CHECKMULTISIG/g)?.length || 0);
}
else {
const matches = script.matchAll(/(?:OP_(?:PUSHNUM_)?(\d+))? OP_CHECKMULTISIG/g);
for (const match of matches) {
const n = parseInt(match[1]);
if (Number.isInteger(n)) {
sigops += n;
}
else {
sigops += 20;
}
}
}
return witness ? sigops : (sigops * 4);
}
exports.countScriptSigops = countScriptSigops;
function convertScriptSigAsm(buf) {
if (buf?.length == 0) {
return "";
}
const b = [];
let i = 0;
while (i < buf.length) {
const op = buf[i];
if (op >= 0x01 && op <= 0x4e) {
i++;
let push;
if (op === 0x4c) {
push = buf.readUInt8(i);
b.push('OP_PUSHDATA1');
i += 1;
}
else if (op === 0x4d) {
push = buf.readUInt16LE(i);
b.push('OP_PUSHDATA2');
i += 2;
}
else if (op === 0x4e) {
push = buf.readUInt32LE(i);
b.push('OP_PUSHDATA4');
i += 4;
}
else {
push = op;
b.push('OP_PUSHBYTES_' + push);
}
const data = buf.slice(i, i + push);
if (data.length !== push) {
break;
}
b.push(data.toString('hex'));
i += data.length;
}
else {
if (op === 0x00) {
b.push('OP_0');
}
else if (op === 0x4f) {
b.push('OP_PUSHNUM_NEG1');
}
else if (op === 0xb1) {
b.push('OP_CLTV');
}
else if (op === 0xb2) {
b.push('OP_CSV');
}
else if (op === 0xba) {
b.push('OP_CHECKSIGADD');
}
else {
const opcode = ops_1.REVERSE_OPS[op];
if (opcode && op < 0xfd) {
if (/^OP_(\d+)$/.test(opcode)) {
b.push(opcode.replace(/^OP_(\d+)$/, 'OP_PUSHNUM_$1'));
}
else {
b.push(opcode);
}
}
else {
b.push('OP_RETURN_' + op);
}
}
i += 1;
}
}
return b.join(' ');
}
exports.convertScriptSigAsm = convertScriptSigAsm;
function countAdjustedVsize(transaction, addresses, net) {
if (transaction == undefined || null) {
return 0;
}
if (net == undefined || null) {
net = bitcoin.networks.bitcoin;
}
let sigops = 0;
if ((addresses != undefined || null) && (addresses.length == transaction.ins.length)) {
transaction.ins.forEach((input, index) => {
if (input.script != undefined || null) {
sigops += countScriptSigops(convertScriptSigAsm(input.script), true);
}
if (addresses.length <= index || (addresses[index] == undefined || null) || addresses[index] == '') {
return;
}
const addressType = (0, txBuild_1.getAddressType)(addresses[index], net);
switch (true) {
case addressType === 'segwit_nested' && input.witness?.length === 2 && input.script && coin_base_1.base.toHex(input.script).startsWith('160014'):
case addressType === 'segwit_native':
sigops += 1;
break;
case addressType === 'segwit_nested' && input.witness?.length && input.script && coin_base_1.base.toHex(input.script).startsWith('220020'):
case addressType === 'segwit_native':
if (input.witness?.length) {
sigops += countScriptSigops(convertScriptSigAsm(input.witness[input.witness.length - 1]), false, true);
}
break;
case addressType === 'segwit_nested':
if (input.script) {
sigops += countScriptSigops(convertScriptSigAsm(input.script));
}
break;
}
});
}
for (const output of transaction.outs) {
if (output) {
sigops += countScriptSigops(convertScriptSigAsm(output.script), true);
}
}
const vsize = transaction.virtualSize();
if (vsize > sigops * 5) {
return vsize;
}
return sigops * 5;
}
exports.countAdjustedVsize = countAdjustedVsize;
//# sourceMappingURL=sigcost.js.map