openassets-ruby 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa13af5ba17c13c7516e29819722ffc2a7a69766
4
- data.tar.gz: d94cc426ab8af56d2e0967f415323c67de17a6f7
3
+ metadata.gz: ead0fb7292a8d56c01d8894f5bc693e05ae0f8fe
4
+ data.tar.gz: 4ffbc89805cfc72986233c5cdb1e34ea38bb3186
5
5
  SHA512:
6
- metadata.gz: 3ebf299dbc652bffa5299bb23ab2cf32862f78cdadfcb010adf8d6a013a680d62b397fac19703de464612fa041ab01fd91959943414c65c9af04b869b3e07b20
7
- data.tar.gz: d338cb28973172b73696a1acef698028d54904fef2fdebe7e5148478eff2acea596f65218c185808c35e1f76157b26d651b382347a11a7e991f80cad9831de32
6
+ metadata.gz: 8ca8fd248203727d065c00bb7c90d177bd3b4b31bd6fec3e85752ee0580fdc034db18e7baad20e644b0aa3fbaa98b29e6f81095067f50fa8a136f1ffe3e729ac
7
+ data.tar.gz: d6bad60c27e19fc8c2094fcfa889f001d470954e749c408115b2ec6d16a55591768e3919806a7ccbaeecbb69220d90583f220a789a517b8aa00954e3691a524c
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # openassets-ruby
2
2
  The implementation of the Open Assets Protocol for Ruby.
3
3
 
4
+ ## Install
5
+
6
+ ```ruby
7
+ gem install openassets-ruby
8
+ ```
9
+
4
10
  ## Configuration
5
11
 
6
12
  Initialize the connection information to the Bitcoin Core server.
