UNPKG

meta-contract-debug

Version:

Meta Contract SDK

227 lines (226 loc) 8.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTxInfoHex = exports.getTxOutputProof = exports.getTxInputProof = exports.getTxidInfo = exports.getOpPushDataLen = exports.buildScriptData = exports.getEmptyTxOutputProof = exports.getOutpointBuf = exports.getRabinPubKeyHashArray = exports.getGenesisHashFromLockingScript = exports.getLockingScriptFromPreimage = exports.writeVarint = exports.getScriptHashBuf = exports.getTxIdBuf = exports.getUInt64Buf = exports.getUInt32Buf = exports.getUInt16Buf = exports.getUInt8Buf = exports.toBufferLE = exports.RABIN_SIG_LEN = void 0; const mvc = require("../mvc"); const mvc_scrypt_1 = require("mvc-scrypt"); const BN = require("../bn.js"); exports.RABIN_SIG_LEN = 384; let toBufferLE = function (num, width) { const hex = num.toString(16); const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex'); buffer.reverse(); return buffer; }; exports.toBufferLE = toBufferLE; let getUInt8Buf = function (amount) { const buf = Buffer.alloc(1, 0); buf.writeUInt8(amount); return buf; }; exports.getUInt8Buf = getUInt8Buf; let getUInt16Buf = function (amount) { const buf = Buffer.alloc(2, 0); buf.writeUInt16LE(amount); return buf; }; exports.getUInt16Buf = getUInt16Buf; let getUInt32Buf = function (index) { const buf = Buffer.alloc(4, 0); buf.writeUInt32LE(index); return buf; }; exports.getUInt32Buf = getUInt32Buf; let getUInt64Buf = function (amount) { return new BN(amount.toString()).toBuffer({ endian: 'little', size: 8 }); }; exports.getUInt64Buf = getUInt64Buf; let getTxIdBuf = function (txid) { const buf = Buffer.from(txid, 'hex').reverse(); return buf; }; exports.getTxIdBuf = getTxIdBuf; let getScriptHashBuf = function (scriptBuf) { const buf = Buffer.from(mvc.crypto.Hash.sha256ripemd160(scriptBuf)); return buf; }; exports.getScriptHashBuf = getScriptHashBuf; let writeVarint = function (buf) { const n = buf.length; let header; let res = Buffer.alloc(0); if (n < 0xfd) { header = (0, exports.getUInt8Buf)(n); } else if (n < 0x10000) { header = Buffer.concat([Buffer.from('fd', 'hex'), (0, exports.getUInt16Buf)(n)]); } else if (n < 0x100000000) { header = Buffer.concat([Buffer.from('fe', 'hex'), (0, exports.getUInt32Buf)(n)]); } else if (n < 0x10000000000000000) { header = Buffer.concat([Buffer.from('ff', 'hex'), (0, exports.getUInt64Buf)(n)]); } return Buffer.concat([header, buf]); }; exports.writeVarint = writeVarint; let getLockingScriptFromPreimage = function (buf) { const offset = 4 + 32 + 32 + 32 + 4; buf = buf.slice(offset, buf.length); const n = buf[0]; buf = buf.slice(1, buf.length); let lockingScriptBuf; if (n < 0xfd) { let len = n; lockingScriptBuf = buf.slice(0, len); } else if (n == 0xfd) { let len = buf.slice(0, 2).readInt16LE(0); lockingScriptBuf = buf.slice(2, len + 2); } else if (n == 0xfe) { let len = buf.slice(0, 4).readInt32LE(0); lockingScriptBuf = buf.slice(4, len + 4); } else if (n == 0xff) { let len = Number(buf.slice(0, 8).readBigUInt64LE(0)); lockingScriptBuf = buf.slice(8, len + 8); } return lockingScriptBuf; }; exports.getLockingScriptFromPreimage = getLockingScriptFromPreimage; let getGenesisHashFromLockingScript = function (lockingScript) { let genesisHash; let c = 0; for (let i = 0; i < lockingScript.chunks.length; i++) { let chunk = lockingScript.chunks[i]; if (chunk.buf && chunk.buf.length == 20) { c++; if (c == 11) { genesisHash = chunk.buf; break; } } } return genesisHash; }; exports.getGenesisHashFromLockingScript = getGenesisHashFromLockingScript; let getRabinPubKeyHashArray = function (rabinPubKeys) { let buf = Buffer.alloc(0); for (let i = 0; i < rabinPubKeys.length; i++) { buf = Buffer.concat([ buf, mvc.crypto.Hash.sha256ripemd160(this.toBufferLE(rabinPubKeys[i].toString(16), this.RABIN_SIG_LEN)), ]); } return buf; }; exports.getRabinPubKeyHashArray = getRabinPubKeyHashArray; function getOutpointBuf(txid, index) { const txidBuf = Buffer.from(txid, 'hex').reverse(); const indexBuf = Buffer.alloc(4, 0); indexBuf.writeUInt32LE(index); let buf = Buffer.concat([txidBuf, indexBuf]); return buf; } exports.getOutpointBuf = getOutpointBuf; const getEmptyTxOutputProof = function () { const data = { txHeader: new mvc_scrypt_1.Bytes(''), hashProof: new mvc_scrypt_1.Bytes(''), satoshiBytes: new mvc_scrypt_1.Bytes(''), scriptHash: new mvc_scrypt_1.Bytes(''), }; return data; }; exports.getEmptyTxOutputProof = getEmptyTxOutputProof; const buildScriptData = function (data) { let res = Buffer.concat([data, (0, exports.getUInt32Buf)(0), (0, exports.getUInt8Buf)(255)]); const pushDataLen = (0, exports.getOpPushDataLen)(res.length); res.writeUInt32LE(pushDataLen + data.length, data.length); return res; }; exports.buildScriptData = buildScriptData; const getOpPushDataLen = function (dataLen) { if (dataLen <= 75) { return 1; } else if (dataLen <= 255) { return 2; } else if (dataLen <= 65535) { return 3; } else { return 5; } }; exports.getOpPushDataLen = getOpPushDataLen; function getTxidInfo(tx) { const writer = new mvc.encoding.BufferWriter(); writer.writeUInt32LE(tx.version); writer.writeUInt32LE(tx.nLockTime); writer.writeUInt32LE(tx.inputs.length); writer.writeUInt32LE(tx.outputs.length); const inputWriter = new mvc.encoding.BufferWriter(); const inputWriter2 = new mvc.encoding.BufferWriter(); for (const input of tx.inputs) { inputWriter.writeReverse(input.prevTxId); inputWriter.writeUInt32LE(input.outputIndex); inputWriter.writeUInt32LE(input.sequenceNumber); inputWriter2.write(mvc.crypto.Hash.sha256(input.script.toBuffer())); } const inputHashProof = inputWriter.toBuffer(); writer.write(mvc.crypto.Hash.sha256(inputHashProof)); writer.write(mvc.crypto.Hash.sha256(inputWriter2.toBuffer())); const outputWriter = new mvc.encoding.BufferWriter(); for (const output of tx.outputs) { outputWriter.writeUInt64LEBN(output.satoshisBN); outputWriter.write(mvc.crypto.Hash.sha256(output.script.toBuffer())); } const outputHashProof = outputWriter.toBuffer(); writer.write(mvc.crypto.Hash.sha256(outputHashProof)); const txHeader = writer.toBuffer().toString('hex'); return { txHeader, inputHashProof: inputHashProof.toString('hex'), outputHashProof: outputHashProof.toString('hex'), }; } exports.getTxidInfo = getTxidInfo; const getTxInputProof = function (tx, inputIndex) { const info = getTxidInfo(tx); const txHeader = new mvc_scrypt_1.Bytes(info.txHeader); const input = tx.inputs[inputIndex]; const res = { hashProof: new mvc_scrypt_1.Bytes(info.inputHashProof), txHash: new mvc_scrypt_1.Bytes(Buffer.from(input.prevTxId, 'hex') .reverse() .toString('hex')), outputIndexBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt32Buf)(input.outputIndex).toString('hex')), sequenceBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt32Buf)(input.sequenceNumber).toString('hex')), }; return [res, txHeader]; }; exports.getTxInputProof = getTxInputProof; const getTxOutputProof = function (tx, outputIndex) { const info = getTxidInfo(tx); const output = tx.outputs[outputIndex]; const res = { txHeader: new mvc_scrypt_1.Bytes(info.txHeader), hashProof: new mvc_scrypt_1.Bytes(info.outputHashProof), satoshiBytes: new mvc_scrypt_1.Bytes((0, exports.getUInt64Buf)(output.satoshis).toString('hex')), scriptHash: new mvc_scrypt_1.Bytes(mvc.crypto.Hash.sha256(output.script.toBuffer()).toString('hex')), }; return res; }; exports.getTxOutputProof = getTxOutputProof; const getTxInfoHex = function (tx, outputIndex) { const info = getTxidInfo(tx); const output = tx.outputs[outputIndex]; return { txHeader: info.txHeader, txHashProof: info.outputHashProof, txSatoshi: (0, exports.getUInt64Buf)(output.satoshis).toString('hex'), }; }; exports.getTxInfoHex = getTxInfoHex;