The best library in JS for doing this is bsv2 which exposes an internal function which builds the preimage when signing a transaction, allowing you to output the result:
npm i bsv
node
const bsv = require('bsv')
const therawhex = '0100000001a772376502aef2738dca0089811044c3689896ac37053f24a9784a13399f764a010000008b483045022100b8a72a38b9630139a597f271c7016501656d717012d14f81ceee47ad7bce8bf702203bc16d1098ed3b81d04e836b4ea6ed5791a6b0863c9165529215b7be3616ec1a4141044ff33350fbb662de8f22d488319792b563dbd120b016a1bc55645465ee27edcb7e58fbaa4bb7ff1cd2620882a18132a3e51e0b0da6455d0ff08703db5b6234b2ffffffff02e8030000000000001976a91461079f5031a5b7e312d9fc5051fd7ce018fabc9288acb01d0000000000001976a9141f02307e6139effb4ec53283bcf6072e4796e10688ace9390b00'
tx.id()
// '9c60182f013eb70304b3dc6d63bc00e15b58a452040c29a0be11344e03760fd0'
Look that txid up here: https://whatsonchain.com/tx/9c60182f013eb70304b3dc6d63bc00e15b58a452040c29a0be11344e03760fd0
Click the JSON tab and grab the hex from the input the tx is spending, along with the value:
Then use them to calculate the Preimage:
var lockingScript = bsv.Script.fromHex('76a9141f02307e6139effb4ec53283bcf6072e4796e10688ac')
var satoshis = bsv.Bn(0.000088 * 100000000)
var sigHashType = bsv.Sig.SIGHASH_ALL | bsv.Sig.SIGHASH_FORKID
var flags = bsv.Tx.SCRIPT_ENABLE_SIGHASH_FORKID
var vIn = 0
var preimage = tx.sighashPreimage(sigHashType, vIn, lockingScript, satoshis, flags).toString('hex')
// 01000000822859cb9c3648de08a50feb15bb7f7c387478c43f55097cd1105800fa1778583bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044a772376502aef2738dca0089811044c3689896ac37053f24a9784a13399f764a010000001976a9141f02307e6139effb4ec53283bcf6072e4796e10688ac6022000000000000fffffffff5d957fb805c72174d3fe34c0559632e1ee9432a4a714bab7b1bc9fbec15a1d7e9390b0041000000
We can then parse that out to something more visual:
const { VarInt } = bsv
const preimageParser = hex => {
const toHex = str => str.toString('hex')
const preimage = Buffer.from(hex, 'hex')
const version = toHex(preimage.slice(0, 4)) // 4 bytes
const hashPrevouts = toHex(preimage.slice(4, 36))// 32 bytes
const hashSequence = toHex(preimage.slice(36, 68))// 32bytes
const txid = toHex(preimage.slice(68, 100).reverse())//32 bytes txid
const vout = toHex(preimage.slice(100, 104))// 4 bytes vout
const l = VarInt.fromBuffer(preimage.slice(104)).toNumber()
const varIntLength = VarInt.fromNumber(l).toBuffer().length
const len = preimage.length
const script = toHex(preimage.slice(104 + varIntLength, len - 52)) // bytes length of script
const satoshis = toHex(preimage.slice(len - 52, len - 44))// amount 8 bytes
const nSequence = toHex(preimage.slice(len - 44, len - 40))// 4 bytes
const hashOutputs = toHex(preimage.slice(len - 40, len - 8))// 32 bytes
const nLocktime = toHex(preimage.slice(len - 8, len - 4))// 4 bytes
const nHashType = toHex(preimage.slice(len - 4, len))// 4 bytes
return {
version, hashPrevouts, hashSequence, txid, vout, l, script, satoshis, nSequence, hashOutputs, nLocktime, nHashType
}
}
preimageParser(preimage)
// result below:
{
version: '01000000',
hashPrevouts: '822859cb9c3648de08a50feb15bb7f7c387478c43f55097cd1105800fa177858',
hashSequence: '3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044',
txid: '4a769f39134a78a9243f0537ac969868c34410818900ca8d73f2ae02653772a7',
vout: '01000000',
l: 25,
script: '76a9141f02307e6139effb4ec53283bcf6072e4796e10688ac',
satoshis: '6022000000000000',
nSequence: 'ffffffff',
hashOutputs: 'f5d957fb805c72174d3fe34c0559632e1ee9432a4a714bab7b1bc9fbec15a1d7',
nLocktime: 'e9390b00',
nHashType: '41000000'
}