openassets-ruby 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab88032ced409505e81e4ce0ed7ec27e59b61e3c
4
- data.tar.gz: d2b86f52973527638af824c70fbd2a57c734b5cc
3
+ metadata.gz: c4b3524d199fabcdbcb114a60fdc5ccb72537dfa
4
+ data.tar.gz: b6b4e4073d70fd1328c56758600de98bb702872c
5
5
  SHA512:
6
- metadata.gz: 4a95fda64c3b67b08c1f8496628a095800f79a23fb323362f5d4d8813a4cdb44e62890eecf78ef7908344c36a9a63ad28e16a04d79c925bf45e22286adfc82df
7
- data.tar.gz: efd6548365827737a57d08dde0740bfaa0c2c8ba9426c4357ad5b02e4176f56935edccb81f553e2d45de3e5f2d778470a17a7755459c8bc27f612aeae72250f3
6
+ metadata.gz: 4979c48dcc97d4d3d0bd40cfa2750b4ed8c309e791f9ee670ebe1688b702432a9d55c5c85161190a77e0e789887f336cc07ec82fa38689e5c3c774b962099f83
7
+ data.tar.gz: c9549400f7c66178df05cebb6441db3da8b0605e1c124ed938415bee3d1804d79c2d9a9748b2115cad6ae3e0a0e6457614b91aa15f59344f35147d1273f7bd94
data/README.md CHANGED
@@ -32,7 +32,39 @@ Returns an array of unspent transaction outputs, argument with the asset ID and
32
32
 
33
33
  # specify th open asset address.
34
34
  api.list_unspent(['akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6'])
35
+
36
+ > [
37
+ {
38
+ "txid": "1610a1f62597a3ea36e09e78354be22d2a958c1a38ed9e5d3f1c2811ee82dc37",
39
+ "vout": 1,
40
+ "address": "1HhJs3JgbiyxC8ktfi6nU4wTqVmrMtCVkG",
41
+ "oa_address": "akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6",
42
+ "script": "76a914b7218fe503cd18555255e5b13d4f07f3fd00d0c988ac",
43
+ "amount": "0.00000600",
44
+ "confirmations": 8338,
45
+ "asset_id": "AWo3R89p5REmoSyMWB8AeUmud8456bRxZL",
46
+ "account": "openassets-ruby",
47
+ "asset_quantity": "67",
48
+ "asset_amount": "6.7",
49
+ "asset_definition_url": "http://goo.gl/fS4mEj"
50
+ },
51
+ ...
35
52
  ```
53
+ Output items are as follows.
54
+
55
+ |Item|description|
56
+ |:---|:---|
57
+ |txid|The TXID of the transaction containing the output.|
58
+ |address| A P2PKH or P2SH address.|
59
+ |oa_address|The Open Asset address.|
60
+ |script|The output script.|
61
+ |amount|The Bitcoin amount.|
62
+ |confirmations|A score indicating the number of blocks on the best block chain that would need to be modified to remove or modify a particular transaction. |
63
+ |asset_id|The asset ID is a 160 bits hash, used to uniquely identify the asset stored on the output.|
64
+ |account|The name of an account.|
65
+ |asset_quantity|The asset quantity is an unsigned integer representing how many units of that asset are stored on the output.|
66
+ |asset_amount| The asset amount is the value obtained by converting the asset quantity to the unit of divisibility that are defined in the Asset definition file. |
67
+ |asset_definition_url|The url of asset definition file.|
36
68
 
37
69
  * **get_balance**
38
70
  Returns the balance in both bitcoin and colored coin assets for all of the addresses available in your Bitcoin Core wallet.
@@ -42,7 +74,41 @@ Returns the balance in both bitcoin and colored coin assets for all of the addre
42
74
 
43
75
  # specify the open asset address.
44
76
  api.get_balance('akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6')
77
+ > [
78
+ {
79
+ "address": "1HhJs3JgbiyxC8ktfi6nU4wTqVmrMtCVkG",
80
+ "oa_address": "akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6",
81
+ "value": "0.00018200",
82
+ "assets": [
83
+ {
84
+ "asset_id": "AWo3R89p5REmoSyMWB8AeUmud8456bRxZL",
85
+ "quantity": "81",
86
+ "amount": "20.7",
87
+ "asset_definition_url": "http://goo.gl/fS4mEj"
88
+ },
89
+ {
90
+ "asset_id": "AJk2Gx5V67S2wNuwTK5hef3TpHunfbjcmX",
91
+ "quantity": "67",
92
+ "amount": "6.7",
93
+ "asset_definition_url": ""
94
+ }
95
+ ],
96
+ "account": "openassets-ruby"
97
+ },
45
98
  ```
99
+ Output items are as follows.
100
+
101
+ |Item|description|
102
+ |:---|:---|
103
+ |address| A P2PKH or P2SH address.|
104
+ |oa_address|The Open Asset address.|
105
+ |value|The Bitcoin amount.|
106
+ |assets|The array of the assets.|
107
+ |asset_id|The asset ID is a 160 bits hash, used to uniquely identify the asset stored on the output.|
108
+ |asset_quantity|The asset quantity is an unsigned integer representing how many units of that asset are stored on the output.|
109
+ |asset_amount| The asset amount is the value obtained by converting the asset quantity to the unit of divisibility that are defined in the Asset definition file. |
110
+ |asset_definition_url|The url of asset definition file.|
111
+ |account|The name of an account.|
46
112
 
47
113
  * **issue_asset**
48
114
  Creates a transaction for issuing an asset.
@@ -61,13 +127,15 @@ Ex, amount = 125 and output_qty = 2, the marker output asset quantity is [62, 63
61
127
  Creates a transaction for sending an asset from the open asset address to another.
62
128
  ```ruby
63
129
  # send asset
64
- # 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')>)
130
+ # 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')>, <output_qty default value is 1.>)
65
131
 
66
132
  # example
67
133
  from = 'akXDPMMHHBrUrd1fM756M1GSB8viVAwMyBk'
68
134
  to = 'akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6'
69
135
  api.send_asset(from, 'AWo3R89p5REmoSyMWB8AeUmud8456bRxZL', 100, to, 10000, 'broadcast')
70
136
  ```
137
+ If specified ``output_qty``, the send output is divided by the number of output_qty.
138
+ Ex, asset holding amount = 200, and send amount = 125 and output_qty = 2, the marker output asset quantity is [62, 63, 75] and send TxOut is three. The last of the asset quantity is change asset output.
71
139
 
72
140
  * **send_bitcoin**
73
141
  Creates a transaction for sending bitcoins from an address to another.
@@ -53,6 +53,8 @@ module OpenAssets
53
53
  'asset_id' => out.output.asset_id,
54
54
  'account' => out.output.account,
55
55
  'asset_quantity' => out.output.asset_quantity.to_s,
56
+ 'asset_amount' => out.output.asset_amount.to_s,
57
+ 'asset_definition_url' => out.output.asset_definition_url
56
58
  }
57
59
  }
