btcruby 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/RELEASE_NOTES.md +8 -0
- data/lib/btcruby.rb +6 -1
- data/lib/btcruby/openssl.rb +23 -9
- data/lib/btcruby/{transaction_outpoint.rb → outpoint.rb} +14 -1
- data/lib/btcruby/script/cltv_plugin.rb +63 -0
- data/lib/btcruby/script/p2sh_plugin.rb +71 -0
- data/lib/btcruby/script/script.rb +7 -1
- data/lib/btcruby/script/script_error.rb +1 -1
- data/lib/btcruby/script/script_interpreter.rb +230 -120
- data/lib/btcruby/script/script_interpreter_plugin.rb +67 -0
- data/lib/btcruby/script/script_number.rb +2 -2
- data/lib/btcruby/script/transaction_signature_checker.rb +4 -1
- data/lib/btcruby/secp256k1.rb +77 -0
- data/lib/btcruby/transaction.rb +5 -4
- data/lib/btcruby/transaction_input.rb +15 -2
- data/lib/btcruby/transaction_output.rb +2 -2
- data/lib/btcruby/validation.rb +90 -0
- data/lib/btcruby/version.rb +1 -1
- data/spec/data/script_invalid.rb +814 -0
- data/spec/data/script_valid.rb +911 -0
- data/spec/data/tx_invalid.rb +197 -0
- data/spec/data/tx_valid.rb +233 -0
- data/spec/open_assets/issuance_id_spec.rb +1 -1
- data/spec/script_interpreter_spec.rb +85 -0
- data/spec/secp256k1_spec.rb +33 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/transaction_spec.rb +153 -0
- metadata +16 -3
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/btcruby/secp256k1'
|
3
|
+
describe BTC::Secp256k1 do
|
4
|
+
|
5
|
+
def verify_rfc6979_signature(keyhex, msg, sighex)
|
6
|
+
key = BTC::Key.new(private_key: keyhex.from_hex)
|
7
|
+
hash = BTC.sha256(msg)
|
8
|
+
sig = BTC::Secp256k1.ecdsa_signature(hash, key.private_key)
|
9
|
+
sig.to_hex.must_equal sighex
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should produce deterministic ECDSA signatures Bitcoin-canonical using nonce from RFC6979" do
|
13
|
+
verify_rfc6979_signature("cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
|
14
|
+
"sample",
|
15
|
+
"3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124")
|
16
|
+
verify_rfc6979_signature("0000000000000000000000000000000000000000000000000000000000000001",
|
17
|
+
"Satoshi Nakamoto",
|
18
|
+
"3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5")
|
19
|
+
verify_rfc6979_signature("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
|
20
|
+
"Satoshi Nakamoto",
|
21
|
+
"3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5")
|
22
|
+
verify_rfc6979_signature("f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
|
23
|
+
"Alan Turing",
|
24
|
+
"304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea")
|
25
|
+
verify_rfc6979_signature("0000000000000000000000000000000000000000000000000000000000000001",
|
26
|
+
"All those moments will be lost in time, like tears in rain. Time to die...",
|
27
|
+
"30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21")
|
28
|
+
verify_rfc6979_signature("e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
|
29
|
+
"There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!",
|
30
|
+
"3045022100b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b0220279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,3 +6,118 @@ require_relative '../lib/btcruby/extensions'
|
|
6
6
|
|
7
7
|
# So every test can access classes directly without prefixing them with BTC::
|
8
8
|
include BTC
|
9
|
+
|
10
|
+
# Script helper used by transaction_spec and script_interpreter_spec
|
11
|
+
FLAGS_MAP = {
|
12
|
+
"" => ScriptFlags::SCRIPT_VERIFY_NONE,
|
13
|
+
"NONE" => ScriptFlags::SCRIPT_VERIFY_NONE,
|
14
|
+
"P2SH" => ScriptFlags::SCRIPT_VERIFY_P2SH,
|
15
|
+
"STRICTENC" => ScriptFlags::SCRIPT_VERIFY_STRICTENC,
|
16
|
+
"DERSIG" => ScriptFlags::SCRIPT_VERIFY_DERSIG,
|
17
|
+
"LOW_S" => ScriptFlags::SCRIPT_VERIFY_LOW_S,
|
18
|
+
"NULLDUMMY" => ScriptFlags::SCRIPT_VERIFY_NULLDUMMY,
|
19
|
+
"SIGPUSHONLY" => ScriptFlags::SCRIPT_VERIFY_SIGPUSHONLY,
|
20
|
+
"MINIMALDATA" => ScriptFlags::SCRIPT_VERIFY_MINIMALDATA,
|
21
|
+
"DISCOURAGE_UPGRADABLE_NOPS" => ScriptFlags::SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
|
22
|
+
"CLEANSTACK" => ScriptFlags::SCRIPT_VERIFY_CLEANSTACK,
|
23
|
+
"CHECKLOCKTIMEVERIFY" => ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY,
|
24
|
+
}
|
25
|
+
|
26
|
+
def parse_script(json_script, expected_result = true)
|
27
|
+
# Note: individual 0xXX bytes may not be individually valid pushdatas, but will be valid when composed together.
|
28
|
+
# Since Script parses binary string right away, we need to compose all distinct bytes in a single hex string.
|
29
|
+
orig_string = json_script
|
30
|
+
json_script = json_script.dup
|
31
|
+
oldsize = json_script.size + 1
|
32
|
+
while json_script.size != oldsize
|
33
|
+
oldsize = json_script.size
|
34
|
+
json_script.gsub!(/0x([0-9a-fA-F]+)\s+0x/, "0x\\1")
|
35
|
+
end
|
36
|
+
json_script.split(" ").inject(Script.new) do |parsed_script, x|
|
37
|
+
if x.size == 0
|
38
|
+
# Empty string, ignore.
|
39
|
+
parsed_script
|
40
|
+
elsif x =~ /^-?\d+$/
|
41
|
+
# Number
|
42
|
+
n = x.to_i
|
43
|
+
if (n == -1) || (n >= 1 and n <= 16)
|
44
|
+
parsed_script << Opcode.opcode_for_small_integer(n)
|
45
|
+
else
|
46
|
+
parsed_script << ScriptNumber.new(integer: n).data
|
47
|
+
end
|
48
|
+
elsif x[0,2] == "0x"
|
49
|
+
# Raw hex data, inserted NOT pushed onto stack:
|
50
|
+
data = BTC.from_hex(x[2..-1])
|
51
|
+
Script.new(data: parsed_script.data + data)
|
52
|
+
elsif x =~ /^'.*'$/
|
53
|
+
# Single-quoted string, pushed as data.
|
54
|
+
parsed_script << x[1..-2]
|
55
|
+
else
|
56
|
+
# opcode, e.g. OP_ADD or ADD:
|
57
|
+
opcode = Opcode.opcode_for_name("OP_" + x)
|
58
|
+
opcode = Opcode.opcode_for_name(x) if opcode == OP_INVALIDOPCODE
|
59
|
+
parsed_script << opcode
|
60
|
+
end
|
61
|
+
end
|
62
|
+
rescue => e
|
63
|
+
if expected_result
|
64
|
+
# puts "json_script = #{orig_string.inspect}"
|
65
|
+
# puts "json_script = #{json_script.inspect}"
|
66
|
+
# puts "EXCEPTION: #{e}"
|
67
|
+
end
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def parse_flags(string)
|
72
|
+
string.split(",").inject(0) do |flags, x|
|
73
|
+
f = FLAGS_MAP[x] or raise RuntimeError, "unrecognized script flag: #{x.inspect}"
|
74
|
+
flags | f
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_crediting_transaction(scriptPubKey)
|
79
|
+
txCredit = Transaction.new;
|
80
|
+
txCredit.version = 1;
|
81
|
+
txCredit.lock_time = 0;
|
82
|
+
txCredit.add_input(TransactionInput.new(
|
83
|
+
previous_hash: nil,
|
84
|
+
coinbase_data: (Script.new << ScriptNumber.new(integer:0) << ScriptNumber.new(integer:0)).data
|
85
|
+
))
|
86
|
+
txCredit.add_output(TransactionOutput.new(
|
87
|
+
script: scriptPubKey,
|
88
|
+
value: 0
|
89
|
+
))
|
90
|
+
txCredit
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_spending_transaction(scriptSig, txCredit)
|
94
|
+
txSpend = Transaction.new
|
95
|
+
txSpend.version = 1;
|
96
|
+
txSpend.lock_time = 0;
|
97
|
+
txSpend.add_input(TransactionInput.new(
|
98
|
+
previous_hash: txCredit.transaction_hash,
|
99
|
+
previous_index: 0,
|
100
|
+
signature_script: scriptSig
|
101
|
+
))
|
102
|
+
txSpend.add_output(TransactionOutput.new(
|
103
|
+
script: Script.new,
|
104
|
+
value: 0
|
105
|
+
))
|
106
|
+
txSpend
|
107
|
+
end
|
108
|
+
|
109
|
+
# ctx = build_crediting_transaction(Script.new)
|
110
|
+
# stx = build_spending_transaction(Script.new, build_crediting_transaction(Script.new))
|
111
|
+
#
|
112
|
+
# puts "crediting tx: #{ctx.transaction_id}" # 7f33a2f5ace097f071010d5105e7fd01f22c83d8d5daa741a41f2a630a2af23b
|
113
|
+
# puts "spending tx: #{stx.transaction_id}" # add55eb99bb1f653ab822ea4177cb0f9673bcc5c2c4c729894ab0c626c8fa1e1
|
114
|
+
#
|
115
|
+
# puts "crediting tx: #{ctx.data.to_hex}"
|
116
|
+
# puts "spending tx: #{stx.data.to_hex}"
|
117
|
+
# From Bitcoin Core:
|
118
|
+
# ctxdummy: 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff020000ffffffff0100000000000000000000000000;
|
119
|
+
# ID = 7f33a2f5ace097f071010d5105e7fd01f22c83d8d5daa741a41f2a630a2af23b
|
120
|
+
# stxdummy: 01000000013bf22a0a632a1fa441a7dad5d8832cf201fde705510d0171f097e0acf5a2337f0000000000ffffffff0100000000000000000000000000;
|
121
|
+
# ID = add55eb99bb1f653ab822ea4177cb0f9673bcc5c2c4c729894ab0c626c8fa1e1
|
122
|
+
|
123
|
+
|
data/spec/transaction_spec.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
|
+
require_relative 'data/tx_valid'
|
3
|
+
require_relative 'data/tx_invalid'
|
4
|
+
|
2
5
|
describe BTC::Transaction do
|
3
6
|
|
4
7
|
it "should have core attributes" do
|
@@ -19,6 +22,156 @@ describe BTC::Transaction do
|
|
19
22
|
})
|
20
23
|
|
21
24
|
end
|
25
|
+
|
26
|
+
describe "Bitcoin Core test vectors" do
|
27
|
+
|
28
|
+
module TxTestHelper
|
29
|
+
extend self
|
30
|
+
|
31
|
+
# Read tests from test/data/tx_valid.json
|
32
|
+
# Format is an array of arrays
|
33
|
+
# Inner arrays are either [ "comment" ]
|
34
|
+
# or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
|
35
|
+
# ... where all scripts are stringified scripts.
|
36
|
+
#
|
37
|
+
# verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
|
38
|
+
def parse_tests(records, expected_result)
|
39
|
+
comment = nil
|
40
|
+
records.each do |test|
|
41
|
+
if test[0].is_a?(Array)
|
42
|
+
if test.size != 3 || !test[1].is_a?(String) || !test[2].is_a?(String)
|
43
|
+
raise "Bad test: #{test.inspect} (#{test.size} #{test[1].class} #{test[2].class})"
|
44
|
+
end
|
45
|
+
mapprevOutScriptPubKeys = {} # Outpoint => Script
|
46
|
+
inputs = test[0]
|
47
|
+
inputs.each do |input|
|
48
|
+
raise "Bad test: input is not an array: #{test.inspect}" if !input.is_a?(Array)
|
49
|
+
raise "Bad test: input is an array of 3 items: #{test.inspect}" if input.size != 3
|
50
|
+
previd, previndex, scriptstring = input
|
51
|
+
|
52
|
+
outpoint = Outpoint.new(transaction_id: previd, index: previndex)
|
53
|
+
|
54
|
+
mapprevOutScriptPubKeys[outpoint] = parse_script(scriptstring)
|
55
|
+
end
|
56
|
+
|
57
|
+
tx = Transaction.new(hex: test[1])
|
58
|
+
flags = parse_flags(test[2])
|
59
|
+
|
60
|
+
if debug_filter(test)
|
61
|
+
validation_proc = lambda do
|
62
|
+
validation_passed = Validation.new.check_transaction(tx, ValidationState.new)
|
63
|
+
if expected_result
|
64
|
+
validation_passed.must_equal expected_result
|
65
|
+
end
|
66
|
+
script_passed = false
|
67
|
+
|
68
|
+
if validation_passed
|
69
|
+
tx.inputs.each do |txin|
|
70
|
+
output_script = mapprevOutScriptPubKeys[txin.outpoint]
|
71
|
+
raise "Bad test: output script not found: #{test.inspect}" if !output_script
|
72
|
+
sig_script = txin.signature_script
|
73
|
+
if !sig_script
|
74
|
+
sig_script = Script.new(data: txin.coinbase_data)
|
75
|
+
end
|
76
|
+
|
77
|
+
checker = TransactionSignatureChecker.new(transaction: tx, input_index: txin.index)
|
78
|
+
plugins = []
|
79
|
+
plugins << P2SHPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_P2SH) != 0
|
80
|
+
plugins << CLTVPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) != 0
|
81
|
+
interpreter = ScriptInterpreter.new(
|
82
|
+
flags: flags,
|
83
|
+
plugins: plugins,
|
84
|
+
signature_checker: checker,
|
85
|
+
raise_on_failure: expected_result,
|
86
|
+
)
|
87
|
+
#Diagnostics.current.trace do
|
88
|
+
script_passed = interpreter.verify_script(signature_script: sig_script, output_script: output_script)
|
89
|
+
if !script_passed
|
90
|
+
break
|
91
|
+
end
|
92
|
+
#end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
(script_passed && validation_passed).must_equal expected_result
|
96
|
+
end # proc
|
97
|
+
|
98
|
+
yield(comment || test.inspect, validation_proc)
|
99
|
+
end # if not filtered
|
100
|
+
|
101
|
+
comment = nil
|
102
|
+
else
|
103
|
+
comment ||= ""
|
104
|
+
comment += test[0].gsub(/\.$/,"") + ". "
|
105
|
+
comment.gsub!(/\. $/, "")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def debug_filter(test)
|
111
|
+
|
112
|
+
#return test.inspect[%{010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000}]
|
113
|
+
|
114
|
+
|
115
|
+
# !!! SIGHASH_SINGLE tx: afd9c17f8913577ec3509520bd6e5d63e9c0fd2a5f70c787993b097ba6ca9fae hashed for input 0: 1eccdc1f7a4783924a49113b491a847de2f89a1e7d73b1ae561d80f918035f46
|
116
|
+
# !!! SIGHASH_SINGLE tx: afd9c17f8913577ec3509520bd6e5d63e9c0fd2a5f70c787993b097ba6ca9fae hashed for input 1: 1943e87af64d0bde608a85330f09aa5c9887a4fdfd9ca6d7a139bef27fee8e3b
|
117
|
+
# !!! SIGHASH_SINGLE tx: afd9c17f8913577ec3509520bd6e5d63e9c0fd2a5f70c787993b097ba6ca9fae hashed for input 2: 1c1f068da6a721f2ecb0fdac3b8adcb4073fee34506971472d29d305507894d6
|
118
|
+
#return test.inspect[%{DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG}]
|
119
|
+
|
120
|
+
#return test.inspect[%{[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000490047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"]}]
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
# def verify_script(tx, txin, sig_script, output_script, flags, expected_result, record)
|
125
|
+
# checker = TransactionSignatureChecker.new(transaction: tx, input_index: txin.index)
|
126
|
+
# plugins = []
|
127
|
+
# plugins << P2SHPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_P2SH) != 0
|
128
|
+
# plugins << CLTVPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) != 0
|
129
|
+
# interpreter = ScriptInterpreter.new(
|
130
|
+
# flags: flags,
|
131
|
+
# plugins: plugins,
|
132
|
+
# signature_checker: checker,
|
133
|
+
# raise_on_failure: expected_result,
|
134
|
+
# )
|
135
|
+
# #Diagnostics.current.trace do
|
136
|
+
# checked = Validation.new.check_transaction(tx, ValidationState.new)
|
137
|
+
# if expected_result
|
138
|
+
# checked.must_equal expected_result
|
139
|
+
# end
|
140
|
+
# result = false
|
141
|
+
# if checked
|
142
|
+
# result = interpreter.verify_script(signature_script: sig_script, output_script: output_script)
|
143
|
+
# if result != expected_result
|
144
|
+
# # puts "Failed scripts: #{sig_script.to_s.inspect} #{output_script.to_s.inspect} flags #{flags}, expected to #{expected_result ? 'succeed' : 'fail'}".gsub(/OP_/, "")
|
145
|
+
# # puts "Error: #{interpreter.error.inspect}"
|
146
|
+
# #debug("Failed #{expected_result ? 'valid' : 'invalid'} script: #{sig_script.to_s.inspect} #{output_script.to_s.inspect} flags #{flags} -- #{record.inspect}")
|
147
|
+
# end
|
148
|
+
# end
|
149
|
+
# puts
|
150
|
+
# puts record.inspect
|
151
|
+
# puts "---------------------------"
|
152
|
+
# puts (result && checked).inspect
|
153
|
+
# puts
|
154
|
+
# (result && checked).must_equal expected_result
|
155
|
+
# #end
|
156
|
+
# end
|
157
|
+
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
TxTestHelper.parse_tests(ValidTxs, true) do |comment, validation_proc|
|
162
|
+
it "should validate transaction: #{comment}" do
|
163
|
+
validation_proc.call
|
164
|
+
#TxTestHelper.verify_script(tx, txin, signature_script, output_script, flags, expected_result, record)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
TxTestHelper.parse_tests(InvalidTxs, false) do |comment, validation_proc| # |helper, tx, txin, signature_script, output_script, flags, expected_result, record, comment|
|
169
|
+
it "should fail transaction: #{comment}" do
|
170
|
+
validation_proc.call
|
171
|
+
#TxTestHelper.verify_script(tx, txin, signature_script, output_script, flags, expected_result, record)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
22
175
|
|
23
176
|
describe "Hash <-> ID conversion" do
|
24
177
|
before do
|
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.1.
|
4
|
+
version: 1.1.2
|
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-
|
12
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -101,18 +101,23 @@ files:
|
|
101
101
|
- lib/btcruby/open_assets/asset_transaction_output.rb
|
102
102
|
- lib/btcruby/open_assets/issuance_id.rb
|
103
103
|
- lib/btcruby/openssl.rb
|
104
|
+
- lib/btcruby/outpoint.rb
|
104
105
|
- lib/btcruby/proof_of_work.rb
|
105
106
|
- lib/btcruby/safety.rb
|
107
|
+
- lib/btcruby/script/cltv_plugin.rb
|
106
108
|
- lib/btcruby/script/opcode.rb
|
109
|
+
- lib/btcruby/script/p2sh_plugin.rb
|
107
110
|
- lib/btcruby/script/script.rb
|
108
111
|
- lib/btcruby/script/script_error.rb
|
109
112
|
- lib/btcruby/script/script_flags.rb
|
110
113
|
- lib/btcruby/script/script_interpreter.rb
|
114
|
+
- lib/btcruby/script/script_interpreter_plugin.rb
|
111
115
|
- lib/btcruby/script/script_number.rb
|
112
116
|
- lib/btcruby/script/signature_checker.rb
|
113
117
|
- lib/btcruby/script/signature_hashtype.rb
|
114
118
|
- lib/btcruby/script/test_signature_checker.rb
|
115
119
|
- lib/btcruby/script/transaction_signature_checker.rb
|
120
|
+
- lib/btcruby/secp256k1.rb
|
116
121
|
- lib/btcruby/transaction.rb
|
117
122
|
- lib/btcruby/transaction_builder.rb
|
118
123
|
- lib/btcruby/transaction_builder/errors.rb
|
@@ -120,8 +125,8 @@ files:
|
|
120
125
|
- lib/btcruby/transaction_builder/result.rb
|
121
126
|
- lib/btcruby/transaction_builder/signer.rb
|
122
127
|
- lib/btcruby/transaction_input.rb
|
123
|
-
- lib/btcruby/transaction_outpoint.rb
|
124
128
|
- lib/btcruby/transaction_output.rb
|
129
|
+
- lib/btcruby/validation.rb
|
125
130
|
- lib/btcruby/version.rb
|
126
131
|
- lib/btcruby/wif.rb
|
127
132
|
- lib/btcruby/wire_format.rb
|
@@ -131,6 +136,10 @@ files:
|
|
131
136
|
- spec/block_header_spec.rb
|
132
137
|
- spec/block_spec.rb
|
133
138
|
- spec/currency_formatter_spec.rb
|
139
|
+
- spec/data/script_invalid.rb
|
140
|
+
- spec/data/script_valid.rb
|
141
|
+
- spec/data/tx_invalid.rb
|
142
|
+
- spec/data/tx_valid.rb
|
134
143
|
- spec/data_spec.rb
|
135
144
|
- spec/diagnostics_spec.rb
|
136
145
|
- spec/key_spec.rb
|
@@ -145,7 +154,9 @@ files:
|
|
145
154
|
- spec/open_assets/asset_transaction_spec.rb
|
146
155
|
- spec/open_assets/issuance_id_spec.rb
|
147
156
|
- spec/proof_of_work_spec.rb
|
157
|
+
- spec/script_interpreter_spec.rb
|
148
158
|
- spec/script_spec.rb
|
159
|
+
- spec/secp256k1_spec.rb
|
149
160
|
- spec/spec_helper.rb
|
150
161
|
- spec/transaction_builder_spec.rb
|
151
162
|
- spec/transaction_spec.rb
|
@@ -194,7 +205,9 @@ test_files:
|
|
194
205
|
- spec/open_assets/asset_transaction_spec.rb
|
195
206
|
- spec/open_assets/issuance_id_spec.rb
|
196
207
|
- spec/proof_of_work_spec.rb
|
208
|
+
- spec/script_interpreter_spec.rb
|
197
209
|
- spec/script_spec.rb
|
210
|
+
- spec/secp256k1_spec.rb
|
198
211
|
- spec/transaction_builder_spec.rb
|
199
212
|
- spec/transaction_spec.rb
|
200
213
|
- spec/wire_format_spec.rb
|