monacoin-openassets-ruby 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +11 -0
  7. data/CODE_OF_CONDUCT.md +13 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE +23 -0
  10. data/README.md +420 -0
  11. data/Rakefile +5 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +7 -0
  14. data/exe/monacoin-openassets +66 -0
  15. data/lib/monacoin-openassets.rb +23 -0
  16. data/lib/openassets/api.rb +423 -0
  17. data/lib/openassets/cache.rb +8 -0
  18. data/lib/openassets/cache/output_cache.rb +43 -0
  19. data/lib/openassets/cache/sqlite_base.rb +26 -0
  20. data/lib/openassets/cache/ssl_certificate_cache.rb +44 -0
  21. data/lib/openassets/cache/transaction_cache.rb +33 -0
  22. data/lib/openassets/error.rb +5 -0
  23. data/lib/openassets/medhod_filter.rb +55 -0
  24. data/lib/openassets/protocol.rb +10 -0
  25. data/lib/openassets/protocol/asset_definition.rb +118 -0
  26. data/lib/openassets/protocol/asset_definition_loader.rb +43 -0
  27. data/lib/openassets/protocol/http_asset_definition_loader.rb +27 -0
  28. data/lib/openassets/protocol/marker_output.rb +128 -0
  29. data/lib/openassets/protocol/output_type.rb +27 -0
  30. data/lib/openassets/protocol/transaction_output.rb +157 -0
  31. data/lib/openassets/provider.rb +7 -0
  32. data/lib/openassets/provider/api_error.rb +9 -0
  33. data/lib/openassets/provider/bitcoin_core_provider.rb +123 -0
  34. data/lib/openassets/provider/block_chain_provider_base.rb +22 -0
  35. data/lib/openassets/send_asset_param.rb +17 -0
  36. data/lib/openassets/send_bitcoin_param.rb +13 -0
  37. data/lib/openassets/transaction.rb +12 -0
  38. data/lib/openassets/transaction/dust_output_error.rb +10 -0
  39. data/lib/openassets/transaction/insufficient_asset_quantity_error.rb +7 -0
  40. data/lib/openassets/transaction/insufficient_funds_error.rb +10 -0
  41. data/lib/openassets/transaction/out_point.rb +22 -0
  42. data/lib/openassets/transaction/spendable_output.rb +38 -0
  43. data/lib/openassets/transaction/transaction_build_error.rb +9 -0
  44. data/lib/openassets/transaction/transaction_builder.rb +319 -0
  45. data/lib/openassets/transaction/transfer_parameters.rb +41 -0
  46. data/lib/openassets/util.rb +173 -0
  47. data/lib/openassets/version.rb +3 -0
  48. data/openassets-ruby.gemspec +38 -0
  49. metadata +246 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4b75062642096bd7e069c3cdfa3e6d88a573b808ec01a3ed7de91852d43a4aba