58
60
  oa_address.empty? ? result : result.select{|r|oa_address.include?(r['oa_address'])}
@@ -72,7 +74,9 @@ module OpenAssets
72
74
  assets = group_assets.map{|asset_id, outputs|
73
75
  {
74
76
  'asset_id' => asset_id,
75
- 'quantity' => outputs.inject(0) { |sum, o| sum + o.asset_quantity }.to_s
77
+ 'quantity' => outputs.inject(0) { |sum, o| sum + o.asset_quantity }.to_s,
78
+ 'amount' => outputs.inject(0) { |sum, o| sum + o.asset_amount }.to_s,
79
+ 'asset_definition_url' => outputs[0].asset_definition_url
76
80
  }
77
81
  }
78
82
  {
@@ -197,11 +201,13 @@ module OpenAssets
197
201
  # @param [Array[OpenAssets::Protocol::TransactionOutput] inputs The outputs referenced by the inputs of the transaction.
198
202
  # @param [Integer] marker_output_index The position of the marker output in the transaction.
199
203
  # @param [Array[Bitcoin::Protocol::TxOUt]] outputs The outputs of the transaction.
200
- # @param [Array[Integer]] asset_quantities The list of asset quantities of the outputs.
204
+ # @param [Array[OpenAssets::Protocol::TransactionOutput]] asset_quantities The list of asset quantities of the outputs.
201
205
  def compute_asset_ids(inputs, marker_output_index, outputs, asset_quantities)
202
206
  return nil if asset_quantities.length > outputs.length - 1 || inputs.length == 0
203
207
  result = []
204
208
 
209
+ marker_output = outputs[marker_output_index]
210
+
205
211
  # Add the issuance outputs
206
212
  issuance_asset_id = pubkey_hash_to_asset_id(inputs[0].script.get_hash160)
207
213
 
@@ -209,7 +215,14 @@ module OpenAssets
209
215
  value = outputs[i].value
210
216
  script = outputs[i].parsed_script
211
217
  if i < asset_quantities.length && asset_quantities[i] > 0
212
- output = OpenAssets::Protocol::TransactionOutput.new(value, script, issuance_asset_id, asset_quantities[i], OpenAssets::Protocol::OutputType::ISSUANCE)
218
+ payload = OpenAssets::Protocol::MarkerOutput.parse_script(marker_output.parsed_script.to_payload)
219
+ metadata = OpenAssets::Protocol::MarkerOutput.deserialize_payload(payload).metadata
220
+ if metadata.nil?
221
+ output = OpenAssets::Protocol::TransactionOutput.new(value, script, issuance_asset_id, asset_quantities[i], OpenAssets::Protocol::OutputType::ISSUANCE)
222
+ else
223
+ output = OpenAssets::Protocol::TransactionOutput.new(
224
+ value, script, issuance_asset_id, asset_quantities[i], OpenAssets::Protocol::OutputType::ISSUANCE, metadata)
225
+ end
213
226
  else
214
227
  output = OpenAssets::Protocol::TransactionOutput.new(value, script, nil, 0, OpenAssets::Protocol::OutputType::ISSUANCE)
215
228
  end
@@ -217,7 +230,6 @@ module OpenAssets
217
230
  end
218
231
 
219
232
  # Add the marker output
220
- marker_output = outputs[marker_output_index]
221
233
  result << OpenAssets::Protocol::TransactionOutput.new(marker_output.value, marker_output.parsed_script, nil, 0, OpenAssets::Protocol::OutputType::MARKER_OUTPUT)
222
234
 
223
235
  # Add the transfer outputs
@@ -228,6 +240,7 @@ module OpenAssets
228
240
  output_asset_quantity = (i <= asset_quantities.length) ? asset_quantities[i-1] : 0
229
241
  output_units_left = output_asset_quantity
230
242
  asset_id = nil
243
+ metadata = nil
231
244
  while output_units_left > 0
232
245
  index += 1
233
246
  if input_units_left == 0
@@ -245,13 +258,14 @@ module OpenAssets
245
258
  if asset_id.nil?
246
259
  # This is the first input to map to this output
247
260
  asset_id = current_input.asset_id
261
+ metadata = current_input.metadata
248
262
  elsif asset_id != current_input.asset_id
249
263
  return nil
250
264
  end
251
265
  end
252
266
  end
253
267
  result << OpenAssets::Protocol::TransactionOutput.new(outputs[i].value, outputs[i].parsed_script,
254
- asset_id, output_asset_quantity, OpenAssets::Protocol::OutputType::TRANSFER)
268
+ asset_id, output_asset_quantity, OpenAssets::Protocol::OutputType::TRANSFER, metadata)
255
269
  end
