btcruby 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/RELEASE_NOTES.md +30 -0
- data/lib/btcruby/address.rb +47 -23
- data/lib/btcruby/open_assets/asset_address.rb +4 -1
- data/lib/btcruby/open_assets/asset_id.rb +3 -2
- data/lib/btcruby/open_assets/issuance_id.rb +29 -0
- data/lib/btcruby/open_assets.rb +1 -0
- data/lib/btcruby/version.rb +1 -1
- data/lib/btcruby/wif.rb +2 -0
- data/spec/address_spec.rb +1 -1
- data/spec/open_assets/issuance_id_spec.rb +16 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d9eaa33fb43ddda93be8bb439718983f8595e41
|
4
|
+
data.tar.gz: af06b8d5bcd07f02d8351e398c6b7a8595a8ddff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f50ec59b1e00e03cf6d23de427ee7b3a50058be67f4931fb9db7b400eee94d54ad58fb8abc66f5337a0960d31efcd010abb276a7a779ef5496a7f489d3d7df4
|
7
|
+
data.tar.gz: 444b559fcbf592eda67d82326510e2433810639b0530d55afdffdf241836d34396221c3fbdea1086c302c9063fe07b7dd2fa38412edcd4eeaf32d5289de8cba5
|
data/RELEASE_NOTES.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
BTCRuby Release Notes
|
3
|
+
=====================
|
4
|
+
|
5
|
+
1.0.4 (July 2, 2015)
|
6
|
+
--------------------
|
7
|
+
|
8
|
+
* Added `register_class` API to extend `BTC::Address` with custom subclasses.
|
9
|
+
* Added `IssuanceID` class to identify unique issuance outputs of any asset (so this can be used as a "issue-once" identifier). Support for `issuance_id` in processor is pending.
|
10
|
+
|
11
|
+
1.0.3 (June 9, 2015)
|
12
|
+
--------------------
|
13
|
+
|
14
|
+
* BTC::Data methods made available as methods on BTC object (`BTC::Data.data_from_hex` -> `BTC.from_hex` etc.)
|
15
|
+
|
16
|
+
1.0.2 (June 9, 2015)
|
17
|
+
--------------------
|
18
|
+
|
19
|
+
* Added `Keychain#to_s` (returns `xpub` or `xprv`).
|
20
|
+
* API cleanup.
|
21
|
+
|
22
|
+
1.0.1 (June 9, 2015)
|
23
|
+
--------------------
|
24
|
+
|
25
|
+
* Fixed support for HMAC functions for Ruby 2.2.
|
26
|
+
|
27
|
+
1.0.0 (June 8, 2015)
|
28
|
+
--------------------
|
29
|
+
|
30
|
+
* First public release.
|
data/lib/btcruby/address.rb
CHANGED
@@ -27,7 +27,8 @@
|
|
27
27
|
#
|
28
28
|
module BTC
|
29
29
|
class Address
|
30
|
-
|
30
|
+
@@registered_classes = []
|
31
|
+
|
31
32
|
# Decodes address from a Base58Check-encoded string
|
32
33
|
def self.parse(string_or_address)
|
33
34
|
raise ArgumentError, "Argument is missing" if !string_or_address
|
@@ -39,27 +40,46 @@ module BTC
|
|
39
40
|
string = string_or_address
|
40
41
|
raise ArgumentError, "String is expected" if !string.is_a?(String)
|
41
42
|
raw_data = Base58.data_from_base58check(string)
|
42
|
-
|
43
|
+
self.mux_parse_raw_data(raw_data, string)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Attempts to parse with a proper subclass
|
47
|
+
def self.mux_parse_raw_data(raw_data, _string = nil)
|
48
|
+
result = nil
|
49
|
+
@@registered_classes.each do |cls|
|
50
|
+
if result = cls.parse_raw_data(raw_data, _string)
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
if !result
|
55
|
+
raise ArgumentError, "Unknown kind of address: #{_string}. Registered types: #{@@registered_classes}"
|
56
|
+
end
|
43
57
|
if !result.is_a?(self)
|
44
58
|
raise ArgumentError, "Argument must be an instance of #{self}, not #{result.class}."
|
45
59
|
end
|
46
|
-
result
|
60
|
+
return result
|
47
61
|
end
|
48
62
|
|
49
63
|
# Internal method to parse address from raw binary data.
|
64
|
+
# Subclasses should implement to return a valid instance or nil if the provided data does not correspond to that subclass.
|
65
|
+
# Default implementation assumes 1-byte version prefix and implementation of mainnet_version and testnet_version class methods.
|
50
66
|
def self.parse_raw_data(raw_data, _string = nil)
|
51
67
|
raise ArgumentError, "Raw data is missing" if !raw_data
|
52
68
|
if raw_data.bytesize < 2 # should contain at least a version byte and some content
|
53
69
|
raise FormatError, "Failed to decode BTC::Address: raw data is too short"
|
54
70
|
end
|
55
71
|
version = raw_data.bytes.first
|
56
|
-
|
57
|
-
|
58
|
-
raise FormatError, "Failed to decode BTC::Address: unknown version #{version}"
|
72
|
+
if self.mainnet_version == version || self.testnet_version == version
|
73
|
+
return self.new(string: _string, _raw_data: raw_data)
|
59
74
|
end
|
60
|
-
return
|
75
|
+
return nil
|
61
76
|
end
|
62
|
-
|
77
|
+
|
78
|
+
# Subclasses should register themselves so they can be parsed via BTC::Address.parse()
|
79
|
+
def self.register_class(cls)
|
80
|
+
@@registered_classes << cls
|
81
|
+
end
|
82
|
+
|
63
83
|
def network
|
64
84
|
@network ||= if !@version
|
65
85
|
BTC::Network.default
|
@@ -140,21 +160,21 @@ module BTC
|
|
140
160
|
raise Exception, "Override data_for_base58check_encoding in #{self.class} to return complete data to be base58-encoded."
|
141
161
|
end
|
142
162
|
|
143
|
-
private
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
163
|
+
# private
|
164
|
+
# def self.version_to_class_dictionary
|
165
|
+
# @version_to_class_dictionary ||= [
|
166
|
+
# PublicKeyAddress,
|
167
|
+
# ScriptHashAddress,
|
168
|
+
# WIF,
|
169
|
+
# AssetID,
|
170
|
+
# IssuanceID,
|
171
|
+
# AssetAddress,
|
172
|
+
# ].inject({}) do |dict, cls|
|
173
|
+
# dict[cls.mainnet_version] = cls
|
174
|
+
# dict[cls.testnet_version] = cls
|
175
|
+
# dict
|
176
|
+
# end
|
177
|
+
# end
|
158
178
|
end
|
159
179
|
|
160
180
|
class BitcoinPaymentAddress < Address
|
@@ -201,6 +221,8 @@ module BTC
|
|
201
221
|
|
202
222
|
# Standard pulic key (P2PKH) address (e.g. 19FGfswVqxNubJbh1NW8A4t51T9x9RDVWQ)
|
203
223
|
class PublicKeyAddress < Hash160Address
|
224
|
+
|
225
|
+
register_class self
|
204
226
|
|
205
227
|
def self.mainnet_version
|
206
228
|
0
|
@@ -236,6 +258,8 @@ module BTC
|
|
236
258
|
# P2SH address (e.g. 3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8)
|
237
259
|
class ScriptHashAddress < Hash160Address
|
238
260
|
|
261
|
+
register_class self
|
262
|
+
|
239
263
|
def self.mainnet_version
|
240
264
|
5
|
241
265
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module BTC
|
2
2
|
# Represents an Asset Address, where the assets can be sent.
|
3
3
|
class AssetAddress < BTC::Address
|
4
|
+
|
5
|
+
register_class self
|
6
|
+
|
4
7
|
NAMESPACE = 0x13
|
5
8
|
|
6
9
|
def self.mainnet_version
|
@@ -18,7 +21,7 @@ module BTC
|
|
18
21
|
_raw_data ||= Base58.data_from_base58check(string)
|
19
22
|
raise FormatError, "Too short AssetAddress" if _raw_data.bytesize < 2
|
20
23
|
raise FormatError, "Invalid namespace for AssetAddress" if _raw_data.bytes[0] != NAMESPACE
|
21
|
-
@bitcoin_address = Address.
|
24
|
+
@bitcoin_address = BTC::Address.mux_parse_raw_data(_raw_data[1..-1])
|
22
25
|
@base58check_string = string
|
23
26
|
elsif bitcoin_address
|
24
27
|
@base58check_string = nil
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module BTC
|
2
2
|
# Represents an Asset ID.
|
3
3
|
class AssetID < BTC::Hash160Address
|
4
|
+
register_class self
|
4
5
|
|
5
6
|
def self.mainnet_version
|
6
|
-
23 #
|
7
|
+
23 # 'A' prefix
|
7
8
|
end
|
8
9
|
|
9
10
|
def self.testnet_version
|
10
|
-
115
|
11
|
+
115 # 'o' prefix
|
11
12
|
end
|
12
13
|
|
13
14
|
# Instantiates AssetID with output, output script or raw hash.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module BTC
|
2
|
+
# Represents a distinct issuance of any given asset.
|
3
|
+
# Hash160(tx hash || txout index || amount)
|
4
|
+
class IssuanceID < BTC::Hash160Address
|
5
|
+
|
6
|
+
register_class self
|
7
|
+
|
8
|
+
def self.mainnet_version
|
9
|
+
63 # 'S' prefix ('single', 'issuance')
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.testnet_version
|
13
|
+
125 # 's' prefix
|
14
|
+
end
|
15
|
+
|
16
|
+
# Instantiates AssetID with output, output script or raw hash.
|
17
|
+
# To compute an Asset ID for the Asset Definition file, use `trim_script_prefix: true`.
|
18
|
+
def initialize(string: nil, hash: nil, network: nil, outpoint: nil, amount: nil, _raw_data: nil)
|
19
|
+
if outpoint || amount
|
20
|
+
raise ArgumentError, "Outpoint is missing" if !outpoint
|
21
|
+
raise ArgumentError, "Amount is missing" if !amount || amount < 0
|
22
|
+
data = outpoint.transaction_hash + WireFormat.encode_uint32le(outpoint.index) + WireFormat.encode_uint64le(amount)
|
23
|
+
super(hash: BTC.hash160(data), network: network)
|
24
|
+
else
|
25
|
+
super(string: string, hash: hash, network: network, _raw_data: _raw_data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/btcruby/open_assets.rb
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
# * Supporting stock split (AssetV2 is issued by consuming AssetV1, validating software must validate AssetV2 accordingly).
|
16
16
|
# * Supporting key rotation (can be done using the same technique as with stock split). Maybe use metadata to link to a previous asset.
|
17
17
|
require_relative 'open_assets/asset_id.rb'
|
18
|
+
require_relative 'open_assets/issuance_id.rb'
|
18
19
|
require_relative 'open_assets/asset_address.rb'
|
19
20
|
require_relative 'open_assets/asset.rb'
|
20
21
|
require_relative 'open_assets/asset_marker.rb'
|
data/lib/btcruby/version.rb
CHANGED
data/lib/btcruby/wif.rb
CHANGED
data/spec/address_spec.rb
CHANGED
@@ -193,7 +193,7 @@ describe BTC::Address do
|
|
193
193
|
asset_addr_string = "akB4NBW9UuCmHuepksob6yfZs6naHtRCPNy"
|
194
194
|
btc_addr = Address.parse(btc_addr_string)
|
195
195
|
asset_addr = Address.parse(asset_addr_string)
|
196
|
-
|
196
|
+
|
197
197
|
->{ BTC::AssetAddress.parse(btc_addr_string) }.must_raise ArgumentError
|
198
198
|
->{ BTC::AssetAddress.parse(btc_addr) }.must_raise ArgumentError
|
199
199
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe BTC::IssuanceID do
|
4
|
+
it "should encode script to a correct address" do
|
5
|
+
key = Key.new(private_key: "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725".from_hex, public_key_compressed: false)
|
6
|
+
issuance_id = IssuanceID.new(outpoint: TransactionOutpoint.new(transaction_hash: BTC.hash256("tx1"), index:0), amount:100, network: Network.mainnet)
|
7
|
+
issuance_id.hash.to_hex.must_equal "5e398b12cce30c0e1550e29f9d1b8f024772ac69"
|
8
|
+
issuance_id.to_s.must_equal "SVtDV3pMkQQu11CQMzsziCmFBx4Ff5FnPT"
|
9
|
+
issuance_id.is_a?(BTC::IssuanceID).must_equal true
|
10
|
+
end
|
11
|
+
it "should decode an asset address" do
|
12
|
+
issuance_id = Address.parse("SVtDV3pMkQQu11CQMzsziCmFBx4Ff5FnPT")
|
13
|
+
issuance_id.is_a?(BTC::IssuanceID).must_equal true
|
14
|
+
issuance_id.hash.to_hex.must_equal "5e398b12cce30c0e1550e29f9d1b8f024772ac69"
|
15
|
+
end
|
16
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: btcruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleg Andreev
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- HOWTO.md
|
45
45
|
- LICENSE
|
46
46
|
- README.md
|
47
|
+
- RELEASE_NOTES.md
|
47
48
|
- Rakefile
|
48
49
|
- TODO.txt
|
49
50
|
- bin/console
|
@@ -107,6 +108,7 @@ files:
|
|
107
108
|
- lib/btcruby/open_assets/asset_transaction_builder/result.rb
|
108
109
|
- lib/btcruby/open_assets/asset_transaction_input.rb
|
109
110
|
- lib/btcruby/open_assets/asset_transaction_output.rb
|
111
|
+
- lib/btcruby/open_assets/issuance_id.rb
|
110
112
|
- lib/btcruby/openssl.rb
|
111
113
|
- lib/btcruby/proof_of_work.rb
|
112
114
|
- lib/btcruby/safety.rb
|
@@ -145,6 +147,7 @@ files:
|
|
145
147
|
- spec/open_assets/asset_processor_spec.rb
|
146
148
|
- spec/open_assets/asset_transaction_builder_spec.rb
|
147
149
|
- spec/open_assets/asset_transaction_spec.rb
|
150
|
+
- spec/open_assets/issuance_id_spec.rb
|
148
151
|
- spec/proof_of_work_spec.rb
|
149
152
|
- spec/script_spec.rb
|
150
153
|
- spec/spec_helper.rb
|