openassets-ruby 0.1.6 → 0.1.7
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 +4 -4
- data/README.md +69 -1
- data/lib/openassets/api.rb +19 -5
- data/lib/openassets/protocol/marker_output.rb +2 -1
- data/lib/openassets/protocol/transaction_output.rb +63 -2
- data/lib/openassets/transaction/transaction_builder.rb +4 -18
- data/lib/openassets/transaction/transfer_parameters.rb +12 -0
- data/lib/openassets/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4b3524d199fabcdbcb114a60fdc5ccb72537dfa
|
4
|
+
data.tar.gz: b6b4e4073d70fd1328c56758600de98bb702872c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/openassets/api.rb
CHANGED
@@ -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[
|
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
|
-
|
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.
|
34
|
-
|
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.
|
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.
|
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
|
data/lib/openassets/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2015-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bitcoin-ruby
|