btcruby 1.0.3 → 1.0.4

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 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