Class: OpenAssets::Transaction::TransactionBuilder

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/openassets/transaction/transaction_builder.rb

Constant Summary

Constants included from Util

Util::OA_NAMESPACE, Util::OA_VERSION_BYTE, Util::OA_VERSION_BYTE_TESTNET

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

#address_to_oa_address, #coin_to_satoshi, #decode_leb128, #encode_leb128, #generate_asset_id, #hash_to_asset_id, #oa_address_to_address, #pubkey_hash_to_asset_id, #read_leb128, #read_var_integer, #satoshi_to_coin, #script_to_address, #script_to_asset_id, #to_bytes, #valid_asset_id?, #validate_address

Constructor Details

#initialize(amount = 600, efr = 10000) ⇒ TransactionBuilder

Returns a new instance of TransactionBuilder.



13
14
15
16
# File 'lib/openassets/transaction/transaction_builder.rb', line 13

def initialize(amount = 600, efr = 10000)
  @amount = amount
  @efr = efr 
end

Instance Attribute Details

#amountObject

The minimum allowed output value.



8
9
10
# File 'lib/openassets/transaction/transaction_builder.rb', line 8

def amount
  @amount
end

#efrObject

The estimated transaction fee rate (satoshis/KB).



11
12
13
# File 'lib/openassets/transaction/transaction_builder.rb', line 11

def efr
  @efr
end

Class Method Details

.collect_colored_outputs(unspent_outputs, asset_id, asset_quantity) ⇒ Object

Returns a list of colored outputs for the specified quantity. @param[Array] unspent_outputs @param asset_id The ID of the asset to collect. @param asset_quantity The asset quantity to collect. @return[Array, int] A list of outputs, and the total asset quantity collected.



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/openassets/transaction/transaction_builder.rb', line 141

def self.collect_colored_outputs(unspent_outputs, asset_id, asset_quantity)
  total_amount = 0
  result = []
  unspent_outputs.each do |output|
    if output.output.asset_id == asset_id
      result << output
      total_amount += output.output.asset_quantity
    end
    return result, total_amount if total_amount >= asset_quantity
  end
  raise InsufficientAssetQuantityError
end

.collect_uncolored_outputs(unspent_outputs, amount) ⇒ Array

collect uncolored outputs in unspent outputs(contains colored output).

Parameters:

Returns:

  • (Array)

    inputs, total_amount

Raises:



123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/openassets/transaction/transaction_builder.rb', line 123

def self.collect_uncolored_outputs(unspent_outputs, amount)
  total_amount = 0
  results = []
  unspent_outputs.each do |output|
    if output.output.asset_id.nil?
      results << output
      total_amount += output.output.value
    end
    return results, total_amount if total_amount >= amount
  end
  raise InsufficientFundsError
end

Instance Method Details

#burn_asset(unspents, asset_id, fee) ⇒ Object

Create a transaction for burn asset



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/openassets/transaction/transaction_builder.rb', line 90

def burn_asset(unspents, asset_id, fee)

  tx = Bitcoin::Protocol::Tx.new
  targets = unspents.select{|o|o.output.asset_id == asset_id}

  if fee == :auto
    # Calculate fees and otsuri (assume that one vout exists)
    fee = calc_fee(targets.size, 1)
  end
  
  raise TransactionBuildError.new('There is no asset.') if targets.length == 0
  total_amount = targets.inject(0){|sum, o|o.output.value + sum}
  otsuri = total_amount - fee
  if otsuri < @amount
    uncolored_outputs, uncolored_amount =
      TransactionBuilder.collect_uncolored_outputs(unspents, @amount - otsuri)
    targets = targets + uncolored_outputs
    otsuri += uncolored_amount
  end
  targets.each{|o|
    script_sig = o.output.script.to_binary
    tx_in = Bitcoin::Protocol::TxIn.from_hex_hash(o.out_point.hash, o.out_point.index)
    tx_in.script_sig = script_sig
    tx.add_in(tx_in)
  }
  tx.add_out(create_uncolored_output(targets[0].output.address, otsuri))
  tx
