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