@vbyte/btc-dev
Version:
Batteries-included toolset for plebian bitcoin development
95 lines (94 loc) • 2.78 kB
JavaScript
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');
}
}