UNPKG

meta-contract-debug

Version:

Meta Contract SDK

182 lines (181 loc) 7.68 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 = exports.sighashType = void 0; const mvc_scrypt_1 = require("mvc-scrypt"); const mvc = require("../mvc"); const TokenUtil = require("./tokenUtil"); const Signature = mvc.crypto.Signature; exports.sighashType = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID; 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, mvc_scrypt_1.toHex)(TokenUtil.getUInt8Buf(n)); } else if (n <= 255) { header = '4c' + (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt8Buf(n)); } else if (n <= 65535) { header = '4d' + (0, mvc_scrypt_1.toHex)(TokenUtil.getUInt16Buf(n)); } else { header = '4e' + (0, mvc_scrypt_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 mvc.PublicKey(publicKey); let _sig = mvc.crypto.Signature.fromString(sig); _sig.nhashtype = sighashType; if (contractType == CONTRACT_TYPE.P2PKH) { const signature = new mvc.Transaction.Signature({ publicKey, prevTxId: input.prevTxId, outputIndex: input.outputIndex, inputIndex: inputIndex, signature: _sig, sigtype: sighashType, }); input.setScript(mvc.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 mvc.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;