256
270
  result
257
271
  end
@@ -1,3 +1,4 @@
1
+ require 'rest-client'
1
2
  module OpenAssets
2
3
  module Protocol
3
4
 
@@ -45,7 +46,7 @@ module OpenAssets
45
46
  list = to_bytes(payload).map{|x|(x.to_i(16)>=128 ? x : x+"|")}.join.split('|')[0..(asset_quantity - 1)].join
46
47
  asset_quantities = decode_leb128(list)
47
48
  meta = to_bytes(payload[list.size..-1])
48
- metadata = meta[1..-1].map{|x|x.to_i(16).chr}.join
49
+ metadata = meta.empty? ? '' : meta[1..-1].map{|x|x.to_i(16).chr}.join
49
50
  new(asset_quantities, metadata)
50
51
  end
51
52
 
@@ -1,3 +1,5 @@
1
+ require 'rest-client'
2
+
1
3
  module OpenAssets
2
4
  module Protocol
3
5
 
@@ -10,20 +12,79 @@ module OpenAssets
10
12
  attr_accessor :output_type
11
13
 
12
14
  attr_accessor :account
15
+ attr_accessor :metadata
16
+ attr_accessor :asset_definition_url
17
+ attr_accessor :valid_asset_definition
18
+
13
19
 
14
20
  # @param [Integer] value The satoshi value of the output.
15
21
  # @param [Bitcoin::Script] script The script controlling redemption of the output.
16
22
  # @param [String] asset_id The asset ID of the output.
17
23
  # @param [Integer] asset_quantity The asset quantity of the output.
18
24
  # @param [OpenAssets::Transaction::OutPutType] output_type The type of the output.
19
- def initialize(value, script, asset_id = nil, asset_quantity = 0, output_type = OutputType::UNCOLORED)
25
+ def initialize(value, script, asset_id = nil, asset_quantity = 0, output_type = OutputType::UNCOLORED, metadata = '')
20
26
  raise ArgumentError, "invalid output_type : #{output_type}" unless OutputType.all.include?(output_type)
21
- raise ArgumentError, "invalid asset_quantity asset_quantity should be unsignd integer. " unless asset_quantity.between?(0, MarkerOutput::MAX_ASSET_QUANTITY)
27
+ raise ArgumentError, "invalid asset_quantity. asset_quantity should be unsignd integer. " unless asset_quantity.between?(0, MarkerOutput::MAX_ASSET_QUANTITY)
22
28
  @value = value
23
29
  @script = script
24
30
  @asset_id = asset_id
25
31
  @asset_quantity = asset_quantity
26
32
  @output_type = output_type
