btcruby 1.0.6 → 1.0.7

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: 4b9b9d085300b3e99129f1512fa8b0b7794a4aa4
4
- data.tar.gz: 7fc8e5d75b7518afd548c7c5dbf49b7c98ec7f7a
3
+ metadata.gz: f1937e58fcda56495863a298341de0e58def9807
4
+ data.tar.gz: 4b1dab008f068d52b3bfd69dc7816c03c3fd05aa
5
5
  SHA512:
6
- metadata.gz: 408fcbdd2fdc406a450382dcce2c86744a7c718f5a4d770a3a7c714f56a28b674d51a450968a2af857bac8c8390f37438efc8db8ef6e5003dc35a4623b3d5204
7
- data.tar.gz: 48b073e59fa89922faa469dff926beff3261ef762270efd18de1ba31aabb5506ff84d7297d582192d392d7daee4fec7bb284ee04e0d5445e920dd9df62ead358
6
+ metadata.gz: 1f73e371b4252cd9b0a16db3fc68dbcba11122dd4dd4e9fa7dc95468d3c438c82ac8463d5b63632d58ad037a3fc81f55640111eda88792f80cb28a8961c11eba
7
+ data.tar.gz: 09f11c01667ca03872e1de72a676d454803742538f02822b8a599985768c68287a40e5fe8087083186cb3613f76039c4aef41a759b5aff3fcb1cbfe0470e7eb5
data/RELEASE_NOTES.md CHANGED
@@ -2,6 +2,13 @@
2
2
  BTCRuby Release Notes
3
3
  =====================
4
4
 
5
+ 1.0.7 (July 19, 2015)
6
+ --------------------
7
+
8
+ * Script `subscript` and `find_and_delete` APIs.
9
+ * Fixed block parsing API (list of transactions was always empty).
10
+ * Added OP_CHECKLOCKTIMEVERIFY.
11
+
5
12
  1.0.6 (July 13, 2015)
6
13
  --------------------
7
14
 
data/lib/btcruby/block.rb CHANGED
@@ -82,7 +82,7 @@ module BTC
82
82
  time: nil,
83
83
  bits: 0,
84
84
  nonce: 0,
85
- transactions: [],
85
+ transactions: nil,
86
86
 
87
87
  # optional attributes
88
88
  height: nil,
@@ -103,6 +103,7 @@ module BTC
103
103
  )
104
104
 
105
105
  @transactions = transactions if transactions
106
+ @transactions ||= []
106
107
  end
107
108
 
108
109
  def init_with_stream(stream)
@@ -179,6 +179,7 @@ module BTC
179
179
  # Expansion
180
180
  OP_NOP1 = 0xb0
181
181
  OP_NOP2 = 0xb1
182
+ OP_CHECKLOCKTIMEVERIFY = OP_NOP2 # See BIP65
182
183
  OP_NOP3 = 0xb2
183
184
  OP_NOP4 = 0xb3
184
185
  OP_NOP5 = 0xb4
@@ -238,7 +238,7 @@ module BTC
238
238
  # and a new script instance is returned.
239
239
  def without_dropped_prefix_data
240
240
  if dropped_prefix_data
241
- return Script.new << @chunks[2..-1]
241
+ return self.class.new << @chunks[2..-1]
242
242
  end
243
243
  self
244
244
  end
@@ -278,7 +278,7 @@ module BTC
278
278
 
279
279
  # Complete copy of a script.
280
280
  def dup
281
- BTC::Script.new(data: self.data)
281
+ self.class.new(data: self.data)
282
282
  end
283
283
 
284
284
  def ==(other)
@@ -314,7 +314,7 @@ module BTC
314
314
  # Wraps the recipient into an output P2SH script
315
315
  # (OP_HASH160 <20-byte hash of the recipient> OP_EQUAL).
316
316
  def p2sh_script
317
- Script.new << OP_HASH160 << BTC.hash160(self.data) << OP_EQUAL
317
+ self.class.new << OP_HASH160 << BTC.hash160(self.data) << OP_EQUAL
318
318
  end
319
319
 
320
320
 
@@ -326,18 +326,18 @@ module BTC
326
326
  def simulated_signature_script(strict: true)
327
327
  if public_key_hash_script?
328
328
  # assuming non-compressed pubkeys to be conservative
329
- return Script.new << Script.simulated_signature(hashtype: SIGHASH_ALL) << Script.simulated_uncompressed_pubkey
329
+ return self.class.new << Script.simulated_signature(hashtype: SIGHASH_ALL) << Script.simulated_uncompressed_pubkey
330
330
 
331
331
  elsif public_key_script?
332
- return Script.new << Script.simulated_signature(hashtype: SIGHASH_ALL)
332
+ return self.class.new << Script.simulated_signature(hashtype: SIGHASH_ALL)
333
333
 
334
334
  elsif script_hash_script? && !strict
335
335
  # This is a wild approximation, but works well if most p2sh scripts are 2-of-3 multisig scripts.
336
336
  # If you have a very particular smart contract scheme you should not use TransactionBuilder which estimates fees this way.
337
- return Script.new << OP_0 << [Script.simulated_signature(hashtype: SIGHASH_ALL)]*2 << Script.simulated_multisig_script(2,3).data
337
+ return self.class.new << OP_0 << [Script.simulated_signature(hashtype: SIGHASH_ALL)]*2 << Script.simulated_multisig_script(2,3).data
338
338
 
339
339
  elsif multisig_script?
340
- return Script.new << OP_0 << [Script.simulated_signature(hashtype: SIGHASH_ALL)]*self.multisig_signatures_required
340
+ return self.class.new << OP_0 << [Script.simulated_signature(hashtype: SIGHASH_ALL)]*self.multisig_signatures_required
341
341
  else
342
342
  return nil
