Class: BSV::Transaction::TransactionInput
- Inherits:
-
Object
- Object
- BSV::Transaction::TransactionInput
- Defined in:
- lib/bsv/transaction/transaction_input.rb
Overview
A transaction input referencing a previous output to spend.
Inputs identify the output being spent by its transaction ID and output index (the "outpoint"), and provide an unlocking script to satisfy the locking script conditions.
Instance Attribute Summary collapse
-
#prev_tx_out_index ⇒ Integer
readonly
Index of the output within the previous transaction.
-
#prev_wtxid ⇒ String
readonly
32-byte wire-order transaction ID of the output being spent.
-
#sequence ⇒ Object
Returns the value of attribute sequence.
-
#source_locking_script ⇒ Script::Script?
Locking script of the source output (needed for sighash).
-
#source_satoshis ⇒ Integer?
Satoshi value of the source output (needed for sighash).
-
#source_transaction ⇒ Transaction::Tx?
The full source transaction (for BEEF wiring).
-
#unlocking_script ⇒ Object
Returns the value of attribute unlocking_script.
-
#unlocking_script_template ⇒ UnlockingScriptTemplate?
Template for deferred signing.
Class Method Summary collapse
-
.from_binary(data, offset = 0) ⇒ Array(TransactionInput, Integer)
Deserialise a transaction input from binary data.
-
.wtxid_from_hex(hex) ⇒ String
Convert a display-order hex transaction ID to wire-order bytes.
Instance Method Summary collapse
-
#dtxid_hex ⇒ String
The previous transaction ID in display-order hex.
-
#initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF) ⇒ TransactionInput
constructor
A new instance of TransactionInput.
-
#initialize_copy(other) ⇒ Object
Called by
#dupand#clone. -
#outpoint_binary ⇒ String
Serialise the outpoint (prev_wtxid + output index) as binary.
-
#to_binary ⇒ String
Serialise the input to its binary wire format.
Constructor Details
#initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF) ⇒ TransactionInput
Returns a new instance of TransactionInput.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/bsv/transaction/transaction_input.rb', line 62 def initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF) BSV::Primitives::Hex.validate_wtxid!(prev_wtxid, name: 'prev_wtxid') # Defensively copy + freeze so external mutation of the caller's String # cannot stale the cached outpoint_binary / to_binary. @prev_wtxid = prev_wtxid.b.dup.freeze @prev_tx_out_index = prev_tx_out_index @unlocking_script = unlocking_script @sequence = sequence @owning_tx = nil BSV.logger&.debug { "[TransactionInput] prev_wtxid set: #{dtxid_hex}:#{@prev_tx_out_index}" } end |
Instance Attribute Details
#prev_tx_out_index ⇒ Integer (readonly)
Returns index of the output within the previous transaction.
15 16 17 |
# File 'lib/bsv/transaction/transaction_input.rb', line 15 def prev_tx_out_index @prev_tx_out_index end |
#prev_wtxid ⇒ String (readonly)
Returns 32-byte wire-order transaction ID of the output being spent.
12 13 14 |
# File 'lib/bsv/transaction/transaction_input.rb', line 12 def prev_wtxid @prev_wtxid end |
#sequence ⇒ Object
Returns the value of attribute sequence.
22 23 24 |
# File 'lib/bsv/transaction/transaction_input.rb', line 22 def sequence @sequence end |
#source_locking_script ⇒ Script::Script?
Enters the BIP-143 preimage as scriptCode (step 5) when no subscript override is supplied. Same caveat as #source_satoshis: no current cache layer depends on this field, but a future preimage cache would need a setter override here. See sighash-cache.
Returns locking script of the source output (needed for sighash).
46 47 48 |
# File 'lib/bsv/transaction/transaction_input.rb', line 46 def source_locking_script @source_locking_script end |
#source_satoshis ⇒ Integer?
Enters the BIP-143 preimage at step 6 but no current cache layer memoises the per-input preimage, so no invalidator is required. If a future change adds preimage or per-input digest memoisation, add a setter override here that invalidates the relevant cache slice. See sighash-cache.
Returns satoshi value of the source output (needed for sighash).
38 39 40 |
# File 'lib/bsv/transaction/transaction_input.rb', line 38 def source_satoshis @source_satoshis end |
#source_transaction ⇒ Transaction::Tx?
Source data is lazily resolved from this Tx during BSV::Transaction::Tx#verify and BSV::Transaction::Tx#sighash_preimage. Mutation of this field after resolution has occurred has no effect on caches because no current cache layer depends on resolved source data.
Returns the full source transaction (for BEEF wiring).
53 54 55 |
# File 'lib/bsv/transaction/transaction_input.rb', line 53 def source_transaction @source_transaction end |
#unlocking_script ⇒ Object
Returns the value of attribute unlocking_script.
30 31 32 |
# File 'lib/bsv/transaction/transaction_input.rb', line 30 def unlocking_script @unlocking_script end |
#unlocking_script_template ⇒ UnlockingScriptTemplate?
Returns template for deferred signing.
56 57 58 |
# File 'lib/bsv/transaction/transaction_input.rb', line 56 def unlocking_script_template @unlocking_script_template end |
Class Method Details
.from_binary(data, offset = 0) ⇒ Array(TransactionInput, Integer)
Deserialise a transaction input from binary data.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/bsv/transaction/transaction_input.rb', line 125 def self.from_binary(data, offset = 0) if data.bytesize < offset + 36 raise ArgumentError, "truncated input: need 36 bytes for outpoint at offset #{offset}, got #{data.bytesize - offset}" end prev_wtxid = data.byteslice(offset, 32) prev_tx_out_index = data.byteslice(offset + 32, 4).unpack1('V') offset += 36 script_len, vi_size = VarInt.decode(data, offset) offset += vi_size if data.bytesize < offset + script_len raise ArgumentError, "truncated input: need #{script_len} bytes for script at offset #{offset}, got #{data.bytesize - offset}" end unlocking_script = (BSV::Script::Script.from_binary(data.byteslice(offset, script_len)) if script_len.positive?) offset += script_len if data.bytesize < offset + 4 raise ArgumentError, "truncated input: need 4 bytes for sequence at offset #{offset}, got #{data.bytesize - offset}" end sequence = data.byteslice(offset, 4).unpack1('V') total = 36 + vi_size + script_len + 4 input = new( prev_wtxid: prev_wtxid, prev_tx_out_index: prev_tx_out_index, unlocking_script: unlocking_script, sequence: sequence ) [input, total] end |
.wtxid_from_hex(hex) ⇒ String
Convert a display-order hex transaction ID to wire-order bytes.
167 168 169 170 171 172 |
# File 'lib/bsv/transaction/transaction_input.rb', line 167 def self.wtxid_from_hex(hex) BSV::Primitives::Hex.validate_dtxid_hex!(hex, name: 'wtxid_from_hex input') wtxid = [hex].pack('H*').reverse BSV.logger&.debug { "[TransactionInput] wtxid_from_hex: #{hex} -> #{wtxid.bytesize}B wire-order" } wtxid end |
Instance Method Details
#dtxid_hex ⇒ String
The previous transaction ID in display-order hex.
188 189 190 |
# File 'lib/bsv/transaction/transaction_input.rb', line 188 def dtxid_hex @prev_wtxid.reverse.unpack1('H*') end |
#initialize_copy(other) ⇒ Object
Called by #dup and #clone. Clears the owning-Tx backref so that the
cloned input does not belong to any transaction until it is explicitly
added via Tx#add_input.
77 78 79 80 |
# File 'lib/bsv/transaction/transaction_input.rb', line 77 def initialize_copy(other) super @owning_tx = nil end |
#outpoint_binary ⇒ String
Memoised; see sighash-cache for the invalidation contract.
Serialise the outpoint (prev_wtxid + output index) as binary.
Memoised: outpoint components are attr_reader only so the value is
immutable after construction. Returns a frozen binary string.
181 182 183 |
# File 'lib/bsv/transaction/transaction_input.rb', line 181 def outpoint_binary @outpoint_binary ||= (@prev_wtxid + [@prev_tx_out_index].pack('V')).freeze end |
#to_binary ⇒ String
Memoised; see sighash-cache for the invalidation contract.
Serialise the input to its binary wire format.
109 110 111 112 113 114 115 116 117 118 |
# File 'lib/bsv/transaction/transaction_input.rb', line 109 def to_binary @to_binary ||= begin script_bytes = @unlocking_script ? @unlocking_script.to_binary : ''.b (@prev_wtxid + [@prev_tx_out_index].pack('V') + VarInt.encode(script_bytes.bytesize) + script_bytes + [@sequence].pack('V')).freeze end end |