Class: Bitcoin::Protocol::TxIn

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin/protocol/txin.rb

Constant Summary

DEFAULT_SEQUENCE =
"\xff\xff\xff\xff"
NULL_HASH =
"\x00"*32
COINBASE_INDEX =
0xffffffff

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ TxIn



33
34
35
36
37
38
39
# File 'lib/bitcoin/protocol/txin.rb', line 33

def initialize *args
  @prev_out_hash, @prev_out_index, @script_sig_length,
  @script_sig, @sequence = *args
  @script_sig_length ||= 0
  @script_sig ||= ''
  @sequence ||= DEFAULT_SEQUENCE
end

Instance Attribute Details

#prev_out_hashObject Also known as: prev_out

previous output hash



9
10
11
# File 'lib/bitcoin/protocol/txin.rb', line 9

def prev_out_hash
  @prev_out_hash
end

#prev_out_indexObject

previous output index



14
15
16
# File 'lib/bitcoin/protocol/txin.rb', line 14

def prev_out_index
  @prev_out_index
end

#script_sigObject Also known as: script

script_sig input Script (signature)



17
18
19
# File 'lib/bitcoin/protocol/txin.rb', line 17

def script_sig
  @script_sig
end

#script_sig_lengthObject Also known as: script_length

script_sig input Script (signature)



17
18
19
# File 'lib/bitcoin/protocol/txin.rb', line 17

def script_sig_length
  @script_sig_length
end

#sequenceObject

sequence



27
28
29
# File 'lib/bitcoin/protocol/txin.rb', line 27

def sequence
  @sequence
end

#sig_addressObject

signature hash and the address of the key that needs to sign it (used when dealing with unsigned or partly signed tx)



21
22
23
# File 'lib/bitcoin/protocol/txin.rb', line 21

def sig_address
  @sig_address
end

#sig_hashObject

signature hash and the address of the key that needs to sign it (used when dealing with unsigned or partly signed tx)



21
22
23
# File 'lib/bitcoin/protocol/txin.rb', line 21

def sig_hash
  @sig_hash
end

Class Method Details

.from_hash(input) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/bitcoin/protocol/txin.rb', line 93

def self.from_hash(input)
  previous_hash         = input['previous_transaction_hash'] || input['prev_out']['hash']
  previous_output_index = input['output_index'] || input['prev_out']['n']
  txin = TxIn.new([ previous_hash ].pack('H*').reverse, previous_output_index)
  if input['coinbase']
    txin.script_sig = [ input['coinbase'] ].pack("H*")
  else
    txin.script_sig = Script.binary_from_string(input['scriptSig'] || input['script'])
  end
  txin.sequence = [ input['sequence'] || 0xffffffff ].pack("V")
  txin
end

.from_hex_hash(hash, index) ⇒ Object



106
107
108
# File 'lib/bitcoin/protocol/txin.rb', line 106

def self.from_hex_hash(hash, index)
  TxIn.new([hash].pack("H*").reverse, index, 0)
end

.from_io(buf) ⇒ Object



63
64
65
# File 'lib/bitcoin/protocol/txin.rb', line 63

def self.from_io(buf)
  txin = new; txin.parse_data_from_io(buf); txin
end

Instance Method Details

#==(other) ⇒ Object

compare to another txout



42
43
44
45
46
47
48
49
# File 'lib/bitcoin/protocol/txin.rb', line 42

def ==(other)
  @prev_out_hash == other.prev_out_hash &&
    @prev_out_index == other.prev_out_index &&
    @script_sig == other.script_sig &&
    @sequence == other.sequence
rescue
  false
end

#add_signature_pubkey_script(sig, pubkey_hex) ⇒ Object



127
128
129
# File 'lib/bitcoin/protocol/txin.rb', line 127

def add_signature_pubkey_script(sig, pubkey_hex)
  self.script = Bitcoin::Script.to_signature_pubkey_script(sig, [pubkey_hex].pack("H*"))
end

#coinbase?Boolean

check if input is coinbase



116
117
118
# File 'lib/bitcoin/protocol/txin.rb', line 116

def coinbase?
  (@prev_out_index == COINBASE_INDEX) && (@prev_out_hash == NULL_HASH)
end

#is_final?Boolean

returns true if the sequence number is final (DEFAULT_SEQUENCE)



52
53
54
# File 'lib/bitcoin/protocol/txin.rb', line 52

def is_final?
  self.sequence == DEFAULT_SEQUENCE
end

#parse_data(data) ⇒ Object

parse raw binary data for transaction input



57
58
59
60
61
# File 'lib/bitcoin/protocol/txin.rb', line 57

def parse_data(data)
  buf = data.is_a?(String) ? StringIO.new(data) : data
  parse_data_from_io(buf)
  buf.pos
end

#parse_data_from_io(buf) ⇒ Object



67
68
69
70
71
72
# File 'lib/bitcoin/protocol/txin.rb', line 67

def parse_data_from_io(buf)
  @prev_out_hash, @prev_out_index = buf.read(36).unpack("a32V")
  @script_sig_length = Protocol.unpack_var_int_from_io(buf)
  @script_sig = buf.read(@script_sig_length)
  @sequence = buf.read(4)
end

#parsed_scriptObject



74
75
76
# File 'lib/bitcoin/protocol/txin.rb', line 74

def parsed_script
  @parsed_script ||= Bitcoin::Script.new(script_sig)
end

#prev_out=(hash) ⇒ Object



11
# File 'lib/bitcoin/protocol/txin.rb', line 11

def prev_out=(hash); @prev_out_hash = hash; end

#previous_outputObject

previous output in hex



111
112
113
# File 'lib/bitcoin/protocol/txin.rb', line 111

def previous_output
  @prev_out_hash.reverse_hth
end

#to_hash(options = {}) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/bitcoin/protocol/txin.rb', line 82

def to_hash(options = {})
  t = { 'prev_out'  => { 'hash' => @prev_out_hash.reverse_hth, 'n' => @prev_out_index } }
  if coinbase?
    t['coinbase']  = @script_sig.unpack("H*")[0]
  else # coinbase tx
    t['scriptSig'] = Bitcoin::Script.new(@script_sig).to_string
  end
  t['sequence']  = @sequence.unpack("V")[0] unless @sequence == "\xff\xff\xff\xff"
  t
end

#to_payload(script = @script_sig, sequence = @sequence) ⇒ Object



78
79
80
# File 'lib/bitcoin/protocol/txin.rb', line 78

def to_payload(script=@script_sig, sequence=@sequence)
  [@prev_out_hash, @prev_out_index].pack("a32V") << Protocol.pack_var_int(script.bytesize) << script << (sequence || DEFAULT_SEQUENCE)
end