btcruby 1.1.4 → 1.1.5
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.rb +1 -1
- data/lib/btcruby/address.rb +1 -0
- data/lib/btcruby/open_assets/asset_marker.rb +1 -0
- data/lib/btcruby/script/opcode.rb +3 -0
- data/lib/btcruby/script/script.rb +2 -1
- data/lib/btcruby/script/script_chunk.rb +1 -0
- data/lib/btcruby/script/script_error.rb +41 -37
- data/lib/btcruby/script/script_interpreter.rb +2 -0
- data/lib/btcruby/script/script_interpreter_plugin.rb +2 -0
- data/lib/btcruby/transaction_builder.rb +1 -0
- data/lib/btcruby/version.rb +1 -1
- data/spec/address_spec.rb +22 -22
- data/spec/base58_spec.rb +8 -8
- data/spec/block_header_spec.rb +4 -4
- data/spec/block_spec.rb +4 -4
- data/spec/currency_formatter_spec.rb +30 -30
- data/spec/data_spec.rb +3 -3
- data/spec/key_spec.rb +11 -11
- data/spec/keychain_spec.rb +12 -12
- data/spec/merkle_tree_spec.rb +3 -3
- data/spec/open_assets/asset_address_spec.rb +7 -7
- data/spec/open_assets/asset_id_spec.rb +3 -3
- data/spec/open_assets/asset_marker_spec.rb +5 -5
- data/spec/open_assets/asset_processor_spec.rb +48 -48
- data/spec/open_assets/asset_transaction_builder_spec.rb +26 -26
- data/spec/open_assets/asset_transaction_spec.rb +9 -9
- data/spec/open_assets/issuance_id_spec.rb +3 -3
- data/spec/script_interpreter_spec.rb +4 -4
- data/spec/script_spec.rb +23 -23
- data/spec/spec_helper.rb +33 -31
- data/spec/transaction_builder_spec.rb +33 -33
- data/spec/transaction_spec.rb +18 -18
- data/spec/wire_format_spec.rb +5 -5
- metadata +2 -2
@@ -3,7 +3,7 @@ require_relative '../spec_helper'
|
|
3
3
|
describe BTC::AssetTransactionBuilder do
|
4
4
|
|
5
5
|
class SignerByKey
|
6
|
-
include TransactionBuilder::Signer
|
6
|
+
include BTC::TransactionBuilder::Signer
|
7
7
|
def initialize(&block)
|
8
8
|
@block = block
|
9
9
|
end
|
@@ -18,7 +18,7 @@ describe BTC::AssetTransactionBuilder do
|
|
18
18
|
builder = BTC::AssetTransactionBuilder.new
|
19
19
|
|
20
20
|
@all_wallet_utxos = self.mock_wallet_utxos
|
21
|
-
builder.bitcoin_provider = TransactionBuilder::Provider.new do |txb|
|
21
|
+
builder.bitcoin_provider = BTC::TransactionBuilder::Provider.new do |txb|
|
22
22
|
@all_wallet_utxos
|
23
23
|
end
|
24
24
|
builder.signer = SignerByKey.new do |output, address|
|
@@ -86,7 +86,7 @@ describe BTC::AssetTransactionBuilder do
|
|
86
86
|
builder = BTC::AssetTransactionBuilder.new
|
87
87
|
|
88
88
|
@all_wallet_utxos = self.mock_wallet_utxos
|
89
|
-
builder.bitcoin_provider = TransactionBuilder::Provider.new do |txb|
|
89
|
+
builder.bitcoin_provider = BTC::TransactionBuilder::Provider.new do |txb|
|
90
90
|
@all_wallet_utxos
|
91
91
|
end
|
92
92
|
builder.signer = SignerByKey.new do |output, address|
|
@@ -97,15 +97,15 @@ describe BTC::AssetTransactionBuilder do
|
|
97
97
|
# Each transfer may have its own unspents and its own change address.
|
98
98
|
# If those are not specified, a per-builder setting is chosen.
|
99
99
|
|
100
|
-
@asset1 = AssetID.new(script: Script.new << OP_1)
|
101
|
-
@asset2 = AssetID.new(script: Script.new << OP_2)
|
100
|
+
@asset1 = BTC::AssetID.new(script: BTC::Script.new << BTC::OP_1)
|
101
|
+
@asset2 = BTC::AssetID.new(script: BTC::Script.new << BTC::OP_2)
|
102
102
|
|
103
103
|
builder.transfer_asset(
|
104
104
|
asset_id: @asset1,
|
105
105
|
amount: 10_000,
|
106
106
|
address: holder2_asset_address,
|
107
107
|
unspent_outputs: [
|
108
|
-
AssetTransactionOutput.new(
|
108
|
+
BTC::AssetTransactionOutput.new(
|
109
109
|
transaction_output: mock_utxo(value: 1000),
|
110
110
|
asset_id: @asset1,
|
111
111
|
value: 11_000,
|
@@ -121,7 +121,7 @@ describe BTC::AssetTransactionBuilder do
|
|
121
121
|
amount: 50_000,
|
122
122
|
address: holder1_asset_address,
|
123
123
|
unspent_outputs: [
|
124
|
-
AssetTransactionOutput.new(
|
124
|
+
BTC::AssetTransactionOutput.new(
|
125
125
|
transaction_output: mock_utxo(value: 1000),
|
126
126
|
asset_id: @asset2,
|
127
127
|
value: 150_000,
|
@@ -136,7 +136,7 @@ describe BTC::AssetTransactionBuilder do
|
|
136
136
|
builder.bitcoin_change_address = wallet2_key.address
|
137
137
|
|
138
138
|
# Send leftover assets to this address.
|
139
|
-
builder.asset_change_address = AssetAddress.new(bitcoin_address: holder2_key.address)
|
139
|
+
builder.asset_change_address = BTC::AssetAddress.new(bitcoin_address: holder2_key.address)
|
140
140
|
|
141
141
|
# Build transactions.
|
142
142
|
@builder = builder
|
@@ -174,35 +174,35 @@ describe BTC::AssetTransactionBuilder do
|
|
174
174
|
# Mocked wallet
|
175
175
|
|
176
176
|
def wallet1_key
|
177
|
-
@wallet1_key ||= Key.new(private_key: "Wallet1".sha256)
|
177
|
+
@wallet1_key ||= BTC::Key.new(private_key: "Wallet1".sha256)
|
178
178
|
end
|
179
179
|
|
180
180
|
def wallet2_key
|
181
|
-
@wallet2_key ||= Key.new(private_key: "Wallet2".sha256)
|
181
|
+
@wallet2_key ||= BTC::Key.new(private_key: "Wallet2".sha256)
|
182
182
|
end
|
183
183
|
|
184
184
|
def issuer1_key
|
185
|
-
@issuer1_key ||= Key.new(private_key: "Issuer1".sha256)
|
185
|
+
@issuer1_key ||= BTC::Key.new(private_key: "Issuer1".sha256)
|
186
186
|
end
|
187
187
|
|
188
188
|
def issuer2_key
|
189
|
-
@issuer2_key ||= Key.new(private_key: "Issuer2".sha256)
|
189
|
+
@issuer2_key ||= BTC::Key.new(private_key: "Issuer2".sha256)
|
190
190
|
end
|
191
191
|
|
192
192
|
def holder1_key
|
193
|
-
@holder1_key ||= Key.new(private_key: "Holder1".sha256)
|
193
|
+
@holder1_key ||= BTC::Key.new(private_key: "Holder1".sha256)
|
194
194
|
end
|
195
195
|
|
196
196
|
def holder2_key
|
197
|
-
@holder2_key ||= Key.new(private_key: "Holder2".sha256)
|
197
|
+
@holder2_key ||= BTC::Key.new(private_key: "Holder2".sha256)
|
198
198
|
end
|
199
199
|
|
200
200
|
def holder1_asset_address
|
201
|
-
AssetAddress.new(bitcoin_address: holder1_key.address)
|
201
|
+
BTC::AssetAddress.new(bitcoin_address: holder1_key.address)
|
202
202
|
end
|
203
203
|
|
204
204
|
def holder2_asset_address
|
205
|
-
AssetAddress.new(bitcoin_address: holder2_key.address)
|
205
|
+
BTC::AssetAddress.new(bitcoin_address: holder2_key.address)
|
206
206
|
end
|
207
207
|
|
208
208
|
def mock_wallet_keys
|
@@ -222,17 +222,17 @@ describe BTC::AssetTransactionBuilder do
|
|
222
222
|
def mock_wallet_utxos
|
223
223
|
scripts = mock_wallet_addresses.map{|a| a.script }
|
224
224
|
(1..32).map do |i|
|
225
|
-
TransactionOutput.new(value: 100_000,
|
225
|
+
BTC::TransactionOutput.new(value: 100_000,
|
226
226
|
script: scripts[i % scripts.size],
|
227
227
|
transaction_hash: ((16+i).to_s(16)*32).from_hex,
|
228
228
|
index: i)
|
229
229
|
end
|
230
230
|
end
|
231
231
|
|
232
|
-
def mock_utxo(value: 100_000, index: 0, script: Script.new << OP_1)
|
233
|
-
TransactionOutput.new(value: value,
|
232
|
+
def mock_utxo(value: 100_000, index: 0, script: BTC::Script.new << BTC::OP_1)
|
233
|
+
BTC::TransactionOutput.new(value: value,
|
234
234
|
script: script,
|
235
|
-
transaction_hash: Key.random.private_key.sha256,
|
235
|
+
transaction_hash: BTC::Key.random.private_key.sha256,
|
236
236
|
index: index)
|
237
237
|
end
|
238
238
|
|
@@ -252,17 +252,17 @@ describe "Issuing an asset" do
|
|
252
252
|
issuing_script = issuer.address.script
|
253
253
|
holding_script = holder.address.script
|
254
254
|
|
255
|
-
source_output = TransactionOutput.new(value: 100, script: issuing_script)
|
255
|
+
source_output = BTC::TransactionOutput.new(value: 100, script: issuing_script)
|
256
256
|
|
257
257
|
# These are set automatically if source_output is a part of some BTC::Transaction
|
258
258
|
# We need these to complete the input for the transfer transaction.
|
259
|
-
source_output.transaction_hash = BTC
|
259
|
+
source_output.transaction_hash = BTC.hash256("some tx")
|
260
260
|
source_output.index = 0
|
261
261
|
|
262
|
-
transfer = Transaction.new
|
263
|
-
transfer.add_input(TransactionInput.new(transaction_output: source_output))
|
264
|
-
transfer.add_output(TransactionOutput.new(value: source_output.value, script: holding_script))
|
265
|
-
marker = AssetMarker.new
|
262
|
+
transfer = BTC::Transaction.new
|
263
|
+
transfer.add_input(BTC::TransactionInput.new(transaction_output: source_output))
|
264
|
+
transfer.add_output(BTC::TransactionOutput.new(value: source_output.value, script: holding_script))
|
265
|
+
marker = BTC::AssetMarker.new
|
266
266
|
marker.quantities = [ 1000_000_000 ]
|
267
267
|
marker.metadata = "Chancellor bailing out banks"
|
268
268
|
transfer.outputs << marker.output
|
@@ -3,21 +3,21 @@ require_relative '../spec_helper'
|
|
3
3
|
describe "Serialization" do
|
4
4
|
|
5
5
|
def build_asset_transaction(inputs: [], issues: [], transfers: [])
|
6
|
-
tx = Transaction.new
|
7
|
-
script = PublicKeyAddress.new(hash: "some address".hash160).script
|
6
|
+
tx = BTC::Transaction.new
|
7
|
+
script = BTC::PublicKeyAddress.new(hash: "some address".hash160).script
|
8
8
|
inputs.each do
|
9
|
-
tx.add_input(TransactionInput.new(previous_hash: "".sha256, previous_index: 0))
|
9
|
+
tx.add_input(BTC::TransactionInput.new(previous_hash: "".sha256, previous_index: 0))
|
10
10
|
end
|
11
11
|
issues.each do |tuple|
|
12
|
-
tx.add_output(TransactionOutput.new(value: 1, script: script))
|
12
|
+
tx.add_output(BTC::TransactionOutput.new(value: 1, script: script))
|
13
13
|
end
|
14
14
|
qtys = issues.map{|tuple| tuple.first} + transfers.map{|tuple| tuple.first}
|
15
|
-
tx.add_output(AssetMarker.new(quantities: qtys).output)
|
15
|
+
tx.add_output(BTC::AssetMarker.new(quantities: qtys).output)
|
16
16
|
transfers.each do |tuple|
|
17
|
-
tx.add_output(TransactionOutput.new(value: 1, script: script))
|
17
|
+
tx.add_output(BTC::TransactionOutput.new(value: 1, script: script))
|
18
18
|
end
|
19
19
|
|
20
|
-
atx = AssetTransaction.new(transaction: tx)
|
20
|
+
atx = BTC::AssetTransaction.new(transaction: tx)
|
21
21
|
atx.inputs.each_with_index do |ain, i|
|
22
22
|
amount, name = inputs[i]
|
23
23
|
if amount
|
@@ -35,7 +35,7 @@ describe "Serialization" do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def asset_id(name)
|
38
|
-
name ? AssetID.new(hash: name.hash160) : nil
|
38
|
+
name ? BTC::AssetID.new(hash: name.hash160) : nil
|
39
39
|
end
|
40
40
|
|
41
41
|
before do
|
@@ -45,7 +45,7 @@ describe "Serialization" do
|
|
45
45
|
transfers: [ [40, "A"], [60, "A"], [44, "B"] ]
|
46
46
|
)
|
47
47
|
data = @atx.data
|
48
|
-
@atx2 = AssetTransaction.new(data: data)
|
48
|
+
@atx2 = BTC::AssetTransaction.new(data: data)
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should restore all outputs" do
|
@@ -2,14 +2,14 @@ require_relative '../spec_helper'
|
|
2
2
|
|
3
3
|
describe BTC::IssuanceID do
|
4
4
|
it "should encode script to a correct address" do
|
5
|
-
key = Key.new(private_key: "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725".from_hex, public_key_compressed: false)
|
6
|
-
issuance_id = IssuanceID.new(outpoint: Outpoint.new(transaction_hash: BTC.hash256("tx1"), index:1), amount:100, network: Network.mainnet)
|
5
|
+
key = BTC::Key.new(private_key: "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725".from_hex, public_key_compressed: false)
|
6
|
+
issuance_id = BTC::IssuanceID.new(outpoint: BTC::Outpoint.new(transaction_hash: BTC.hash256("tx1"), index:1), amount:100, network: BTC::Network.mainnet)
|
7
7
|
issuance_id.hash.to_hex.must_equal "29d2765469a299d1219a1cbf7561534eae4595f7"
|
8
8
|
issuance_id.to_s.must_equal "SR78rsv5RCMMay22D3ZUZmMgPkRGpqphnQ"
|
9
9
|
issuance_id.is_a?(BTC::IssuanceID).must_equal true
|
10
10
|
end
|
11
11
|
it "should decode an asset address" do
|
12
|
-
issuance_id = Address.parse("SR78rsv5RCMMay22D3ZUZmMgPkRGpqphnQ")
|
12
|
+
issuance_id = BTC::Address.parse("SR78rsv5RCMMay22D3ZUZmMgPkRGpqphnQ")
|
13
13
|
issuance_id.is_a?(BTC::IssuanceID).must_equal true
|
14
14
|
issuance_id.hash.to_hex.must_equal "29d2765469a299d1219a1cbf7561534eae4595f7"
|
15
15
|
end
|
@@ -9,11 +9,11 @@ describe BTC::ScriptInterpreter do
|
|
9
9
|
|
10
10
|
def verify_script(sig_script, output_script, flags, expected_result, record)
|
11
11
|
tx = build_spending_transaction(sig_script, build_crediting_transaction(output_script));
|
12
|
-
checker = TransactionSignatureChecker.new(transaction: tx, input_index: 0)
|
12
|
+
checker = BTC::TransactionSignatureChecker.new(transaction: tx, input_index: 0)
|
13
13
|
plugins = []
|
14
|
-
plugins << P2SHPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_P2SH) != 0
|
15
|
-
plugins << CLTVPlugin.new if (flags & ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) != 0
|
16
|
-
interpreter = ScriptInterpreter.new(
|
14
|
+
plugins << BTC::P2SHPlugin.new if (flags & BTC::ScriptFlags::SCRIPT_VERIFY_P2SH) != 0
|
15
|
+
plugins << BTC::CLTVPlugin.new if (flags & BTC::ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) != 0
|
16
|
+
interpreter = BTC::ScriptInterpreter.new(
|
17
17
|
flags: flags,
|
18
18
|
plugins: plugins,
|
19
19
|
signature_checker: checker,
|
data/spec/script_spec.rb
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
describe BTC::Script do
|
3
|
-
|
3
|
+
|
4
4
|
it "should instantiate with empty data" do
|
5
|
-
empty_script = Script.new
|
5
|
+
empty_script = BTC::Script.new
|
6
6
|
empty_script.data.must_equal "".b
|
7
7
|
empty_script.to_s.must_equal ''
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should support standard P2PKH script" do
|
11
|
-
script = (Script.new << OP_DUP << OP_HASH160 << "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex << OP_EQUALVERIFY << OP_CHECKSIG)
|
11
|
+
script = (BTC::Script.new << BTC::OP_DUP << BTC::OP_HASH160 << "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG)
|
12
12
|
script.standard?.must_equal true
|
13
13
|
script.public_key_hash_script?.must_equal true
|
14
14
|
script.script_hash_script?.must_equal false
|
15
15
|
script.multisig_script?.must_equal false
|
16
16
|
script.standard_multisig_script?.must_equal false
|
17
|
-
script.standard_address.class.must_equal PublicKeyAddress
|
17
|
+
script.standard_address.class.must_equal BTC::PublicKeyAddress
|
18
18
|
script.standard_address.data.must_equal "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex
|
19
19
|
script.to_s.must_equal "OP_DUP OP_HASH160 5a73e920b7836c74f9e740a5bb885e8580557038 OP_EQUALVERIFY OP_CHECKSIG"
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should support standard P2SH script" do
|
23
|
-
script = (Script.new << OP_HASH160 << "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex << OP_EQUAL)
|
23
|
+
script = (BTC::Script.new << BTC::OP_HASH160 << "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex << BTC::OP_EQUAL)
|
24
24
|
script.standard?.must_equal true
|
25
25
|
script.public_key_hash_script?.must_equal false
|
26
26
|
script.script_hash_script?.must_equal true
|
27
27
|
script.multisig_script?.must_equal false
|
28
28
|
script.standard_multisig_script?.must_equal false
|
29
|
-
script.standard_address.class.must_equal ScriptHashAddress
|
29
|
+
script.standard_address.class.must_equal BTC::ScriptHashAddress
|
30
30
|
script.standard_address.data.must_equal "5a73e920b7836c74f9e740a5bb885e8580557038".from_hex
|
31
31
|
script.to_s.must_equal "OP_HASH160 5a73e920b7836c74f9e740a5bb885e8580557038 OP_EQUAL"
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should support standard multisig script" do
|
35
|
-
script = (Script.new << OP_1 <<
|
35
|
+
script = (BTC::Script.new << BTC::OP_1 <<
|
36
36
|
"c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a".from_hex <<
|
37
37
|
"bffbec99da8a6573bd4e359d85c8cb62e6f483d9afac4be2db963f0fe10bcb19".from_hex <<
|
38
|
-
OP_2 <<
|
39
|
-
OP_CHECKMULTISIG)
|
38
|
+
BTC::OP_2 <<
|
39
|
+
BTC::OP_CHECKMULTISIG)
|
40
40
|
script.standard?.must_equal true
|
41
41
|
script.public_key_hash_script?.must_equal false
|
42
42
|
script.script_hash_script?.must_equal false
|
@@ -51,7 +51,7 @@ describe BTC::Script do
|
|
51
51
|
script.to_s.must_equal "OP_1 c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a "+
|
52
52
|
"bffbec99da8a6573bd4e359d85c8cb62e6f483d9afac4be2db963f0fe10bcb19 OP_2 OP_CHECKMULTISIG"
|
53
53
|
|
54
|
-
script2 = Script.multisig(public_keys:[
|
54
|
+
script2 = BTC::Script.multisig(public_keys:[
|
55
55
|
"c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a".from_hex,
|
56
56
|
"bffbec99da8a6573bd4e359d85c8cb62e6f483d9afac4be2db963f0fe10bcb19".from_hex
|
57
57
|
], signatures_required: 1)
|
@@ -63,36 +63,36 @@ describe BTC::Script do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should support subscripts" do
|
66
|
-
s = Script.new << OP_DUP << OP_HASH160 << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG
|
66
|
+
s = BTC::Script.new << BTC::OP_DUP << BTC::OP_HASH160 << BTC::OP_CODESEPARATOR << "some data" << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG
|
67
67
|
s.subscript(0..-1).must_equal s
|
68
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)
|
69
|
+
s.subscript(3..-1).must_equal(BTC::Script.new << "some data" << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG)
|
70
|
+
s[3..-1].must_equal(BTC::Script.new << "some data" << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG)
|
71
71
|
end
|
72
72
|
|
73
73
|
|
74
74
|
it "removing subscript does not modify the receiver" do
|
75
|
-
s = Script.new << OP_DUP << OP_HASH160 << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG
|
75
|
+
s = BTC::Script.new << BTC::OP_DUP << BTC::OP_HASH160 << BTC::OP_CODESEPARATOR << "some data" << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG
|
76
76
|
s1 = s.dup
|
77
|
-
s2 = s1.find_and_delete(Script.new << OP_HASH160)
|
77
|
+
s2 = s1.find_and_delete(BTC::Script.new << BTC::OP_HASH160)
|
78
78
|
s.must_equal s1
|
79
|
-
s2.must_equal(Script.new << OP_DUP << OP_CODESEPARATOR << "some data" << OP_EQUALVERIFY << OP_CHECKSIG)
|
79
|
+
s2.must_equal(BTC::Script.new << BTC::OP_DUP << BTC::OP_CODESEPARATOR << "some data" << BTC::OP_EQUALVERIFY << BTC::OP_CHECKSIG)
|
80
80
|
end
|
81
81
|
|
82
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)
|
83
|
+
s = BTC::Script.new << BTC::OP_1 << BTC::OP_3 << BTC::OP_1 << BTC::OP_2 << BTC::OP_1 << BTC::OP_2 << BTC::OP_1 << BTC::OP_3
|
84
|
+
s2 = s.find_and_delete(BTC::Script.new << BTC::OP_1 << BTC::OP_2 << BTC::OP_1)
|
85
|
+
s2.must_equal(BTC::Script.new << BTC::OP_1 << BTC::OP_3 << BTC::OP_2 << BTC::OP_1 << BTC::OP_3)
|
86
86
|
end
|
87
87
|
|
88
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))
|
89
|
+
s = BTC::Script.new.append_pushdata("foo").append_pushdata("foo", opcode:BTC::OP_PUSHDATA1)
|
90
|
+
s2 = s.find_and_delete(BTC::Script.new << "foo")
|
91
|
+
s2.must_equal(BTC::Script.new.append_pushdata("foo", opcode:BTC::OP_PUSHDATA1))
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should parse interpreted data and pushdata correctly" do
|
95
|
-
script = Script.new << OP_0 << OP_1NEGATE << OP_NOP << OP_RESERVED << OP_1 << OP_16 << "1" << "2" << "chancellor"
|
95
|
+
script = BTC::Script.new << BTC::OP_0 << BTC::OP_1NEGATE << BTC::OP_NOP << BTC::OP_RESERVED << BTC::OP_1 << BTC::OP_16 << "1" << "2" << "chancellor"
|
96
96
|
script.chunks.map{|c| c.interpreted_data }.must_equal ["", "\x81".b, nil, nil, "\x01".b, "\x10".b, "1", "2", "chancellor"]
|
97
97
|
script.chunks.map{|c| c.pushdata }.must_equal ["", nil, nil, nil, nil, nil, "1", "2", "chancellor"]
|
98
98
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,22 +5,22 @@ require_relative '../lib/btcruby'
|
|
5
5
|
require_relative '../lib/btcruby/extensions'
|
6
6
|
|
7
7
|
# So every test can access classes directly without prefixing them with BTC::
|
8
|
-
include BTC
|
8
|
+
#include BTC
|
9
9
|
|
10
10
|
# Script helper used by transaction_spec and script_interpreter_spec
|
11
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,
|
12
|
+
"" => BTC::ScriptFlags::SCRIPT_VERIFY_NONE,
|
13
|
+
"NONE" => BTC::ScriptFlags::SCRIPT_VERIFY_NONE,
|
14
|
+
"P2SH" => BTC::ScriptFlags::SCRIPT_VERIFY_P2SH,
|
15
|
+
"STRICTENC" => BTC::ScriptFlags::SCRIPT_VERIFY_STRICTENC,
|
16
|
+
"DERSIG" => BTC::ScriptFlags::SCRIPT_VERIFY_DERSIG,
|
17
|
+
"LOW_S" => BTC::ScriptFlags::SCRIPT_VERIFY_LOW_S,
|
18
|
+
"NULLDUMMY" => BTC::ScriptFlags::SCRIPT_VERIFY_NULLDUMMY,
|
19
|
+
"SIGPUSHONLY" => BTC::ScriptFlags::SCRIPT_VERIFY_SIGPUSHONLY,
|
20
|
+
"MINIMALDATA" => BTC::ScriptFlags::SCRIPT_VERIFY_MINIMALDATA,
|
21
|
+
"DISCOURAGE_UPGRADABLE_NOPS" => BTC::ScriptFlags::SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
|
22
|
+
"CLEANSTACK" => BTC::ScriptFlags::SCRIPT_VERIFY_CLEANSTACK,
|
23
|
+
"CHECKLOCKTIMEVERIFY" => BTC::ScriptFlags::SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY,
|
24
24
|
}
|
25
25
|
|
26
26
|
def parse_script(json_script, expected_result = true)
|
@@ -33,7 +33,7 @@ def parse_script(json_script, expected_result = true)
|
|
33
33
|
oldsize = json_script.size
|
34
34
|
json_script.gsub!(/0x([0-9a-fA-F]+)\s+0x/, "0x\\1")
|
35
35
|
end
|
36
|
-
json_script.split(" ").inject(Script.new) do |parsed_script, x|
|
36
|
+
json_script.split(" ").inject(BTC::Script.new) do |parsed_script, x|
|
37
37
|
if x.size == 0
|
38
38
|
# Empty string, ignore.
|
39
39
|
parsed_script
|
@@ -41,25 +41,27 @@ def parse_script(json_script, expected_result = true)
|
|
41
41
|
# Number
|
42
42
|
n = x.to_i
|
43
43
|
if (n == -1) || (n >= 1 and n <= 16)
|
44
|
-
parsed_script << Opcode.opcode_for_small_integer(n)
|
44
|
+
parsed_script << BTC::Opcode.opcode_for_small_integer(n)
|
45
45
|
else
|
46
|
-
parsed_script << ScriptNumber.new(integer: n).data
|
46
|
+
parsed_script << BTC::ScriptNumber.new(integer: n).data
|
47
47
|
end
|
48
48
|
elsif x[0,2] == "0x"
|
49
49
|
# Raw hex data, inserted NOT pushed onto stack:
|
50
50
|
data = BTC.from_hex(x[2..-1])
|
51
|
-
Script.new(data: parsed_script.data + data)
|
51
|
+
BTC::Script.new(data: parsed_script.data + data)
|
52
52
|
elsif x =~ /^'.*'$/
|
53
53
|
# Single-quoted string, pushed as data.
|
54
54
|
parsed_script << x[1..-2]
|
55
55
|
else
|
56
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
|
57
|
+
opcode = BTC::Opcode.opcode_for_name("OP_" + x)
|
58
|
+
opcode = BTC::Opcode.opcode_for_name(x) if opcode == BTC::OP_INVALIDOPCODE
|
59
59
|
parsed_script << opcode
|
60
60
|
end
|
61
61
|
end
|
62
62
|
rescue => e
|
63
|
+
# puts e.backtrace.join("\n")
|
64
|
+
# raise "!!!!"
|
63
65
|
if expected_result
|
64
66
|
# puts "json_script = #{orig_string.inspect}"
|
65
67
|
# puts "json_script = #{json_script.inspect}"
|
@@ -76,14 +78,14 @@ def parse_flags(string)
|
|
76
78
|
end
|
77
79
|
|
78
80
|
def build_crediting_transaction(scriptPubKey)
|
79
|
-
txCredit = Transaction.new
|
80
|
-
txCredit.version = 1
|
81
|
-
txCredit.lock_time = 0
|
82
|
-
txCredit.add_input(TransactionInput.new(
|
81
|
+
txCredit = BTC::Transaction.new
|
82
|
+
txCredit.version = 1
|
83
|
+
txCredit.lock_time = 0
|
84
|
+
txCredit.add_input(BTC::TransactionInput.new(
|
83
85
|
previous_hash: nil,
|
84
|
-
coinbase_data: (Script.new << ScriptNumber.new(integer:0) << ScriptNumber.new(integer:0)).data
|
86
|
+
coinbase_data: (BTC::Script.new << BTC::ScriptNumber.new(integer:0) << BTC::ScriptNumber.new(integer:0)).data
|
85
87
|
))
|
86
|
-
txCredit.add_output(TransactionOutput.new(
|
88
|
+
txCredit.add_output(BTC::TransactionOutput.new(
|
87
89
|
script: scriptPubKey,
|
88
90
|
value: 0
|
89
91
|
))
|
@@ -91,16 +93,16 @@ def build_crediting_transaction(scriptPubKey)
|
|
91
93
|
end
|
92
94
|
|
93
95
|
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(
|
96
|
+
txSpend = BTC::Transaction.new
|
97
|
+
txSpend.version = 1
|
98
|
+
txSpend.lock_time = 0
|
99
|
+
txSpend.add_input(BTC::TransactionInput.new(
|
98
100
|
previous_hash: txCredit.transaction_hash,
|
99
101
|
previous_index: 0,
|
100
102
|
signature_script: scriptSig
|
101
103
|
))
|
102
|
-
txSpend.add_output(TransactionOutput.new(
|
103
|
-
script: Script.new,
|
104
|
+
txSpend.add_output(BTC::TransactionOutput.new(
|
105
|
+
script: BTC::Script.new,
|
104
106
|
value: 0
|
105
107
|
))
|
106
108
|
txSpend
|