openassets-ruby 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|