end

#issue_asset(issue_spec, metadata, fees) ⇒ Object

Creates a transaction for issuing an asset. @return An unsigned transaction for issuing asset.

Parameters:

  • issue_spec (TransferParameters)

    The parameters of the issuance.

  • metadata (bytes)

    The metadata to be embedded in the transaction.

  • fees (Integer)

    The fees to include in the transaction.



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
# File 'lib/openassets/transaction/transaction_builder.rb', line 23

def issue_asset(issue_spec, , fees)
  
  if fees == :auto
    # Calculate fees (assume that one vin and four vouts are wrote)
    fees = calc_fee(1, 4)
  end
  
  inputs, total_amount =
      TransactionBuilder.collect_uncolored_outputs(issue_spec.unspent_outputs, 2 * @amount + fees)
  tx = Bitcoin::Protocol::Tx.new
  inputs.each { |spendable|
    script_sig = spendable.output.script.to_binary
    tx_in = Bitcoin::Protocol::TxIn.from_hex_hash(spendable.out_point.hash, spendable.out_point.index)
    tx_in.script_sig = script_sig
    tx.add_in(tx_in)
  }
  issue_address = oa_address_to_address(issue_spec.to_script)
  from_address = oa_address_to_address(issue_spec.change_script)
  validate_address([issue_address, from_address])
  asset_quantities =[]
  issue_spec.split_output_amount.each{|amount|
    asset_quantities << amount
    tx.add_out(create_colored_output(issue_address))
  }
  tx.add_out(create_marker_output(asset_quantities, ))
  tx.add_out(create_uncolored_output(from_address, total_amount - @amount - fees))
  tx
end

#transfer_asset(asset_id, asset_transfer_spec, btc_change_script, fees) ⇒ Object

Creates a transaction for sending an asset. @param asset_id The ID of the asset being sent. @param asset_transfer_spec The parameters of the asset being transferred. @param btc_change_script The script where to send bitcoin change, if any. @param fees The fees to include in the transaction. @return The resulting unsigned transaction.



58
59
60
61
62
# File 'lib/openassets/transaction/transaction_builder.rb', line 58

def transfer_asset(asset_id, asset_transfer_spec, btc_change_script, fees)
  btc_transfer_spec = OpenAssets::Transaction::TransferParameters.new(
      asset_transfer_spec.unspent_outputs, nil, oa_address_to_address(btc_change_script), 0)
  transfer([[asset_id, asset_transfer_spec]], [btc_transfer_spec], fees)
end

#transfer_assets(transfer_specs, btc_transfer_spec, fees) ⇒ Object

Creates a transaction for sending assets to many. @param[Array] asset_transfer_spec The parameters of the asset being transferred. @param btc_transfer_spec The script where to send bitcoin change, if any. @param fees The fees to include in the transaction. @return The resulting unsigned transaction.



69
70
71
# File 'lib/openassets/transaction/transaction_builder.rb', line 69

def transfer_assets(transfer_specs, btc_transfer_spec, fees)
  transfer(transfer_specs, [btc_transfer_spec], fees)
end

#transfer_btc(btc_transfer_spec, fees) ⇒ Object

Creates a transaction for sending bitcoins. @param btc_transfer_spec The parameters of the bitcoins being transferred. @param fees The fees to include in the transaction. @return The resulting unsigned transaction.



77
78
79
# File 'lib/openassets/transaction/transaction_builder.rb', line 77

def transfer_btc(btc_transfer_spec, fees)
  transfer_btcs([btc_transfer_spec], fees)
end

#transfer_btcs(btc_transfer_specs, fees) ⇒ Object

Creates a transaction for sending bitcoins to many. @param[Array] btc_transfer_specs The parameters of the bitcoins being transferred. @param fees The fees to include in the transaction. @return The resulting unsigned transaction.



85
86
87
# File 'lib/openassets/transaction/transaction_builder.rb', line 85

def transfer_btcs(btc_transfer_specs, fees)
  transfer([], btc_transfer_specs, fees)
end