Class: BSV::Transaction::TransactionInput

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF) ⇒ TransactionInput

Returns a new instance of TransactionInput.

Parameters:

  • prev_wtxid (String)

    32-byte wire-order transaction ID

  • prev_tx_out_index (Integer)

    output index in the previous transaction

  • unlocking_script (Script::Script, nil) (defaults to: nil)

    unlocking script (nil if unsigned)

  • sequence (Integer) (defaults to: 0xFFFFFFFF)

    sequence number



39
40
41
42
43
44
45
46
# File 'lib/bsv/transaction/transaction_input.rb', line 39

def initialize(prev_wtxid:, prev_tx_out_index:, unlocking_script: nil, sequence: 0xFFFFFFFF)
  BSV::Primitives::Hex.validate_wtxid!(prev_wtxid, name: 'prev_wtxid')
  @prev_wtxid = prev_wtxid.b
  @prev_tx_out_index = prev_tx_out_index
  @unlocking_script = unlocking_script
  @sequence = sequence
  BSV.logger&.debug { "[TransactionInput] prev_wtxid set: #{dtxid_hex}:#{@prev_tx_out_index}" }
end

Instance Attribute Details

#prev_tx_out_indexInteger (readonly)

Returns index of the output within the previous transaction.

Returns:

  • (Integer)

    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_wtxidString (readonly)

Returns 32-byte wire-order transaction ID of the output being spent.

Returns:

  • (String)

    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

#sequenceInteger

Returns sequence number (default: 0xFFFFFFFF).

Returns:

  • (Integer)

    sequence number (default: 0xFFFFFFFF)



18
19
20
# File 'lib/bsv/transaction/transaction_input.rb', line 18

def sequence
  @sequence
end

#source_locking_scriptScript::Script?

Returns locking script of the source output (needed for sighash).

Returns:

  • (Script::Script, nil)

    locking script of the source output (needed for sighash)



27
28
29
# File 'lib/bsv/transaction/transaction_input.rb', line 27

def source_locking_script
  @source_locking_script
end

#source_satoshisInteger?

Returns satoshi value of the source output (needed for sighash).

Returns:

  • (Integer, nil)

    satoshi value of the source output (needed for sighash)



24
25
26
# File 'lib/bsv/transaction/transaction_input.rb', line 24

def source_satoshis
  @source_satoshis
end

#source_transactionTransaction?

Returns the full source transaction (for BEEF wiring).

Returns:

  • (Transaction, nil)

    the full source transaction (for BEEF wiring)



30
31
32
# File 'lib/bsv/transaction/transaction_input.rb', line 30

def source_transaction
  @source_transaction
end

#unlocking_scriptScript::Script?

Returns the unlocking script (set after signing).

Returns:



21
22
23
# File 'lib/bsv/transaction/transaction_input.rb', line 21

def unlocking_script
  @unlocking_script
end

#unlocking_script_templateUnlockingScriptTemplate?

Returns template for deferred signing.

Returns:



33
34
35
# File 'lib/bsv/transaction/transaction_input.rb', line 33

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.

Parameters:

  • data (String)

    binary data

  • offset (Integer) (defaults to: 0)

    byte offset to start reading from

Returns:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/bsv/transaction/transaction_input.rb', line 65

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.

Parameters:

  • hex (String)

    hex-encoded transaction ID (display order)

Returns:

  • (String)

    32-byte transaction ID in wire byte order



107
108
109
110
111
112
# File 'lib/bsv/transaction/transaction_input.rb', line 107

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_hexString

The previous transaction ID in display-order hex.

Returns:

  • (String)

    hex-encoded transaction ID (display order)



124
125
126
# File 'lib/bsv/transaction/transaction_input.rb', line 124

def dtxid_hex
  @prev_wtxid.reverse.unpack1('H*')
end

#outpoint_binaryString

Serialise the outpoint (prev_wtxid + output index) as binary.

Returns:

  • (String)

    36-byte outpoint



117
118
119
# File 'lib/bsv/transaction/transaction_input.rb', line 117

def outpoint_binary
  @prev_wtxid + [@prev_tx_out_index].pack('V')
end

#to_binaryString

Serialise the input to its binary wire format.

Returns:

  • (String)

    binary input (outpoint + varint + script + sequence)



51
52
53
54
55
56
57
58
# File 'lib/bsv/transaction/transaction_input.rb', line 51

def to_binary
  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')
end