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 +4 -4
- data/README.md +17 -1
- data/lib/openassets/api.rb +18 -0
- data/lib/openassets/protocol/marker_output.rb +1 -1
- data/lib/openassets/transaction/insufficient_asset_quantity_error.rb +7 -0
- data/lib/openassets/transaction/transaction_builder.rb +73 -4
- data/lib/openassets/transaction.rb +1 -0
- data/lib/openassets/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ead0fb7292a8d56c01d8894f5bc693e05ae0f8fe
|
4
|
+
data.tar.gz: 4ffbc89805cfc72986233c5cdb1e34ea38bb3186
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/lib/openassets/api.rb
CHANGED
@@ -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
|
@@ -11,11 +11,11 @@ module OpenAssets
|
|
11
11
|
@amount = amount
|
12
12
|
end
|
13
13
|
|
14
|
-
#
|
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
|
-
|
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
|
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.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-
|
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
|