btcruby 1.0.6 → 1.0.7

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