Class BSV::Transaction::Beef ¶
Inherits: Object
Background Evaluation Extended Format (BEEF) for SPV-ready transaction bundles. Encodes one or more transactions together with their merkle proofs (BUMPs), enabling recipients to verify inclusion without querying a block explorer.
Supports BRC-62 (V1), BRC-96 (V2), and BRC-95 (Atomic BEEF) formats.
@example Parse a BEEF bundle and find a transaction
Constants¶
Version constants¶
ATOMIC_BEEF ¶
BRC-96
BEEF_V1 ¶
Version magic bytes as LE uint32 (matching pack('V') / unpack1('V')). Stream bytes: 01 00 BE EF / 02 00 BE EF / 01 01 01 01
BEEF_V2 ¶
BRC-62
Transaction format flags¶
FORMAT_RAW_TX ¶
Raw transaction without a merkle proof.
FORMAT_RAW_TX_AND_BUMP ¶
Raw transaction with an associated BUMP index.
FORMAT_TXID_ONLY ¶
Only the transaction ID (no raw data).
Attributes¶
bumps [R] ¶
- @return [Array
] merkle proofs (BUMPs) referenced by transactions
subject_txid [R] ¶
- @return [String, nil] 32-byte subject txid (Atomic BEEF only)
transactions [R] ¶
- @return [Array
] the transactions in dependency order
txs_not_valid [R] ¶
Returns transactions that could not be sorted due to cycles, or nil.
Populated by {#sort_transactions!} when cycles are detected (F5.5). - @return [Array
version [RW] ¶
- @return [Integer] BEEF version constant
Public Class Methods¶
from_binary(data) ¶
Deserialise a BEEF bundle from binary data.
Supports V1 (BRC-62), V2 (BRC-96), and Atomic (BRC-95) formats. After parsing, input source transactions are wired automatically. - @param data [String] raw BEEF binary - @raise [ArgumentError] - @return [Beef] the parsed BEEF bundle
from_hex(hex) ¶
Deserialise a BEEF bundle from a hex string. - @param hex [String] hex-encoded BEEF data - @return [Beef] the parsed BEEF bundle
Public Instance Methods¶
find_atomic_transaction(txid) ¶
Find a transaction and recursively wire its ancestry (source transactions and merkle paths) for atomic proof validation. - @param txid [String] 32-byte txid in display byte order - @return [Transaction, nil] the transaction with full proof tree, or nil
find_bump(txid) ¶
Find the merkle path (BUMP) for a transaction by its txid.
First checks the transaction-table entries, then scans @bumps directly for a BUMP whose level-0 leaves contain the txid. - @param txid [String] 32-byte txid in display byte order - @return [MerklePath, nil] the merkle path, or nil if not found
find_transaction(txid) ¶
Find a transaction in the bundle by its transaction ID. - @param txid [String] 32-byte txid in display byte order - @return [Transaction, nil] the matching transaction, or nil
find_transaction_for_signing(txid) ¶
Find a transaction with all source_transactions wired for signing. - @param txid [String] 32-byte txid in display byte order - @return [Transaction, nil] the transaction with wired inputs, or nil
initialize(version: = BEEF_V1, bumps: = [], transactions: = []) ¶
- @param
version[Integer] BEEF version constant (default: BEEF_V1, matching to_binary's default for ARC compatibility; from_binary overwrites this with the parsed version) - @param
bumps[Array] merkle proofs - @param
transactions[Array] transaction entries - @return [Beef] a new instance of Beef
make_txid_only(txid) ¶
Convert a transaction entry to TXID-only format. - @param txid [String] 32-byte txid in display byte order - @return [BeefTx, nil] the converted entry, or nil if not found
merge(other) ¶
Merge all BUMPs and transactions from another BEEF bundle.
BUMP indices are remapped during merge. New BeefTx instances are constructed rather than sharing references with the source bundle (F5.9). - @param other [Beef] the BEEF bundle to merge from - @raise [ArgumentError] if a transaction in +other+ has a +bump_index+ that does not point to any BUMP in +other.bumps+ (i.e. the source bundle is internally inconsistent) - @return [self]
merge_bump(merkle_path) ¶
Add or deduplicate a merkle path (BUMP) in this BEEF bundle.
If an existing BUMP shares the same block_height and merkle root, it is combined (via MerklePath#combine) and the existing index is returned. Otherwise the BUMP is appended.
After the BUMP is stored, any existing FORMAT_RAW_TX transactions whose txid appears in the new BUMP's level-0 leaves are retroactively upgraded to FORMAT_RAW_TX_AND_BUMP (F5.6). - @param merkle_path [MerklePath] the BUMP to merge - @return [Integer] the index of the (possibly merged) BUMP
merge_raw_tx(raw_bytes, bump_index: = nil) ¶
Add a transaction from raw binary data.
If the transaction already exists, upgrades weaker entries to stronger formats when a raw tx or bump_index is now available (F5.7). - @param raw_bytes [String] raw transaction binary - @param bump_index [Integer, nil] optional BUMP index - @return [BeefTx] the new or upgraded BeefTx entry
merge_transaction(tx) ¶
Add a transaction to this BEEF bundle.
Recursively merges the transaction's ancestors (via source_transaction references on inputs) and their merkle paths. Duplicate transactions (same txid) are upgraded if a stronger format is now available (F5.7): TXID_ONLY → RAW_TX or RAW_TX_AND_BUMP; RAW_TX → RAW_TX_AND_BUMP. - @param tx [Transaction] the transaction to merge - @return [BeefTx] the (possibly existing or upgraded) BeefTx entry
sort_transactions!() ¶
Sort transactions in topological (dependency) order in place.
After sorting, every transaction's input ancestors appear before it in the array. This is required for correct BEEF serialisation.
Transactions that form a cycle (i.e. cannot be topologically sorted) are moved to +@txs_not_valid+ rather than being silently dropped (F5.5). - @return [self]
to_atomic_binary(subject_txid) ¶
Serialise as Atomic BEEF (BRC-95), wrapping V2 data with a subject txid. - @param subject_txid [String] 32-byte subject transaction ID - @return [String] raw Atomic BEEF binary
to_atomic_hex(subject_txid) ¶
Serialise as Atomic BEEF (BRC-95) hex string. - @param subject_txid [String] 32-byte subject transaction ID - @return [String] hex-encoded Atomic BEEF
to_binary(version: = BEEF_V1) ¶
Serialise the BEEF bundle to binary format.
Defaults to V1 (BRC-62) for compatibility with ARC and the reference TS SDK. Pass +version: BEEF_V2+ for BRC-96 format. - @param version [Integer] BEEF_V1 (default) or BEEF_V2 - @raise [ArgumentError] if version is BEEF_V1 and the bundle contains any FORMAT_TXID_ONLY entries (V1 / BRC-62 has no TXID-only format; pass +version: BEEF_V2+ to serialise such bundles) - @return [String] raw BEEF binary
to_hex() ¶
Serialise the BEEF bundle to a hex string.
Uses the bundle's own +@version+, so a BEEF parsed from V2 round-trips to V2 hex, and a BEEF parsed from V1 (or freshly constructed via the default constructor) round-trips to V1 hex. - @return [String] hex-encoded BEEF data
valid?(allow_txid_only: = false) ¶
Check structural validity of the BEEF bundle.
A valid BEEF has every transaction either: * proven (has a BUMP / merkle_path), or * all its inputs reference transactions that are themselves valid within this bundle.
For FORMAT_RAW_TX_AND_BUMP entries, the BUMP linkage and computed root are also verified (F5.4). - @param allow_txid_only [Boolean] whether TXID-only entries count as valid (default: false) - @return [Boolean] true if structurally valid
verify(chain_tracker = nil, allow_txid_only: = false) ¶
Verify the BEEF bundle against a chain tracker (SPV).
Calls {#valid?} first for structural checks, then optionally verifies each BUMP's computed merkle root against the chain tracker (F5.3). - @param chain_tracker [#valid_root_for_height?] optional chain tracker (see {ChainTracker}) that responds to +valid_root_for_height?(root_hex, block_height)+ - @param allow_txid_only [Boolean] passed to {#valid?} - @return [Boolean] true if the bundle is structurally valid and, when a chain tracker is provided, all BUMP roots are confirmed by the chain