Class: BTC::AssetTransaction
- Inherits:
-
Object
- Object
- BTC::AssetTransaction
- Defined in:
- lib/btcruby/open_assets/asset_transaction.rb
Overview
Wrapper around Transaction that stores info about assets on inputs and outputs.
Instance Attribute Summary collapse
-
#inputs ⇒ Object
readonly
List of AssetTransactionInput instances.
-
#marker ⇒ Object
readonly
AssetMarker instance describing the transaction.
-
#metadata ⇒ Object
readonly
Metadata stored in AssetMarker.
-
#outputs ⇒ Object
readonly
List of AssetTransactionOutput instances.
-
#transaction ⇒ Object
readonly
Raw BTC::Transaction containing asset transfer.
-
#transaction_hash ⇒ Object
readonly
Identifier of the underlying Bitcoin transaction.
-
#transaction_id ⇒ Object
readonly
Returns the value of attribute transaction_id.
Instance Method Summary collapse
-
#data ⇒ Object
Serialized tx will have: - raw tx data - array of input colors (verified yes/no, asset id, units) - array of output colors (verified yes/no, asset id, units) - do not contain marker output.
- #dup ⇒ Object
-
#initialize(transaction: nil, data: nil) ⇒ AssetTransaction
constructor
A new instance of AssetTransaction.
- #inputs_verified? ⇒ Boolean
- #inspect ⇒ Object
- #issue_outputs ⇒ Object
-
#output_at_raw_index(i) ⇒ Object
deprecated.
- #outputs_verified? ⇒ Boolean
- #transfer_outputs ⇒ Object
-
#verified? ⇒ Boolean
AssetTransaction is considered verified when all outputs are verified.
Constructor Details
#initialize(transaction: nil, data: nil) ⇒ AssetTransaction
Returns a new instance of AssetTransaction.
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 90 91 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 27 def initialize(transaction: nil, data: nil) if data && !transaction txdata, len = WireFormat.read_string(data: data, offset: 0) raise ArgumentError, "Invalid data: tx data" if !txdata transaction = Transaction.new(data: txdata) data = data[len..-1] end raise ArgumentError, "Missing transaction" if !transaction raise FormatError, "Transaction does not contain an AssetMarker" if !transaction.open_assets_transaction? raise FormatError, "Coinbase transactions cannot be AssetTransactions" if transaction.coinbase? raise FormatError, "Transactions with no inputs cannot be AssetTransactions" if transaction.inputs.size == 0 @transaction = transaction # Extract the first marker output marker_output = transaction.outputs.find{|txout| txout.script.open_assets_marker? } @marker = AssetMarker.new(output: marker_output) # raises if marker is malformed # Create unverified inputs. @inputs = transaction.inputs.map do |txin| AssetTransactionInput.new(transaction_input: txin) end # Create unverified outputs for all outputs. @outputs = transaction.outputs.inject([]) do |array, txout| # note: other outputs looking like markers are allowed, so we check for the first one only. aout = AssetTransactionOutput.new(transaction_output: txout) if txout == marker_output aout.marker = true aout.verified = true else if (txout.index < marker_output.index) aout.issue = true else aout.transfer = true end end array << aout end # Check that the marker contains not more quantities than outputs available. # Marker output does not count and is not included in quantities list. if @marker.quantities.size > (@outputs.size - 1) raise FormatError, "OpenAssets marker specifies more quantities than colorable outputs available: #{@marker.quantities.size} > #{@outputs.size-1}." end # Fill in assets amounts for outputs (but keep them unverified). # Excessive outputs receive `nil` amount. @outputs.find_all{|o|!o.marker?}.each_with_index do |aout, i| aout.value = @marker.quantities[i] end # contains only color info about ins/outs if data offset = 0 @inputs.each do |ain| offset = ain.parse_assets_data(data, offset: offset) end @outputs.each do |aout| if !aout.marker? offset = aout.parse_assets_data(data, offset: offset) end end end end |
Instance Attribute Details
#inputs ⇒ Object
List of AssetTransactionInput instances.
12 13 14 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 12 def inputs @inputs end |
#marker ⇒ Object
AssetMarker instance describing the transaction
18 19 20 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 18 def marker @marker end |
#metadata ⇒ Object (readonly)
Metadata stored in AssetMarker
21 22 23 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 21 def end |
#outputs ⇒ Object
List of AssetTransactionOutput instances.
15 16 17 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 15 def outputs @outputs end |
#transaction ⇒ Object
Raw BTC::Transaction containing asset transfer
9 10 11 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 9 def transaction @transaction end |
#transaction_hash ⇒ Object (readonly)
Identifier of the underlying Bitcoin transaction.
24 25 26 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 24 def transaction_hash @transaction_hash end |
#transaction_id ⇒ Object (readonly)
Returns the value of attribute transaction_id.
25 26 27 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 25 def transaction_id @transaction_id end |
Instance Method Details
#data ⇒ Object
Serialized tx will have:
- raw tx data
- array of input colors (verified yes/no, asset id, units)
- array of output colors (verified yes/no, asset id, units) - do not contain marker output
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 97 def data data = "".b txdata = @transaction.data data << WireFormat.encode_string(txdata) @inputs.each do |ain| data << ain.assets_data end @outputs.each do |aout| if !aout.marker? data << aout.assets_data end end data end |
#dup ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 154 def dup atx = AssetTransaction.new(transaction: self.transaction.dup) self.inputs.each_with_index do |ain, i| ain2 = atx.inputs[i] ain2.asset_id = ain.asset_id ain2.value = ain.value ain2.verified = ain.verified end self.outputs.each_with_index do |aout, i| aout2 = atx.outputs[i] aout2.asset_id = aout.asset_id aout2.value = aout.value aout2.verified = aout.verified aout2.kind = aout.kind end end |
#inputs_verified? ⇒ Boolean
138 139 140 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 138 def inputs_verified? @inputs.all?{|i|i.verified?} end |
#inspect ⇒ Object
171 172 173 174 175 176 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 171 def inspect issues = issue_outputs.map{|out| out.value.inspect }.join(",") ins = inputs.map{|inp| inp.value.inspect }.join(",") outs = transfer_outputs.map{|out| out.value.inspect }.join(",") %{#<#{self.class}:#{self.transaction_id[0,8]} issues [#{issues}] transfers [#{ins}] => [#{outs}]>} end |
#issue_outputs ⇒ Object
124 125 126 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 124 def issue_outputs @outputs.find_all{|o| o.issue? } end |
#output_at_raw_index(i) ⇒ Object
deprecated
146 147 148 149 150 151 152 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 146 def output_at_raw_index(i) # deprecated @outputs[i] # @outputs.find do |out| # raise ArgumentError, "Underlying BTC::TransactionOutput instance are expected to have `index` attribute." if !out.index # out.index == i # end end |
#outputs_verified? ⇒ Boolean
142 143 144 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 142 def outputs_verified? @outputs.all?{|o|o.verified?} end |
#transfer_outputs ⇒ Object
128 129 130 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 128 def transfer_outputs @outputs.find_all{|o| o.transfer? } end |
#verified? ⇒ Boolean
AssetTransaction is considered verified when all outputs are verified. Inputs may remain unverified when their assets are destroyed.
134 135 136 |
# File 'lib/btcruby/open_assets/asset_transaction.rb', line 134 def verified? outputs_verified? end |