33
+ @metadata = metadata
34
+ load_asset_definition_url
35
+ end
36
+
37
+ # calculate asset amount.
38
+ # asset amount is the value obtained by converting the asset quantity to the unit of divisibility that are defined in the Asset definition file.
39
+ def asset_amount
40
+ d = divisibility
41
+ d > 0 ? (@asset_quantity.to_f / (10 ** d)).to_f : @asset_quantity
42
+ end
43
+
44
+ # get divisibility defined by asset definition file.
45
+ def divisibility
46
+ json = metadata_to_json
47
+ if json.nil? || json.length == 0
48
+ return 0
49
+ else
50
+ return json['divisibility']
51
+ end
52
+ end
53
+
54
+ # get Asset definition url that is included metadata.
55
+ private
56
+ def load_asset_definition_url
57
+ @valid_asset_definition = true
58
+ @asset_definition_url = ''
59
+ return if @metadata.nil? || @metadata.length == 0
60
+ if @metadata.start_with?('u=')
61
+ json = metadata_to_json
62
+ if json['asset_ids'].include?(@asset_id)
63
+ @asset_definition_url = metadata_url
64
+ else
65
+ @asset_definition_url = "The asset definition is invalid. #{metadata_url}"
66
+ @valid_asset_definition = false
67
+ end
68
+ else
69
+ @asset_definition_url = 'Invalid metadata format.'
70
+ @valid_asset_definition = false
71
+ end
72
+ end
73
+
74
+ private
75
+ def metadata_to_json
76
+ url = metadata_url
77
+ if url.nil?
78
+ ''
79
+ else
80
+ JSON.parse(RestClient.get url, :accept => :json)
81
+ end
82
+ end
83
+
84
+ def metadata_url
85
+ unless @metadata.nil?
86
+ @metadata.slice(2..-1)
87
+ end
27
88
  end
28
89
  end
29
90
 
@@ -30,12 +30,8 @@ module OpenAssets
30
30
  from_address = oa_address_to_address(issue_spec.change_script)
31
31
  validate_address([issue_address, from_address])
32
32
  asset_quantities =[]
33
- issue_spec.output_qty.times {|index|
34
- if index == issue_spec.output_qty - 1
35
- asset_quantities[index] = issue_spec.amount / issue_spec.output_qty + issue_spec.amount % issue_spec.output_qty
36
- else
37
- asset_quantities[index] = issue_spec.amount / issue_spec.output_qty
38
- end
33
+ issue_spec.split_output_amount.each{|amount|
34
+ asset_quantities << amount
39
35
  tx.add_out(create_colored_output(issue_address))
40
36
  }
41
37
  tx.add_out(create_marker_output(asset_quantities, metadata))
@@ -136,12 +132,7 @@ module OpenAssets
136
132
  inputs = inputs + colored_outputs
137
133
 
138
134
  # add asset transfer output
139
- transfer_spec.output_qty.times{|index|
140
- if index == transfer_spec.output_qty - 1
141
- amount = transfer_spec.amount / transfer_spec.output_qty + transfer_spec.amount % transfer_spec.output_qty
142
- else
143
- amount = transfer_spec.amount / transfer_spec.output_qty
144
- end
135
+ transfer_spec.split_output_amount.each {|amount|
145
136
  outputs << create_colored_output(oa_address_to_address(transfer_spec.to_script))
146
137
  asset_quantities << amount
147
138
  }
@@ -168,12 +159,7 @@ module OpenAssets
168
159
  end
169
160
 
170
161
  if btc_transfer_spec.amount > 0
171
- btc_transfer_spec.output_qty.times {|index|
172
- if index == btc_transfer_spec.output_qty - 1
173
- amount = btc_transfer_spec.amount / btc_transfer_spec.output_qty + btc_transfer_spec.amount % btc_transfer_spec.output_qty
174
- else
175
- amount = btc_transfer_spec.amount / btc_transfer_spec.output_qty
176
- end
162
+ btc_transfer_spec.split_output_amount.each {|amount|
177
163
  outputs << create_uncolored_output(btc_transfer_spec.to_script, amount)
178
164
  }
179
165
  end
@@ -23,6 +23,18 @@ module OpenAssets
23
23
  @output_qty = output_qty
24
24
  end
25
25
 
26
+ def split_output_amount
27
+ split_amounts = []
28
+ output_qty.times{|index|
29
+ if index == output_qty - 1
30
+ value = amount / output_qty + amount % output_qty
31
+ else
32
+ value = amount / output_qty
33
+ end
34
+ split_amounts << value
35
+ }
36
+ split_amounts
37
+ end
26
38
  end
27
39
 
28
40
  end
@@ -1,3 +1,3 @@
1
1
  module OpenAssets
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
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.6
4
+ version: 0.1.7
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-29 00:00:00.000000000 Z
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bitcoin-ruby