4
+ data.tar.gz: 7de23417640dd75d7d37755271bcc08b1a7c291bc2a046f8ae4d269374a82b16
5
+ SHA512:
6
+ metadata.gz: 87f179e2849bf5ec1565d15327e59a4d33068981e57b223dcb4f00cb34679a510803d3efbd8fa809170c7dad4ed509623312611ad297aa41e60a73d1d33a83ac
7
+ data.tar.gz: 416ba493cb0f5b54d570094be8955cef4d6f3d3c540c6bf07a1b32ff0adb525d3fc82676a858d541cad572d2939963a34222a8d133ec51de4d109b56a3a9e1ad
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea
11
+ *.iml
12
+ cache.db
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ openassets-ruby
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.0
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5.0
4
+ - 2.4.1
5
+ - 2.4.0
6
+ - 2.3.0
7
+
8
+ bundler_args: --jobs=2
9
+
10
+ script:
11
+ - bundle exec rake spec
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in openassets-ruby.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-2017 HAW International Inc.
4
+ Copyright (c) 2015-2017 azuchi
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
data/README.md ADDED
@@ -0,0 +1,420 @@
1
+ # openassets-ruby [![Build Status](https://travis-ci.org/haw-itn/openassets-ruby.svg?branch=master)](https://travis-ci.org/haw-itn/openassets-ruby) [![Gem Version](https://badge.fury.io/rb/openassets-ruby.svg)](https://badge.fury.io/rb/openassets-ruby) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
2
+ The implementation of the [Open Assets Protocol](https://github.com/OpenAssets/open-assets-protocol) for Ruby.
3
+
4
+ ## Install
5
+
6
+ ```ruby
7
+ gem install openassets-ruby
8
+ ```
9
+
10
+ ## Configuration
11
+
12
+ Initialize the connection information to the Bitcoin Core server.
13
+
14
+ * **use mainnet**
15
+
16
+ ```ruby
17
+ require 'openassets'
18
+
19
+ api = OpenAssets::Api.new({
20
+ network: 'mainnet',
21
+ provider: 'bitcoind',
22
+ cache: 'cache.db',
23
+ dust_limit: 600,
24
+ default_fees: 10000,
25
+ min_confirmation: 1,
26
+ max_confirmation: 9999999,
27
+ rpc: {
28
+ user: 'xxx',
29
+ password: 'xxx',
30
+ schema: 'http',
31
+ port: 8332,
32
+ host: 'localhost',
33
+ timeout: 60,
34
+ open_timeout: 60 }
35
+ })
36
+ ```
37
+
38
+ * **use testnet**
39
+
40
+ Change `network` and `port` depending on your server setting.
41
+
42
+ ```ruby
43
+ require 'openassets'
44
+
45
+ api = OpenAssets::Api.new({
46
+ network: 'testnet',
47
+ provider: 'bitcoind',
48
+ cache: 'testnet.db',
49
+ dust_limit: 600,
50
+ default_fees: 10000,
51
+ min_confirmation: 1,
52
+ max_confirmation: 9999999,
53
+ rpc: {
54
+ user: 'xxx',
55
+ password: 'xxx',
56
+ schema: 'http',
57
+ port: 18332,
58
+ host: 'localhost',
59
+ timeout: 60,
60
+ open_timeout: 60 }
61
+ })
62
+ ```
63
+
64
+ * **with [multi-wallet support](https://github.com/bitcoin/bitcoin/blob/0.15/doc/release-notes/release-notes-0.15.0.md#multi-wallet-support)**
65
+
66
+ From Bitcoin Core version 0.15 onwards, change `wallet` depending on wallet settings.
67
+
68
+ ```ruby
69
+ require 'openassets'
70
+
71
+ api = OpenAssets::Api.new({
72
+ network: 'testnet',
73
+ provider: 'bitcoind',
74
+ cache: 'testnet.db',
75
+ dust_limit: 600,
76
+ default_fees: 10000,
77
+ min_confirmation: 1,
78
+ max_confirmation: 9999999,
79
+ rpc: {
80
+ user: 'xxx',
81
+ password: 'xxx',
82
+ schema: 'http',
83
+ port: 18332,
84
+ host: 'localhost',
85
+ wallet: 'wallet.dat',
86
+ timeout: 60,
87
+ open_timeout: 60 }
88
+ })
89
+ ```
90
+
91
+ The configuration options are as follows:
92
+
93
+ |option|description|default|
94
+ |---|---|---|
95
+ |**network**|The using network. "mainnet" or "testnet" or "regtest" or "litecoin" or "litecoin_testnet" |mainnet|
96
+ |**provider**|The RPC server. "bitcoind" is the only option for now.|bitcoind|
97
+ |**cache**|The path to the database file. Specify `':memory:'` to use in-memory database.|cache.db|
98
+ |**dust_limit**|The amount of Bitcoin, which is set to the each output of the Open Assets Protocol (issue or transfer).|600 (satoshi)|
99
+ |**default_fees**|The default transaction fee in satoshi. Specify `:auto` to use auto fee settings. (used by issue_asset and send_asset, send_bitcoin )|10000 (satoshi)|
100
+ |**min_confirmation**|The minimum number of confirmations the transaction containing an output that used to get UTXO.|1|
101
+ |**max_confirmation**|The maximum number of confirmations the transaction containing an output that used to get UTXO.|9999999|
102
+ |**rpc**|The access information to the RPC server of Bitcoin Core.|N/A|
103
+
104
+ ### Using the API with multi-wallet support
105
+
106
+ To use the Bitcoin Core multi-wallet support ([version 0.15 onwards](https://github.com/bitcoin/bitcoin/blob/0.15/doc/release-notes/release-notes-0.15.0.md#multi-wallet-support)), you should use multiple instances of API, for example:
107
+
108
+ ```ruby
109
+ @apis = Hash.new
110
+ @apis[1] = OpenAssets::Api.new({
111
+ network: 'testnet',
112
+ provider: 'bitcoind',
113
+ cache: 'testnet.db',
114
+ dust_limit: 600,
115
+ default_fees: 10000,
116
+ min_confirmation: 1,
117
+ max_confirmation: 9999999,
118
+ rpc: {
119
+ user: 'xxx',
120
+ password: 'xxx',
121
+ schema: 'http',
122
+ port: 18332,
123
+ host: 'localhost',
124
+ wallet: 'wallet001.dat',
125
+ timeout: 60,
126
+ open_timeout: 60 }
127
+ })
128
+ @apis[2] = OpenAssets::Api.new({
129
+ network: 'testnet',
130
+ provider: 'bitcoind',
131
+ cache: 'testnet.db',
132
+ dust_limit: 600,
133
+ default_fees: 10000,
134
+ min_confirmation: 1,
135
+ max_confirmation: 9999999,
136
+ rpc: {
137
+ user: 'xxx',
138
+ password: 'xxx',
139
+ schema: 'http',
140
+ port: 18332,
141
+ host: 'localhost',
142
+ wallet: 'wallet002.dat',
143
+ timeout: 60,
144
+ open_timeout: 60 }
145
+ })
146
+ # More wallets perhaps...
147
+ # Then call API selectively
148
+ @apis[1].provider.list_unspent
149
+ @apis[2].provider.list_unspent
150
+ ```
151
+
152
+ ## API
153
+
154
+ Currently openassets-ruby support the following API.
155
+
156
+ * **list_unspent**
157
+ Returns an array of unspent transaction outputs, argument with the asset ID and quantity of each output.
158
+ ```ruby
159
+ # get all unspent outputs in the wallet.
160
+ api.list_unspent
161
+
162
+ # specify th open asset address.
163
+ api.list_unspent(['akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6'])
164
+
165
+ > [
166
+ {
167
+ "txid": "1610a1f62597a3ea36e09e78354be22d2a958c1a38ed9e5d3f1c2811ee82dc37",
168
+ "vout": 1,
169
+ "address": "1HhJs3JgbiyxC8ktfi6nU4wTqVmrMtCVkG",
170
+ "oa_address": "akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6",
171
+ "script": "76a914b7218fe503cd18555255e5b13d4f07f3fd00d0c988ac",
172
+ "amount": "0.00000600",
173
+ "confirmations": 8338,
174
+ "asset_id": "AWo3R89p5REmoSyMWB8AeUmud8456bRxZL",
175
+ "account": "openassets-ruby",
176
+ "asset_quantity": "67",
177
+ "asset_amount": "6.7",
178
+ "asset_definition_url": "http://goo.gl/fS4mEj",
179
+ "proof_of_authenticity": false
180
+ },
181
+ ...
182
+ ```
183
+ Output items are as follows.
184
+
185
+ |Item|description|
186
+ |:---|:---|
187
+ |txid|The TXID of the transaction containing the output.|
188
+ |address| A P2PKH or P2SH address.|
189
+ |oa_address|The Open Asset address.|
190
+ |script|The output script.|
191
+ |amount|The Bitcoin amount.|
192
+ |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. |
193
+ |asset_id|The asset ID is a 160 bits hash, used to uniquely identify the asset stored on the output.|
194
+ |account|The name of an account.|
195
+ |asset_quantity|The asset quantity is an unsigned integer representing how many units of that asset are stored on the output.|
196
+ |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. |
197
+ |asset_definition_url|The url of asset definition file.|
198
+ |proof_of_authenticity|The result of [Proof of Authenticity](https://github.com/OpenAssets/open-assets-protocol/blob/master/asset-definition-protocol.mediawiki#Proof_of_Authenticity) that is checked consistent with the subject in the SSL certificate. If the result is true, issuer is verified. If the result is false, issuer is not verified. This verification is performed only if link_to_website that is defined in Asset Definition File is true.|
199
+
200
+ * **get_balance**
201
+ Returns the balance in both bitcoin and colored coin assets for all of the addresses available in your Bitcoin Core wallet.
202
+ ```ruby
203
+ # get all balance in the wallet.
204
+ api.get_balance
205
+
206
+ # specify the open asset address.
207
+ api.get_balance('akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6')
208
+ > [
209
+ {
210
+ "address": "1HhJs3JgbiyxC8ktfi6nU4wTqVmrMtCVkG",
211
+ "oa_address": "akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6",
212
+ "value": "0.00018200",
213
+ "assets": [
214
+ {
215
+ "asset_id": "AWo3R89p5REmoSyMWB8AeUmud8456bRxZL",
216
+ "quantity": "81",
217
+ "amount": "20.7",
218
+ "asset_definition_url": "http://goo.gl/fS4mEj",
219
+ "proof_of_authenticity": false
220
+ },
221
+ {
222
+ "asset_id": "AJk2Gx5V67S2wNuwTK5hef3TpHunfbjcmX",
223
+ "quantity": "67",
224
+ "amount": "6.7",
225
+ "asset_definition_url": "",
226
+ "proof_of_authenticity": false
227
+ }
228
+ ],
229
+ "account": "openassets-ruby"
230
+ },
231
+ ```
232
+ Output items are as follows.
233
+
234
+ |Item|description|
235
+ |:---|:---|
236
+ |address| A P2PKH or P2SH address.|
237
+ |oa_address|The Open Asset address.|
238
+ |value|The Bitcoin amount.|
239
+ |assets|The array of the assets.|
240
+ |asset_id|The asset ID is a 160 bits hash, used to uniquely identify the asset stored on the output.|
241
+ |asset_quantity|The asset quantity is an unsigned integer representing how many units of that asset are stored on the output.|
242
+ |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. |
243
+ |asset_definition_url|The url of asset definition file.|
244
+ |proof_of_authenticity|The result of [Proof of Authenticity](https://github.com/OpenAssets/open-assets-protocol/blob/master/asset-definition-protocol.mediawiki#Proof_of_Authenticity) that is checked consistent with the subject in the SSL certificate. If the result is true, issuer is verified. If the result is false, issuer is not verified. This verification is performed only if link_to_website that is defined in Asset Definition File is true.|
245
+ |account|The name of an account.|
246
+
247
+ * **issue_asset**
248
+ Creates a transaction for issuing an asset.
249
+ ```ruby
250
+ # issue asset
251
+ # api.issue_asset(<issuer open asset address>,
252
+ # <issuing asset quantity>,
253
+ # <metadata>,
254
+ # <to open asset address>,
255
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
256
+ # <mode=('broadcast', 'signed', 'unsigned')>,
257
+ # <output_qty default value is 1.>)
258
+
259
+ # example
260
+ address = 'akEJwzkzEFau4t2wjbXoMs7MwtZkB8xixmH'
261
+ api.issue_asset(address, 150, 'u=https://goo.gl/bmVEuw', address, nil, 'broadcast')
262
+ ```
263
+ If specified ``output_qty``, the issue output is divided by the number of output_qty.
264
+ For example, amount = 125 and output_qty = 2, the marker output asset quantity is [62, 63] and issue TxOut is two.
265
+
266
+ * **send_asset**
267
+ Creates a transaction for sending an asset from the open asset address to another.
268
+ ```ruby
269
+ # send asset
270
+ # api.send_asset(<from open asset address>,
271
+ # <asset ID>,
272
+ # <asset quantity>,
273
+ # <to open asset address>,
274
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
275
+ # <mode=('broadcast', 'signed', 'unsigned')>,
276
+ # <output_qty default value is 1.>)
277
+
278
+ # example
279
+ from = 'akXDPMMHHBrUrd1fM756M1GSB8viVAwMyBk'
280
+ to = 'akTfC7D825Cse4NvFiLCy7vr3B6x2Mpq8t6'
281
+ api.send_asset(from, 'AWo3R89p5REmoSyMWB8AeUmud8456bRxZL', 100, to, 10000, 'broadcast')
282
+ ```
283
+ If specified ``output_qty``, the send output is divided by the number of output_qty.
284
+ 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.
285
+
286
+ * **send_bitcoin**
287
+ Creates a transaction for sending bitcoins from an address to another.
288
+ This transaction inputs use only uncolored outputs.
289
+ ```ruby
290
+ # send bitcoin
291
+ # api.send_bitcoin(<from btc address>,
292
+ # <amount (satoshi)>,
293
+ # <to btc address>,
294
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
295
+ # <mode=('broadcast', 'signed', 'unsigned')>,
296
+ # <output_qty default value is 1.>)
297
+
298
+ # example
299
+ from = '14M4kbAtn71P1nnNYuhBDFTNYxa19t1XP6'
300
+ to = '1MFW7BTwiNbAkmVz4SzAMQXboKYKGSzkq2'
301
+ api.send_bitcoin(from, 60000, to)
302
+ ```
303
+ If specified ``output_qty``, the send output is divided by the number of output_qty.
304
+ Ex, amount = 60000 and output_qty = 2, send TxOut is two (each value is 30000, 30000) and change TxOut one.
305
+
306
+ * **get_outputs_from_txid**
307
+ Get tx outputs. (use for debug)
308
+ ```ruby
309
+ # api.get_outputs_from_txid(<txid>, <use_cache default value is false.>)
310
+
311
+ # example
312
+ api.get_outputs_from_txid('3fba8bfb157ae29c293d5bd65c178fec169a87f880e2e62537fcce26612a6aa3')
313
+ > [{
314
+ "address": "14M4kbAtn71P1nnNYuhBDFTNYxa19t1XP6",
315
+ "oa_address": "akEJwzkzEFau4t2wjbXoMs7MwtZkB8xixmH",
316
+ "script": "76a91424b3d405bc60bd9628691fe28bb00f6800e1480688ac",
317
+ "amount": "0.00000600",
318
+ "asset_id": "AWo3R89p5REmoSyMWB8AeUmud8456bRxZL",
319
+ "asset_quantity": "1",
320
+ "asset_amount": "1",
321
+ "account": null,
322
+ "asset_definition_url": "",
323
+ "txid": "3fba8bfb157ae29c293d5bd65c178fec169a87f880e2e62537fcce26612a6aa3",
324
+ "vout": 1
325
+ },..
326
+ ```
327
+
328
+ * **send_assets**
329
+ Creates a transaction for sending **multiple** asset from the open asset address(es) to another.
330
+ `<from open asset address>` is used to send bitcoins **if** needed, and receive bitcoin change **if** any.
331
+ ```ruby
332
+ # send assets
333
+ # api.send_assets(<from open asset address>,
334
+ # <The array of send Asset information(see OpenAssets::SendAssetParam).>,
335
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
336
+ # <mode=('broadcast', 'signed', 'unsigned')>,
337
+ # <output_qty default value is 1.>)
338
+
339
+ # example
340
+ from = api.address_to_oa_address('mrxpeizRrF8ymNx5FrvcGGZVecZjtUFVP3')
341
+ to = api.address_to_oa_address('n4MEsSUN8GktDFZzU3V55mP3jWGMN7e4wE')
342
+ params = []
343
+ params << OpenAssets::SendAssetParam.new('oGu4VXx2TU97d9LmPP8PMCkHckkcPqC5RY', 50, to)
344
+ params << OpenAssets::SendAssetParam.new('oUygwarZqNGrjDvcZUpZdvEc7es6dcs1vs', 4, to)
345
+ tx = api.send_assets(from, params)
346
+
347
+ # send assets from multiple addresses.
348
+ change_address = 'mwxeANpckdbdgZCpUMTceQhbbhLPJiqpfD'
349
+ from = [
350
+ api.address_to_oa_address("mrxpeizRrF8ymNx5FrvcGGZVecZjtUFVP3"),
351
+ api.address_to_oa_address("mvYbB238p3rFYFjM56cHhNNHeQb5ypQJ3T")
352
+ ]
353
+ to = api.address_to_oa_address('n4MEsSUN8GktDFZzU3V55mP3jWGMN7e4wE')
354
+ params = []
355
+ params << OpenAssets::SendAssetParam.new('oGu4VXx2TU97d9LmPP8PMCkHckkcPqC5RY', 100, to, from[0])
356
+ params << OpenAssets::SendAssetParam.new('oUygwarZqNGrjDvcZUpZdvEc7es6dcs1vs', 100, to, from[1])
357
+ tx = api.send_assets(change_address, params)
358
+ ```
359
+
360
+ * **send_bitcoins**
361
+ Creates a transaction for sending **multiple** bitcoins from an address to others.
362
+ This transaction inputs use only uncolored outputs.
363
+ ```ruby
364
+ # send bitcoins
365
+ # api.send_bitcoins(<from btc address>,
366
+ # <The array of send bitcoin information(see OpenAssets::SendBitcoinParam).>,
367
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
368
+ # <mode=('broadcast', 'signed', 'unsigned')>,
369
+ # <output_qty default value is 1.>)
370
+
371
+ # example
372
+ from = 'mrxpeizRrF8ymNx5FrvcGGZVecZjtUFVP3'
373
+ to1 = 'n4MEsSUN8GktDFZzU3V55mP3jWGMN7e4wE'
374
+ to2 = 'mvYbB238p3rFYFjM56cHhNNHeQb5ypQJ3T'
375
+ params = []
376
+ params << OpenAssets::SendBitcoinParam.new(50000, to1)
377
+ params << OpenAssets::SendBitcoinParam.new(3000, to2)
378
+ tx = api.send_bitcoins(from, params)
379
+ ```
380
+
381
+
382
+ * **burn_asset**
383
+ Creates a transaction for burn asset.
384
+ This API is to burn the asset by spending the all UTXO of specified asset as Bitcoin.
385
+ ```ruby
386
+ # burn_asset
387
+ # api.burn_asset(<from open asset address>,
388
+ # <asset ID>,
389
+ # <fees (The fess in satoshis for the transaction. use 10000 satoshi if specified nil)>,
390
+ # <mode=('broadcast', 'signed', 'unsigned')>
391
+
392
+ # example
393
+ oa_address = 'bX2vhttomKj2fdd7SJV2nv8U4zDjusE5Y4B'
394
+ asset_id = 'oGu4VXx2TU97d9LmPP8PMCkHckkcPqC5RY'
395
+ tx = api.burn_asset(oa_address, asset_id)
396
+ ```
397
+
398
+ **Note:** Burnt asset will be lost forever.
399
+
400
+ ## Command line interface
401
+
402
+ Openassets-ruby comes with a `openassets` command line interface that allows easy interaction with OpenAssets.
403
+
404
+ ### Usage
405
+
406
+ openassets [options] [command]
407
+
408
+ Options:
409
+ -c path to config JSON which is passed to OpenAssets::Api.new - see Configuration for details
410
+ -e load config from ENV variables (look at the exe/openassets file for details)
411
+
412
+ commands:
413
+ * console runs an IRB console and gives you an initialized API instance to interact with OpenAssets
414
+ * any method on the API instance, helpful for get_balance, list_unspent
415
+
416
+
417
+
418
+ ## License
419
+
420
+ openassets-ruby is licensed under the [MIT License](LICENSE).