Resolve "WIP: UTXO Selection and Storage"
This commit is contained in:
@@ -10,19 +10,47 @@ import {
|
||||
import type { TransactionBCH } from '@bitauth/libauth';
|
||||
|
||||
/**
|
||||
* Transaction Entity.
|
||||
* Transaction Primitive.
|
||||
*/
|
||||
export class Transaction {
|
||||
constructor(public transaction: TransactionBCH) {}
|
||||
|
||||
/**
|
||||
* Create a Transaction Entity from the given byte data.
|
||||
* Instantiates a transaction from either:
|
||||
*
|
||||
* @param bytes {Uint8Array} The raw byte data of the transaction.
|
||||
* 1. Transaction bytecode
|
||||
* 2. Transaction bytecode (in hexadecimal format)
|
||||
*
|
||||
* @param transaction The transaction in one of the above formats.
|
||||
*
|
||||
* @throws {Error} If transaction data cannot be decoded.
|
||||
*
|
||||
* @returns {Transaction} The created Transaction Entity.
|
||||
* @returns The created Transaction Primitive.
|
||||
*/
|
||||
public static from(transaction: Uint8Array | string) {
|
||||
// Handle string (hex) case
|
||||
if (typeof transaction === 'string') {
|
||||
return Transaction.fromHex(transaction);
|
||||
}
|
||||
|
||||
// Handle Uint8Array case
|
||||
if (transaction instanceof Uint8Array) {
|
||||
return Transaction.fromBytes(transaction);
|
||||
}
|
||||
|
||||
throw new TypeError(
|
||||
'Invalid transaction input type. Expected Uint8Array, or hex string',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Transaction Primitive from the given byte data.
|
||||
*
|
||||
* @param bytes The raw byte data of the transaction.
|
||||
*
|
||||
* @throws {Error} If transaction data cannot be decoded.
|
||||
*
|
||||
* @returns {Transaction} The created Transaction Primitive.
|
||||
*/
|
||||
public static fromBytes(bytes: Uint8Array): Transaction {
|
||||
// Attempt to decode the raw transaction bytes.
|
||||
@@ -33,18 +61,18 @@ export class Transaction {
|
||||
throw new Error(decodeResult);
|
||||
}
|
||||
|
||||
// Return a new instance of the Transaction Entity created from the decode result.
|
||||
// Return a new instance of the Transaction Primitive created from the decode result.
|
||||
return new Transaction(decodeResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Transaction Entity from the given byte data encoded as hexadecimal string.
|
||||
* Create a Transaction Primitive from the given byte data encoded as hexadecimal string.
|
||||
*
|
||||
* @param hex {string} The raw byte data (encoded as hexadecimal string) of the transaction.
|
||||
* @param hex The raw byte data (encoded as hexadecimal string) of the transaction.
|
||||
*
|
||||
* @throws {Error} If transaction cannot be decoded.
|
||||
*
|
||||
* @returns {Transaction} The created Transaction Entity.
|
||||
* @returns {Transaction} The created Transaction Primitive.
|
||||
*/
|
||||
public static fromHex(hex: string): Transaction {
|
||||
// Ensure that the given string is hex.
|
||||
@@ -59,12 +87,17 @@ export class Transaction {
|
||||
return Transaction.fromBytes(bytes);
|
||||
}
|
||||
|
||||
public static fromAny(bytesOrHex: Uint8Array | string) {
|
||||
if (typeof bytesOrHex === 'string') {
|
||||
return Transaction.fromHex(bytesOrHex);
|
||||
}
|
||||
|
||||
return Transaction.fromBytes(bytesOrHex);
|
||||
/**
|
||||
* Create a Transaction Primitive from LibAuth's TransactionBCH type.
|
||||
*
|
||||
* @remarks This method is UNSAFE and should only be used where input is trusted.
|
||||
*
|
||||
* @param transaction The transaction object (as per LibAuth).
|
||||
*
|
||||
* @returns The created Transaction Primitive.
|
||||
*/
|
||||
public static fromRaw(transaction: TransactionBCH) {
|
||||
return new this(transaction);
|
||||
}
|
||||
|
||||
public toBytes(): Uint8Array {
|
||||
@@ -91,6 +124,30 @@ export class Transaction {
|
||||
return this.toHash().toBytes();
|
||||
}
|
||||
|
||||
public toRaw(): TransactionBCH {
|
||||
return this.transaction;
|
||||
}
|
||||
|
||||
public isCoinbase(): boolean {
|
||||
// A coinbase transaction MUST only have one input
|
||||
if (this.getInputs().length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const input = this.getInputs()[0];
|
||||
|
||||
// Check if the outpoint transaction hash is all zeros (32 bytes of 0x00)
|
||||
const isOutpointZero = input.outpointTransactionHash.every(
|
||||
(byte) => byte === 0x00,
|
||||
);
|
||||
|
||||
// Check if the outpoint index is 0xFFFFFFFF (or -1 in signed 32-bit integer representation)
|
||||
const isOutpointIndexMax = input.outpointIndex === 0xffffffff;
|
||||
|
||||
// Both conditions must be true for a coinbase transaction
|
||||
return isOutpointZero && isOutpointIndexMax;
|
||||
}
|
||||
|
||||
public getVersion() {
|
||||
return this.transaction.version;
|
||||
}
|
||||
@@ -106,24 +163,4 @@ export class Transaction {
|
||||
public getLocktime() {
|
||||
return this.transaction.locktime;
|
||||
}
|
||||
|
||||
public isCoinbase(): boolean {
|
||||
// A coinbase transaction MUST only have one input
|
||||
if (this.getInputs().length !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const input = this.getInputs()[0];
|
||||
|
||||
// Check if the outpoint transaction hash is all zeros (32 bytes of 0x00)
|
||||
const isOutpointZero = input.outpointTransactionHash.every(
|
||||
(byte) => byte === 0x00
|
||||
);
|
||||
|
||||
// Check if the outpoint index is 0xFFFFFFFF (or -1 in signed 32-bit integer representation)
|
||||
const isOutpointIndexMax = input.outpointIndex === 0xffffffff;
|
||||
|
||||
// Both conditions must be true for a coinbase transaction
|
||||
return isOutpointZero && isOutpointIndexMax;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user