UNPKG

@vbyte/btc-dev

Version:

Batteries-included toolset for plebian bitcoin development

95 lines (94 loc) 2.78 kB
import { Buff } from '@vbyte/buff'; import { Assert } from '@vbyte/micro-lib'; import { assert_tx_data } from './validate.js'; import { COINBASE } from '../../const.js'; export function encode_tx(txdata, use_segwit = true) { assert_tx_data(txdata); const { version, vin, vout, locktime } = txdata; const buffer = [encode_tx_version(version)]; if (use_segwit) { buffer.push(Buff.hex('0001')); } buffer.push(encode_tx_inputs(vin)); buffer.push(encode_tx_outputs(vout)); if (use_segwit) { for (const input of vin) { buffer.push(encode_vin_witness(input.witness)); } } buffer.push(encode_tx_locktime(locktime)); return Buff.join(buffer); } export function encode_tx_version(num) { return Buff.num(num, 4).reverse(); } export function encode_txin_txid(txid) { return Buff.hex(txid, 32).reverse(); } export function encode_txin_vout(vout) { return Buff.num(vout, 4).reverse(); } export function encode_txin_sequence(sequence) { return Buff.num(sequence, 4).reverse(); } export function encode_tx_inputs(vin) { const raw = [Buff.varint(vin.length, 'le')]; for (const input of vin) { raw.push(encode_vin(input)); } return Buff.join(raw); } export function encode_vin(txin) { if (txin.coinbase !== null) { return Buff.join([ encode_txin_txid(COINBASE.TXID), encode_txin_vout(COINBASE.VOUT), encode_script_data(txin.coinbase), encode_txin_sequence(txin.sequence) ]); } else { return Buff.join([ encode_txin_txid(txin.txid), encode_txin_vout(txin.vout), encode_script_data(txin.script_sig), encode_txin_sequence(txin.sequence) ]); } } export function encode_vout_value(value) { return Buff.big(value, 8).reverse(); } export function encode_tx_outputs(vout) { const buffer = [Buff.varint(vout.length, 'le')]; for (const output of vout) { buffer.push(encode_tx_vout(output)); } return Buff.join(buffer); } export function encode_tx_vout(txout) { const { value, script_pk } = txout; return Buff.join([ encode_vout_value(value), encode_script_data(script_pk) ]); } export function encode_vin_witness(data) { const buffer = [Buff.varint(data.length)]; for (const param of data) { buffer.push(encode_script_data(param)); } return Buff.join(buffer); } export function encode_tx_locktime(locktime) { return Buff.num(locktime, 4).reverse(); } export function encode_script_data(script) { if (script !== null) { Assert.is_hex(script); return Buff.hex(script).prefix_varint('le'); } else { return Buff.hex('00'); } }