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 +4 -4
- data/RELEASE_NOTES.md +7 -0
- data/lib/btcruby/block.rb +2 -1
- data/lib/btcruby/opcode.rb +1 -0
- data/lib/btcruby/script.rb +50 -19
- data/lib/btcruby/version.rb +1 -1
- data/spec/script_spec.rb +28 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1937e58fcda56495863a298341de0e58def9807
|
4
|
+
data.tar.gz: 4b1dab008f068d52b3bfd69dc7816c03c3fd05aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/lib/btcruby/opcode.rb
CHANGED
data/lib/btcruby/script.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
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(
|
388
|
-
raise ArgumentError, "No
|
389
|
-
encoded_pushdata = self.class.encode_pushdata(
|
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
|
-
|
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)
|
data/lib/btcruby/version.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|