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 +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
|