meta-contract-debug
Version:
Meta Contract SDK
227 lines (226 loc) • 8.56 kB
JavaScript
"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;