Class: Mastercoin::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/mastercoin-ruby/transaction.rb

Defined Under Namespace

Classes: NoMastercoinTransactionException

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tx_hash) ⇒ Transaction

Returns a new instance of Transaction.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
# File 'lib/mastercoin-ruby/transaction.rb', line 12

def initialize(tx_hash)
  @store = Mastercoin.storage
  self.data_addresses = []
  self.rejected_outputs = [] 
  self.btc_tx = @store.get_tx(tx_hash)
  self.sending_address = btc_tx.inputs.first.get_prev_out.get_address
  self.source_address = Mastercoin::ExodusPayment.highest_output_for_tx(self.btc_tx)

  exodus_value = nil

  raise TransactionNotFoundException.new("Transaction #{tx_hash} could not be found. Is your blockchain up to date?") if self.btc_tx.nil?

  unless self.has_genesis_as_output?
    raise NoMastercoinTransactionException.new("This transaction does not contain a txout to the genesis address, invalid.")
  end

  unless self.has_three_outputs?
    raise NoMastercoinTransactionException.new("This transaction does not contain three outputs, invalid.")
  end
 
  if self.btc_tx.outputs.collect{|x| x.script.is_multisig?}.include?(true)
    self.multisig = true
  else
    self.multisig = false
  end

  # This should probably be next up for refactor, smelling code creep!

  self.btc_tx.outputs.each do |output|
    if output.get_address == Mastercoin::EXODUS_ADDRESS
      exodus_value = output.value
    end
  end

  if multisig
    self.btc_tx.outputs.each do |output|
      if output.script.is_multisig?
        keys = output.script.get_multisig_pubkeys.collect{|x| x.unpack("H*")[0]}
        self.data = Mastercoin::Message.probe_and_read(keys, self.sending_address)
      elsif output.get_address == Mastercoin::EXODUS_ADDRESS
        # Do nothing for now
      else
        self.target_address = output.get_address if output.value == exodus_value
      end
    end
  else
    self.btc_tx.outputs.each do |output|
      if output.get_address == Mastercoin::EXODUS_ADDRESS
        # Do nothing yet; this is simply the exodus address
      elsif Mastercoin::SimpleSend.decode_from_address(output.get_address).looks_like_mastercoin? # This looks like a data packet
        self.data = Mastercoin::SimpleSend.decode_from_address(output.get_address)
      end
    end

    self.btc_tx.outputs.each do |output|
      address = output.get_address
      sequence = Mastercoin::Util.get_sequence(address)

      if self.data.sequence.to_s == sequence.to_s
        self.target_address = address
      end
    end

    unless self.target_address
      # Find data outputs and brute force receiver
      found = self.btc_tx.outputs.find_all{|x| x.value == exodus_value}.reject do |output|
        output.get_address == Mastercoin::EXODUS_ADDRESS || Mastercoin::SimpleSend.decode_from_address(output.get_address).looks_like_mastercoin? # This looks like a data packet
      end

      if found.length == 1
        self.target_address = found.first.get_address
      else
        puts "Could not find target address"
      end
    end
  end
  raise NoMastercoinTransactionException.new("Could not find a valid looking data-address, invalid.") unless self.data
end

Instance Attribute Details

#amountObject

Returns the value of attribute amount.



6
7
8
# File 'lib/mastercoin-ruby/transaction.rb', line 6

def amount
  @amount
end

#btc_txObject

Returns the value of attribute btc_tx.



5
6
7
# File 'lib/mastercoin-ruby/transaction.rb', line 5

def btc_tx
  @btc_tx
end

#currency_idObject

Returns the value of attribute currency_id.



6
7
8
# File 'lib/mastercoin-ruby/transaction.rb', line 6

def currency_id
  @currency_id
end

#dataObject

Returns the value of attribute data.



9
10
11
# File 'lib/mastercoin-ruby/transaction.rb', line 9

def data
  @data
end

#data_addressesObject

Returns the value of attribute data_addresses.



7
8
9
# File 'lib/mastercoin-ruby/transaction.rb', line 7

def data_addresses
  @data_addresses
end

#multisigObject

Returns the value of attribute multisig.



7
8
9
# File 'lib/mastercoin-ruby/transaction.rb', line 7

def multisig
  @multisig
end

#rejected_outputsObject

Returns the value of attribute rejected_outputs.



7
8
9
# File 'lib/mastercoin-ruby/transaction.rb', line 7

def rejected_outputs
  @rejected_outputs
end

#sending_addressObject

Returns the value of attribute sending_address.



7
8
9
# File 'lib/mastercoin-ruby/transaction.rb', line 7

def sending_address
  @sending_address
end

#source_addressObject

Returns the value of attribute source_address.



10
11
12
# File 'lib/mastercoin-ruby/transaction.rb', line 10

def source_address
  @source_address
end

#target_addressObject

Returns the value of attribute target_address.



7
8
9
# File 'lib/mastercoin-ruby/transaction.rb', line 7

def target_address
  @target_address
end

#transaction_typeObject

Returns the value of attribute transaction_type.



6
7
8
# File 'lib/mastercoin-ruby/transaction.rb', line 6

def transaction_type
  @transaction_type
end

Instance Method Details

#has_genesis_as_output?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/mastercoin-ruby/transaction.rb', line 95

def has_genesis_as_output?
  self.btc_tx.outputs.collect{|x| x.get_address == Mastercoin::EXODUS_ADDRESS}.any?
end

#has_three_outputs?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/mastercoin-ruby/transaction.rb', line 91

def has_three_outputs?
  self.btc_tx.outputs.size >= 3
end

#to_sObject



99
100
101
# File 'lib/mastercoin-ruby/transaction.rb', line 99

def to_s
  self.data.explain(self.sending_address, self.target_address)
end