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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c08f34b042c6881e1117904400ed1fa066cf31f1
4
- data.tar.gz: b4c4cf4fec603d4e9f04786fae3afefd46666bbe
3
+ metadata.gz: 0d9eaa33fb43ddda93be8bb439718983f8595e41
4
+ data.tar.gz: af06b8d5bcd07f02d8351e398c6b7a8595a8ddff
5
5
  SHA512:
6
- metadata.gz: 406d2ecfc50fdc0d019188e12d56e0c9a1f286768220ae5bf5fce5a4a95702da91f79ebb816d0d2b4aca1c6a1c19d15afb0f4c452b94d61c657ac152ec13a227
7
- data.tar.gz: 12d8493b58fb45a00e1cd115ad1904bfc13dbfa1e31d0ce938706a8d265df7f818486485c210102af0c9c2c03c0507d03580ce74fae1b28c18d25614aae82674
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.
@@ -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
- result = parse_raw_data(raw_data, string)
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
- address_class = version_to_class_dictionary[version]
57
- if !address_class
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 address_class.new(string: _string, _raw_data: raw_data)
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
- def self.version_to_class_dictionary
146
- @version_to_class_dictionary ||= [
147
- PublicKeyAddress,
148
- ScriptHashAddress,
149
- WIF,
150
- AssetID,
151
- AssetAddress
152
- ].inject({}) do |dict, cls|
153
- dict[cls.mainnet_version] = cls
154
- dict[cls.testnet_version] = cls
155
- dict
156
- end
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.parse_raw_data(_raw_data[1..-1])
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 # "A" prefix
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
@@ -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'
@@ -1,3 +1,3 @@
1
1
  module BTC
2
- VERSION = "1.0.3".freeze
2
+ VERSION = "1.0.4".freeze
3
3
  end
data/lib/btcruby/wif.rb CHANGED
@@ -2,6 +2,8 @@ module BTC
2
2
  # Private key in Wallet Import Format (WIF aka Sipa format).
3
3
  # Examples: 5KQntKuhYWSRXNq... or L3p8oAcQTtuokSC...
4
4
  class WIF < Address
5
+
6
+ register_class self
5
7
 
6
8
  KEY_LENGTH = 32
7
9
 
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.3
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-06-09 00:00:00.000000000 Z
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