@@ -17,7 +23,6 @@ api = OpenAssets::Api.new({:network => 'mainnet',
17
23
  ## API
18
24
 
19
25
  Currently openassets-ruby support the following API.
20
- (The other API is in development. ex, send_asset)
21
26
 
22
27
  * **list_unspent**
23
28
  Returns an array of unspent transaction outputs, argument with the asset ID and quantity of each output.
@@ -49,7 +54,18 @@ Creates a transaction for issuing an asset.
49
54
  address = 'akEJwzkzEFau4t2wjbXoMs7MwtZkB8xixmH'
50
55
  api.issue_asset(address, 150, 'u=https://goo.gl/bmVEuw', address, nil, 'broadcast')
51
56
  ```
57
+ * **send_asset**
58
+ Creates a transaction for sending an asset from the open asset address to another.
59
+ ```ruby
60
+ # send asset
61
+ # api.send_asset(<from open asset address>, <asset ID>, <asset quantity>, <to open asset address>, <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>, <mode=('broadcast', 'signed', 'unsigned')>)
52
62
 
63
+ # example
64
+ from = 'akXDPMMHHBrUrd1fM756M1GSB8viVAwMyBk'
65
+ to = 'akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6'
66
+ api.send_asset(from, 'AWo3R89p5REmoSyMWB8AeUmud8456bRxZL', 100, to, 10000, 'broadcast')
67
+ ```
68
+
53
69
  ## License
54
70
 
55
71
  The MIT License (MIT)
@@ -104,6 +104,24 @@ module OpenAssets
104
104
  tx
105
105
  end
106
106
 
107
+ # Creates a transaction for sending an asset from an address to another.
108
+ # @param[String] from The open asset address to send the asset from.
109
+ # @param[String] asset_id The asset ID identifying the asset to send.
110
+ # @param[Integer] amount The amount of asset units to send.
111
+ # @param[String] to The open asset address to send the asset to.
112
+ # @param[Integer] fees The fess in satoshis for the transaction.
113
+ # @param[String] mode 'broadcast' (default) for signing and broadcasting the transaction,
114
+ # 'signed' for signing the transaction without broadcasting,
115
+ # 'unsigned' for getting the raw unsigned transaction without broadcasting"""='broadcast'
116
+ def send_asset(from, asset_id, amount, to, fees = nil, mode = 'broadcast')
117
+ builder = OpenAssets::Transaction::TransactionBuilder.new(@config[:dust_limit])
118
+ colored_outputs = get_unspent_outputs([oa_address_to_address(from)])
119
+ send_param = OpenAssets::Transaction::TransferParameters.new(colored_outputs, to, from, amount)
120
+ tx = builder.transfer_assets(asset_id, send_param, from, fees.nil? ? @config[:default_fees]: fees)
121
+ tx = process_transaction(tx, mode)
122
+ tx
123
+ end
124
+
107
125
  # Get unspent outputs.
108
126
  # @param [Array] addresses The array of Bitcoin address.
109
127
  # @return [Array[OpenAssets::Transaction::SpendableOutput]] The array of unspent outputs.
@@ -17,7 +17,7 @@ module OpenAssets
17
17
 
18
18
  # @param [Array] asset_quantities The asset quantity array
19
19
  # @param [String] metadata The metadata in the marker output.
20
- def initialize(asset_quantities, metadata)
20
+ def initialize(asset_quantities, metadata = '')
21
21
  @asset_quantities = asset_quantities
22
22
  @metadata = metadata
23
23
  end
@@ -0,0 +1,7 @@
1
+ module OpenAssets
2
+ module Transaction
3
+ # An insufficient amount of assets is available.
4
+ class InsufficientAssetQuantityError < TransactionBuildError
5
+ end
6
+ end
7
+ end
@@ -11,11 +11,11 @@ module OpenAssets
11
11
  @amount = amount
12
12
  end
13
13
 
14
- # issue asset.
14
+ # Creates a transaction for issuing an asset.
15
15
  # @param [TransferParameters] issue_spec The parameters of the issuance.
16
16
  # @param [bytes] metadata The metadata to be embedded in the transaction.
17
17
  # @param [Integer] fees The fees to include in the transaction.
18
- # @return An unsigned transaction for issuing asset.
18
+ # @return[Bitcoin:Protocol:Tx] An unsigned transaction for issuing asset.
19
19
  def issue_asset(issue_spec, metadata, fees)
20
20
  inputs, total_amount =
21
21
  TransactionBuilder.collect_uncolored_outputs(issue_spec.unspent_outputs, 2 * @amount + fees)
@@ -35,8 +35,59 @@ module OpenAssets
35
35
  tx
36
36
  end
37
37
 
38
- def transfer_assets
38
+ # Creates a transaction for sending an asset.
39
+ # @param[String] asset_id The ID of the asset being sent.
40
+ # @param[OpenAssets::Transaction::TransferParameters] transfer_spec The parameters of the asset being transferred.
41
+ # @param[String] btc_change_script The script where to send bitcoin change, if any.
42
+ # @param[Integer] fees The fees to include in the transaction.
43
+ # @return[Bitcoin::Protocol:Tx] The resulting unsigned transaction.
44
+ def transfer_assets(asset_id, transfer_spec, btc_change_script, fees)
45
+ btc_transfer_spec = OpenAssets::Transaction::TransferParameters.new(transfer_spec.unspent_outputs, nil, btc_change_script, 0)
46
+ outputs = []
47
+ asset_quantities = []
48
+ inputs, total_amount = TransactionBuilder.collect_colored_outputs(transfer_spec.unspent_outputs, asset_id, transfer_spec.amount)
39
49
 
50
+ # add asset transfer outpu
51
+ outputs << create_colored_output(oa_address_to_address(transfer_spec.to_script))
52
+ asset_quantities << transfer_spec.amount
53
+
54
+ # add the rest of the asset to the origin address
55
+ if total_amount > transfer_spec.amount
56
+ outputs << create_colored_output(oa_address_to_address(transfer_spec.change_script))
57
+ asset_quantities << (total_amount - transfer_spec.amount)
58
+ end
59
+
60
+ btc_excess = inputs.inject(0) { |sum, i| sum + i.output.value } - outputs.inject(0){|sum, o| sum + o.value}
61
+ if btc_excess < btc_transfer_spec.amount + fees
62
+ uncolored_outputs, uncolored_amount =
63
+ TransactionBuilder.collect_uncolored_outputs(btc_transfer_spec.unspent_outputs, btc_transfer_spec.amount + fees - btc_excess)
64
+ inputs << uncolored_outputs
65
+ btc_excess += uncolored_amount
66
+ end
67
+
68
+ change = btc_excess - btc_transfer_spec.amount - fees
69
+ if change > 0
70
+ outputs << create_uncolored_output(oa_address_to_address(btc_transfer_spec.change_script), change)
71
+ end
72
+
73
+ if btc_transfer_spec.amount > 0
74
+ outputs << create_uncolored_output(oa_address_to_address(btc_transfer_spec.to_script), btc_transfer_spec.amount)
75
+ end
76
+
77
+ # add marker output to outputs first.
78
+ unless asset_quantities.empty?
79
+ outputs.unshift(create_marker_output(asset_quantities))
80
+ end
81
+
82
+ tx = Bitcoin::Protocol::Tx.new
83
+ inputs.flatten.each{|i|
84
+ script_sig = i.output.script.to_binary
85
+ tx_in = Bitcoin::Protocol::TxIn.from_hex_hash(i.out_point.hash, i.out_point.index)
86
+ tx_in.script_sig = script_sig
87
+ tx.add_in(tx_in)
88
+ }
89
+ outputs.each{|o|tx.add_out(o)}
90
+ tx
40
91
  end
41
92
 
42
93
  def transfer_btc
@@ -60,6 +111,24 @@ module OpenAssets
60
111
  raise InsufficientFundsError
61
112
  end
62
113
 
114
+ # Returns a list of colored outputs for the specified quantity.
115
+ # @param[Array[OpenAssets::Transaction::SpendableOutput]] unspent_outputs
116
+ # @param[String] asset_id The ID of the asset to collect.
117
+ # @param[Integer] asset_quantity The asset quantity to collect.
118
+ # @return[Array[OpenAssets::Transaction::SpendableOutput], int] A list of outputs, and the total asset quantity collected.
119
+ def self.collect_colored_outputs(unspent_outputs, asset_id, asset_quantity)
120
+ total_amount = 0
121
+ result = []
122
+ unspent_outputs.each do |output|
123
+ if output.output.asset_id == asset_id
124
+ result << output
125
+ total_amount += output.output.asset_quantity
126
+ end
127
+ return result, total_amount if total_amount >= asset_quantity
128
+ end
129
+ raise InsufficientAssetQuantityError
130
+ end
131
+
63
132
  private
64
133
  # create colored output.
65
134
  # @param [String] address The Bitcoin address.
@@ -74,7 +143,7 @@ module OpenAssets
74
143
  # @param [Array] asset_quantities asset_quantity array.
75
144
  # @param [String] metadata
76
145
  # @return [Bitcoin::Protocol::TxOut] the marker output.
77
- def create_marker_output(asset_quantities, metadata)
146
+ def create_marker_output(asset_quantities, metadata = '')
78
147
  script = OpenAssets::Protocol::MarkerOutput.new(asset_quantities, metadata).build_script
79
148
  Bitcoin::Protocol::TxOut.new(0, script.to_payload)
80
149
  end
@@ -6,6 +6,7 @@ module OpenAssets
6
6
  autoload :OutPoint, 'openassets/transaction/out_point'
7
7
  autoload :TransactionBuildError, 'openassets/transaction/transaction_build_error'
8
8
  autoload :InsufficientFundsError, 'openassets/transaction/insufficient_funds_error'
9
+ autoload :InsufficientAssetQuantityError, 'openassets/transaction/insufficient_asset_quantity_error'
9
10
  autoload :DustOutputError, 'openassets/transaction/dust_output_error'
10
11
  end
11
12
  end
@@ -1,3 +1,3 @@
1
1
  module OpenAssets
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openassets-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-08-07 00:00:00.000000000 Z
11
+ date: 2015-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bitcoin-ruby
@@ -126,6 +126,7 @@ files:
126
126
  - lib/openassets/provider/block_chain_provider_base.rb
127
127
  - lib/openassets/transaction.rb
128
128
  - lib/openassets/transaction/dust_output_error.rb
129
+ - lib/openassets/transaction/insufficient_asset_quantity_error.rb
129
130
  - lib/openassets/transaction/insufficient_funds_error.rb
130
131
  - lib/openassets/transaction/out_point.rb
131
132
  - lib/openassets/transaction/spendable_output.rb