343
343
  end
@@ -360,7 +360,7 @@ module BTC
360
360
 
361
361
  # Returns a dummy script that simulates m-of-n multisig script
362
362
  def self.simulated_multisig_script(m,n)
363
- Script.new <<
363
+ self.new <<
364
364
  Opcode.opcode_for_small_integer(m) <<
365
365
  [simulated_uncompressed_pubkey]*n << # assuming non-compressed pubkeys to be conservative
366
366
  Opcode.opcode_for_small_integer(n) <<
@@ -384,9 +384,9 @@ module BTC
384
384
  # Appends a pushdata opcode with the most compact encoding.
385
385
  # Optional opcode may be equal to OP_PUSHDATA1, OP_PUSHDATA2, or OP_PUSHDATA4.
386
386
  # ArgumentError is raised if opcode does not represent a given data length.
387
- def append_pushdata(pushdata, opcode: nil)
388
- raise ArgumentError, "No pushdata is given" if !pushdata
389
- encoded_pushdata = self.class.encode_pushdata(pushdata, opcode: opcode)
387
+ def append_pushdata(data, opcode: nil)
388
+ raise ArgumentError, "No data provided" if !data
389
+ encoded_pushdata = self.class.encode_pushdata(data, opcode: opcode)
390
390
  if !encoded_pushdata
391
391
  raise ArgumentError, "Cannot encode pushdata with opcode #{opcode}"
392
392
  end
@@ -433,11 +433,7 @@ module BTC
433
433
  self << element
434
434
  end
435
435
  elsif object.is_a?(Chunk)
436
- if object.pushdata?
437
- append_pushdata(object.pushdata)
438
- else
439
- append_opcode(object.opcode)
440
- end
436
+ @chunks << object
441
437
  else
442
438
  raise ArgumentError, "Operand must be an integer, a string a BTC::Script instance or an array of any of those."
443
439
  end
@@ -449,9 +445,40 @@ module BTC
449
445
  self.dup << other
450
446
  end
451
447
 
452
-
453
-
454
-
448
+ # Same arguments as with Array#[].
449
+ def subscript(*args)
450
+ self.class.new << chunks[*args]
451
+ end
452
+ alias_method :[], :subscript
453
+
454
+ # Removes chunks matching subscript byte-for-byte and returns a new script instance with subscript removed.
455
+ # So if pushdata items are encoded differently, they won't match.
456
+ # Consensus-critical code.
457
+ def find_and_delete(subscript)
458
+ subscript.is_a?(Script) or raise ArgumentError,"Argument must be an instance of BTC::Script"
459
+ # Replacing [a b a]
460
+ # Script: a b b a b a b a c
461
+ # Result: a b b b a c
462
+ subscriptsize = subscript.chunks.size
463
+ buf = []
464
+ i = 0
465
+ result = self.class.new
466
+ chunks.each do |chunk|
467
+ if chunk == subscript.chunks[i]
468
+ buf << chunk
469
+ i+=1
470
+ if i == subscriptsize # matched the whole subscript
471
+ i = 0
472
+ buf.clear
473
+ end
474
+ else
475
+ i = 0
476
+ result << buf
477
+ result << chunk
478
+ end
479
+ end
480
+ result
481
+ end
455
482
 
456
483
 
457
484
  # Private API
@@ -708,6 +735,10 @@ module BTC
708
735
  @raw_data = raw_data
709
736
  end
710
737
 
738
+ def ==(other)
739
+ @raw_data == other.raw_data
740
+ end
741
+
711
742
  protected
712
743
 
713
744
  def data_is_ascii_printable?(data)
@@ -1,3 +1,3 @@
1
1
  module BTC
2
- VERSION = "1.0.6".freeze
2
+ VERSION = "1.0.7".freeze
3
3
  end
data/spec/script_spec.rb CHANGED
@@ -62,5 +62,33 @@ describe BTC::Script do
62
62
 
63
63
  end
64
64
 
65
+ it "should support subscripts" do
66
+ s = Script.new << OP_DUP << OP_HASH160 << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG
67
+ s.subscript(0..-1).must_equal s
68
+ s[0..-1].must_equal s
69
+ s.subscript(3..-1).must_equal(Script.new << "some data" << OP_EQUALVERIFY << OP_CHECKSIG)
70
+ s[3..-1].must_equal(Script.new << "some data" << OP_EQUALVERIFY << OP_CHECKSIG)
71
+ end
72
+
73
+
74
+ it "removing subscript does not modify receiver" do
75
+ s = Script.new << OP_DUP << OP_HASH160 << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG
76
+ s1 = s.dup
77
+ s2 = s1.find_and_delete(Script.new << OP_HASH160)
78
+ s.must_equal s1
79
+ s2.must_equal(Script.new << OP_DUP << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG)
80
+ end
81
+
82
+ it "should find subsequence" do
83
+ s = Script.new << OP_1 << OP_3 << OP_1 << OP_2 << OP_1 << OP_2 << OP_1 << OP_3
84
+ s2 = s.find_and_delete(Script.new << OP_1 << OP_2 << OP_1)
85
+ s2.must_equal(Script.new << OP_1 << OP_3 << OP_2 << OP_1 << OP_3)
86
+ end
87
+
88
+ it "should not find-and-delete non-matching encoding for the same pushdata" do
89
+ s = Script.new.append_pushdata("foo").append_pushdata("foo", opcode:OP_PUSHDATA1)
90
+ s2 = s.find_and_delete(Script.new << "foo")
91
+ s2.must_equal(Script.new.append_pushdata("foo", opcode:OP_PUSHDATA1))
92
+ end
65
93
 
66
94
  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.6
4
+ version: 1.0.7
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-07-13 00:00:00.000000000 Z
12
+ date: 2015-07-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi