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.

Raises:



10
11
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
# File 'lib/mastercoin-ruby/transaction.rb', line 10

def initialize(tx_hash)
  @store = Mastercoin.storage
  self.data_addresses = []
  self.rejected_outputs = [] 
  self.btc_tx = @store.get_tx(tx_hash)

  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

  self.source_address = Mastercoin::ExodusPayment.highest_output_for_tx(self.btc_tx)

  if multisig
    self.btc_tx.outputs.each do |output|
      if output.get_address == Mastercoin::EXODUS_ADDRESS
        # Do nothing yet; this is simply the exodus address
      elsif output.script.is_multisig?
        keys = output.script.get_multisig_pubkeys.collect{|x| x.unpack("H*")[0]}
        keys.each do |key| 
          self.data_addresses << Mastercoin::SimpleSend.decode_from_compressed_public_key(key) if Mastercoin::SimpleSend.decode_from_compressed_public_key(key).looks_like_mastercoin?
        end
      else
        #TODO Change this not really too trust worthy
        self.target_address = output.get_address if output.value == 0.00006 * 1e8
      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_addresses << 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)

      raise NoMastercoinTransactionException.new("Could not find a valid looking data-address, invalid.")

      if self.data_addresses[0].sequence.to_s == sequence.to_s
        self.target_address = address
      end
    end
  end

  self.data_addresses.sort!{|x, y| x.sequence.to_i <=> y.sequence.to_i }

  self.analyze_addresses!
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

#data_addressesObject

Returns the value of attribute data_addresses.



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

def data_addresses
  @data_addresses
end

#multisigObject

Returns the value of attribute multisig.



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

def multisig
  @multisig
end

#rejected_outputsObject

Returns the value of attribute rejected_outputs.



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

def rejected_outputs
  @rejected_outputs
end

#source_addressObject

Returns the value of attribute source_address.



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

def source_address
  @source_address
end

#target_addressObject

Returns the value of attribute target_address.



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

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

#analyze_addresses!Object



74
75
76
77
78
79
# File 'lib/mastercoin-ruby/transaction.rb', line 74

def analyze_addresses!
  address = self.data_addresses[0]
  self.transaction_type = address.transaction_type
  self.currency_id = address.currency_id
  self.amount = address.amount
end

#has_genesis_as_output?Boolean

Returns:



85
86
87
# File 'lib/mastercoin-ruby/transaction.rb', line 85

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

#has_three_outputs?Boolean

Returns:



81
82
83
# File 'lib/mastercoin-ruby/transaction.rb', line 81

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

#to_sObject



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

def to_s
  if self.transaction_type.to_s == "0"
    "Simple send:: Sent #{self.amount / 1e8} '#{Mastercoin::CURRENCY_IDS[self.currency_id.to_s]}' to #{self.target_address}"
  else
    "Unknown transaction: #{self.transaction_type}"
  end
end