bitcoin-ruby 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -1
- data/Gemfile +21 -0
- data/README.rdoc +85 -25
- data/Rakefile +7 -3
- data/bin/bitcoin_node +39 -42
- data/bin/bitcoin_shell +1 -0
- data/bin/bitcoin_wallet +129 -53
- data/bitcoin-ruby.gemspec +4 -7
- data/concept-examples/blockchain-pow.rb +1 -1
- data/doc/CONFIG.rdoc +5 -5
- data/doc/EXAMPLES.rdoc +9 -5
- data/doc/NAMECOIN.rdoc +34 -0
- data/doc/NODE.rdoc +147 -10
- data/examples/balance.rb +10 -4
- data/examples/bbe_verify_tx.rb +7 -2
- data/examples/forwarder.rb +73 -0
- data/examples/generate_tx.rb +34 -0
- data/examples/simple_network_monitor_and_util.rb +187 -0
- data/examples/verify_tx.rb +1 -1
- data/lib/bitcoin.rb +308 -18
- data/lib/bitcoin/builder.rb +62 -36
- data/lib/bitcoin/config.rb +2 -0
- data/lib/bitcoin/connection.rb +11 -8
- data/lib/bitcoin/electrum/mnemonic.rb +162 -0
- data/lib/bitcoin/ffi/openssl.rb +187 -21
- data/lib/bitcoin/gui/addr_view.rb +2 -0
- data/lib/bitcoin/gui/conn_view.rb +2 -0
- data/lib/bitcoin/gui/connection.rb +2 -0
- data/lib/bitcoin/gui/em_gtk.rb +2 -0
- data/lib/bitcoin/gui/gui.rb +2 -0
- data/lib/bitcoin/gui/helpers.rb +2 -0
- data/lib/bitcoin/gui/tree_view.rb +2 -0
- data/lib/bitcoin/gui/tx_view.rb +2 -0
- data/lib/bitcoin/key.rb +77 -11
- data/lib/bitcoin/litecoin.rb +81 -0
- data/lib/bitcoin/logger.rb +20 -1
- data/lib/bitcoin/namecoin.rb +279 -0
- data/lib/bitcoin/network/command_client.rb +7 -6
- data/lib/bitcoin/network/command_handler.rb +229 -43
- data/lib/bitcoin/network/connection_handler.rb +182 -70
- data/lib/bitcoin/network/node.rb +231 -106
- data/lib/bitcoin/protocol.rb +44 -23
- data/lib/bitcoin/protocol/address.rb +5 -3
- data/lib/bitcoin/protocol/alert.rb +3 -4
- data/lib/bitcoin/protocol/aux_pow.rb +123 -0
- data/lib/bitcoin/protocol/block.rb +98 -18
- data/lib/bitcoin/protocol/handler.rb +6 -5
- data/lib/bitcoin/protocol/parser.rb +44 -19
- data/lib/bitcoin/protocol/tx.rb +105 -52
- data/lib/bitcoin/protocol/txin.rb +39 -19
- data/lib/bitcoin/protocol/txout.rb +28 -13
- data/lib/bitcoin/protocol/version.rb +16 -7
- data/lib/bitcoin/script.rb +579 -122
- data/lib/bitcoin/storage/{dummy.rb → dummy/dummy_store.rb} +8 -14
- data/lib/bitcoin/storage/models.rb +20 -7
- data/lib/bitcoin/storage/{sequel_store/sequel_migrations.rb → sequel/migrations.rb} +22 -7
- data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +52 -0
- data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +50 -0
- data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +18 -0
- data/lib/bitcoin/storage/sequel/sequel_store.rb +436 -0
- data/lib/bitcoin/storage/storage.rb +233 -28
- data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +52 -0
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +18 -0
- data/lib/bitcoin/storage/utxo/utxo_store.rb +361 -0
- data/lib/bitcoin/validation.rb +369 -0
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet/coinselector.rb +3 -0
- data/lib/bitcoin/wallet/keygenerator.rb +3 -1
- data/lib/bitcoin/wallet/keystore.rb +6 -2
- data/lib/bitcoin/wallet/txdp.rb +6 -4
- data/lib/bitcoin/wallet/wallet.rb +54 -16
- data/spec/bitcoin/bitcoin_spec.rb +48 -3
- data/spec/bitcoin/builder_spec.rb +40 -17
- data/spec/bitcoin/fixtures/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +3697 -0
- data/spec/bitcoin/fixtures/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +23 -0
- data/spec/bitcoin/fixtures/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +24 -0
- data/spec/bitcoin/fixtures/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +37 -0
- data/spec/bitcoin/fixtures/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +31 -0
- data/spec/bitcoin/fixtures/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +27 -0
- data/spec/bitcoin/fixtures/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +72 -0
- data/spec/bitcoin/fixtures/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +27 -0
- data/spec/bitcoin/fixtures/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +24 -0
- data/spec/bitcoin/fixtures/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +30 -0
- data/spec/bitcoin/fixtures/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +28 -0
- data/spec/bitcoin/fixtures/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +27 -0
- data/spec/bitcoin/fixtures/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +27 -0
- data/spec/bitcoin/fixtures/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +27 -0
- data/spec/bitcoin/fixtures/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +34 -0
- data/spec/bitcoin/fixtures/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
- data/spec/bitcoin/fixtures/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +24 -0
- data/spec/bitcoin/fixtures/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +41 -0
- data/spec/bitcoin/fixtures/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +23 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +43 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +67 -0
- data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
- data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +39 -0
- data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
- data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +39 -0
- data/spec/bitcoin/fixtures/rawblock-auxpow.bin +0 -0
- data/spec/bitcoin/fixtures/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +30 -0
- data/spec/bitcoin/fixtures/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +23 -0
- data/spec/bitcoin/fixtures/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +30 -0
- data/spec/bitcoin/fixtures/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +28 -0
- data/spec/bitcoin/key_spec.rb +128 -3
- data/spec/bitcoin/namecoin_spec.rb +182 -0
- data/spec/bitcoin/network_spec.rb +5 -3
- data/spec/bitcoin/node/command_api_spec.rb +376 -0
- data/spec/bitcoin/protocol/addr_spec.rb +2 -0
- data/spec/bitcoin/protocol/alert_spec.rb +2 -0
- data/spec/bitcoin/protocol/aux_pow_spec.rb +44 -0
- data/spec/bitcoin/protocol/block_spec.rb +134 -39
- data/spec/bitcoin/protocol/getblocks_spec.rb +32 -0
- data/spec/bitcoin/protocol/inv_spec.rb +10 -8
- data/spec/bitcoin/protocol/notfound_spec.rb +31 -0
- data/spec/bitcoin/protocol/ping_spec.rb +2 -0
- data/spec/bitcoin/protocol/tx_spec.rb +83 -17
- data/spec/bitcoin/protocol/version_spec.rb +7 -5
- data/spec/bitcoin/script/opcodes_spec.rb +412 -133
- data/spec/bitcoin/script/script_spec.rb +112 -13
- data/spec/bitcoin/spec_helper.rb +68 -0
- data/spec/bitcoin/storage/reorg_spec.rb +199 -0
- data/spec/bitcoin/storage/storage_spec.rb +337 -0
- data/spec/bitcoin/storage/validation_spec.rb +261 -0
- data/spec/bitcoin/wallet/coinselector_spec.rb +10 -7
- data/spec/bitcoin/wallet/keygenerator_spec.rb +2 -0
- data/spec/bitcoin/wallet/keystore_spec.rb +2 -0
- data/spec/bitcoin/wallet/txdp_spec.rb +2 -0
- data/spec/bitcoin/wallet/wallet_spec.rb +91 -58
- metadata +105 -51
- data/lib/bitcoin/storage/sequel.rb +0 -335
- data/spec/bitcoin/fixtures/0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json +0 -27
- data/spec/bitcoin/fixtures/477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json +0 -27
- data/spec/bitcoin/reorg_spec.rb +0 -129
- data/spec/bitcoin/storage_spec.rb +0 -229
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
1
3
|
require_relative '../spec_helper.rb'
|
2
4
|
|
3
5
|
describe 'Bitcoin::Protocol::Parser (version)' do
|
@@ -19,7 +21,7 @@ describe 'Bitcoin::Protocol::Parser (version)' do
|
|
19
21
|
pkt = handler.pkt
|
20
22
|
pkt.fields.should == {
|
21
23
|
:version => 60000,
|
22
|
-
:services =>
|
24
|
+
:services => Bitcoin::Protocol::Version::NODE_NETWORK,
|
23
25
|
:time => 1329775027,
|
24
26
|
:from => "127.0.0.1:18333",
|
25
27
|
:to => "127.0.0.1:57802",
|
@@ -39,12 +41,12 @@ describe 'Bitcoin::Protocol::Parser (version)' do
|
|
39
41
|
pkt = handler.pkt
|
40
42
|
pkt.fields.should == {
|
41
43
|
:version => 40000,
|
42
|
-
:services =>
|
44
|
+
:services => Bitcoin::Protocol::Version::NODE_NETWORK,
|
43
45
|
:time => 1321812496,
|
44
46
|
:from => "127.0.0.1:18333",
|
45
47
|
:to => "127.0.0.1:1234",
|
46
48
|
:nonce => 8210299263586646091,
|
47
|
-
:user_agent =>
|
49
|
+
:user_agent => '',
|
48
50
|
:last_block => 250
|
49
51
|
}
|
50
52
|
end
|
@@ -63,8 +65,8 @@ describe 'Bitcoin::Protocol::Parser (version)' do
|
|
63
65
|
|
64
66
|
pkt = handler.pkt
|
65
67
|
pkt.fields.should == {
|
66
|
-
:version => Bitcoin
|
67
|
-
:services
|
68
|
+
:version => Bitcoin.network[:protocol_version],
|
69
|
+
:services => Bitcoin::Protocol::Version::NODE_NETWORK,
|
68
70
|
:time => 1337,
|
69
71
|
:to => "127.0.0.1:8333",
|
70
72
|
:from => "127.0.0.1:1234",
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
1
3
|
require_relative '../spec_helper.rb'
|
2
4
|
require 'bitcoin/script'
|
3
5
|
|
@@ -6,7 +8,6 @@ describe "Bitcoin::Script OPCODES" do
|
|
6
8
|
before do
|
7
9
|
@script = Bitcoin::Script.new("")
|
8
10
|
@script.class.instance_eval { attr_accessor :stack, :stack_alt }
|
9
|
-
@script.stack << "foobar"
|
10
11
|
end
|
11
12
|
|
12
13
|
def op(op, stack)
|
@@ -16,68 +17,52 @@ describe "Bitcoin::Script OPCODES" do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
it "should do OP_NOP" do
|
19
|
-
|
20
|
-
@script.stack.should == ["foobar"]
|
20
|
+
op(:nop, ["foobar"]).should == ["foobar"]
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should do OP_DUP" do
|
24
|
-
|
25
|
-
@script.stack.should == ["foobar", "foobar"]
|
24
|
+
op(:dup, ["foobar"]).should == ["foobar", "foobar"]
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should do OP_SHA256" do
|
29
|
-
|
30
|
-
@script.stack.should ==
|
31
|
-
[["c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"].pack("H*")]
|
28
|
+
op(:sha256, ["foobar"]).should == [["c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"].pack("H*")]
|
32
29
|
end
|
33
30
|
|
34
31
|
it "should do OP_SHA1" do
|
35
|
-
|
36
|
-
@script.stack.should ==
|
37
|
-
[["8843d7f92416211de9ebb963ff4ce28125932878"].pack("H*")]
|
32
|
+
op(:sha1, ["foobar"]).should == [["8843d7f92416211de9ebb963ff4ce28125932878"].pack("H*")]
|
38
33
|
end
|
39
34
|
|
40
35
|
it "should do OP_HASH160" do
|
41
|
-
|
42
|
-
@script.stack.should ==
|
43
|
-
[["f6c97547d73156abb300ae059905c4acaadd09dd"].pack("H*")]
|
36
|
+
op(:hash160, ["foobar"]).should == [["f6c97547d73156abb300ae059905c4acaadd09dd"].pack("H*")]
|
44
37
|
end
|
45
38
|
|
46
39
|
it "should do OP_RIPEMD160" do
|
47
|
-
|
48
|
-
@script.stack.should ==
|
49
|
-
[["a06e327ea7388c18e4740e350ed4e60f2e04fc41"].pack("H*")]
|
40
|
+
op(:ripemd160, ["foobar"]).should == [["a06e327ea7388c18e4740e350ed4e60f2e04fc41"].pack("H*")]
|
50
41
|
end
|
51
42
|
|
52
43
|
it "should do OP_HASH256" do
|
53
|
-
|
54
|
-
@script.stack.should ==
|
55
|
-
[["3f2c7ccae98af81e44c0ec419659f50d8b7d48c681e5d57fc747d0461e42dda1"].pack("H*")]
|
44
|
+
op(:hash256, ["foobar"]).should == [["3f2c7ccae98af81e44c0ec419659f50d8b7d48c681e5d57fc747d0461e42dda1"].pack("H*")]
|
56
45
|
end
|
57
46
|
|
58
47
|
it "should do OP_TOALTSTACK" do
|
59
|
-
|
60
|
-
@script.stack.should == []
|
48
|
+
op(:toaltstack, ["foobar"]).should == []
|
61
49
|
@script.stack_alt.should == ["foobar"]
|
62
50
|
end
|
63
51
|
|
64
52
|
it "should do OP_FROMALTSTACK" do
|
65
|
-
@script.instance_eval { @
|
53
|
+
@script.instance_eval { @stack = [] }
|
54
|
+
@script.instance_eval { @stack_alt = ["foo"] }
|
66
55
|
@script.op_fromaltstack
|
67
|
-
@script.stack.should == ["
|
56
|
+
@script.stack.should == ["foo"]
|
68
57
|
@script.stack_alt.should == []
|
69
58
|
end
|
70
59
|
|
71
60
|
it "should do OP_TUCK" do
|
72
|
-
|
73
|
-
@script.op_tuck
|
74
|
-
@script.stack.should == ["foobar", "bar", "foo", "bar"]
|
61
|
+
op(:tuck, ["foobar", "foo", "bar"]).should == ["foobar", "bar", "foo", "bar"]
|
75
62
|
end
|
76
63
|
|
77
64
|
it "should do OP_SWAP" do
|
78
|
-
|
79
|
-
@script.op_swap
|
80
|
-
@script.stack.should == ["barfoo", "foobar"]
|
65
|
+
op(:swap, ["foo", "bar"]).should == ["bar", "foo"]
|
81
66
|
end
|
82
67
|
|
83
68
|
it "should do OP_BOOLAND" do
|
@@ -94,20 +79,19 @@ describe "Bitcoin::Script OPCODES" do
|
|
94
79
|
end
|
95
80
|
|
96
81
|
it "should do OP_SUB" do
|
97
|
-
op(:sub, [
|
98
|
-
op(:sub, [
|
99
|
-
op(:sub, [
|
82
|
+
op(:sub, [3, 2]).should == [1]
|
83
|
+
op(:sub, [9, 1]).should == [8]
|
84
|
+
op(:sub, [1, 3]).should == [-2]
|
100
85
|
end
|
101
86
|
|
102
87
|
it "should do OP_GREATERTHANOREQUAL" do
|
103
|
-
op(:greaterthanorequal, [
|
88
|
+
op(:greaterthanorequal, [2, 1]).should == [1]
|
104
89
|
op(:greaterthanorequal, [2, 2]).should == [1]
|
105
|
-
op(:greaterthanorequal, [
|
90
|
+
op(:greaterthanorequal, [1, 2]).should == [0]
|
106
91
|
end
|
107
92
|
|
108
93
|
it "should do OP_DROP" do
|
109
|
-
|
110
|
-
@script.stack.should == []
|
94
|
+
op(:drop, ["foo"]).should == []
|
111
95
|
end
|
112
96
|
|
113
97
|
it "should do OP_EQUAL" do
|
@@ -128,75 +112,340 @@ describe "Bitcoin::Script OPCODES" do
|
|
128
112
|
end
|
129
113
|
|
130
114
|
it "should do OP_0" do
|
131
|
-
|
132
|
-
@script.stack.should == ["foobar", ""]
|
115
|
+
op("0", ["foo"]).should == ["foo", ""]
|
133
116
|
end
|
134
117
|
|
135
118
|
it "should do OP_1" do
|
136
|
-
|
137
|
-
@script.stack.should == ["foobar", 1]
|
119
|
+
op("1", ["foo"]).should == ["foo", 1]
|
138
120
|
end
|
139
121
|
|
140
122
|
it "should do OP_MIN" do
|
141
123
|
[
|
142
|
-
[4, 5],
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
124
|
+
[[4, 5], 4],
|
125
|
+
[[5, 4], 4],
|
126
|
+
[[4, 4], 4],
|
127
|
+
[["\x04", "\x05"], 4],
|
128
|
+
|
129
|
+
[[1, 0], 0],
|
130
|
+
[[0, 1], 0],
|
131
|
+
[[-1, 0], -1],
|
132
|
+
[[0, -2147483647], -2147483647],
|
133
|
+
].each{|stack, expected|
|
134
|
+
op(:min, stack).should == [expected]
|
147
135
|
}
|
148
136
|
end
|
149
137
|
|
150
138
|
it "should do OP_MAX" do
|
151
139
|
[
|
152
|
-
[4, 5],
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
140
|
+
[[4, 5], 5],
|
141
|
+
[[5, 4], 5],
|
142
|
+
[[4, 4], 4],
|
143
|
+
[["\x04", "\x05"], 5],
|
144
|
+
|
145
|
+
[[2147483647, 0], 2147483647],
|
146
|
+
[[0, 100], 100],
|
147
|
+
[[-100, 0], 0],
|
148
|
+
[[0, -2147483647], 0],
|
149
|
+
].each{|stack, expected|
|
150
|
+
op(:max, stack).should == [expected]
|
157
151
|
}
|
158
152
|
end
|
159
|
-
|
153
|
+
|
160
154
|
it "should do op_2over" do
|
161
|
-
|
162
|
-
@script.op_2over
|
163
|
-
@script.stack.should == [1,2,3,4,1,2]
|
155
|
+
op('2over', [1,2,3,4]).should == [1,2,3,4,1,2]
|
164
156
|
end
|
165
|
-
|
157
|
+
|
166
158
|
it "should do op_2swap" do
|
167
|
-
|
168
|
-
@script.op_2swap
|
169
|
-
@script.stack.should == [3,4,1,2]
|
159
|
+
op("2swap", [1,2,3,4]).should == [3,4,1,2]
|
170
160
|
end
|
171
|
-
|
161
|
+
|
172
162
|
it "should do op_ifdup" do
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
@script.instance_eval { @stack = ['a'] }
|
178
|
-
@script.op_ifdup
|
179
|
-
@script.stack.should == ['a','a']
|
180
|
-
|
181
|
-
@script.instance_eval { @stack = [0] }
|
182
|
-
@script.op_ifdup
|
183
|
-
@script.stack.should == [0]
|
163
|
+
op(:ifdup, [1]).should == [1,1]
|
164
|
+
op(:ifdup, ['a']).should == ['a','a']
|
165
|
+
op(:ifdup, [0]).should == [0]
|
184
166
|
end
|
185
167
|
|
186
168
|
it "should do op_1negate" do
|
187
|
-
|
188
|
-
@script.op_1negate
|
189
|
-
@script.stack.should == [ -1 ]
|
169
|
+
op("1negate", []).should == [ -1 ]
|
190
170
|
end
|
191
|
-
|
171
|
+
|
192
172
|
it "should do op_depth" do
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
173
|
+
op(:depth, []).should == [0]
|
174
|
+
op(:depth, [1,2,3]).should == [1,2,3,3]
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should do op_boolor" do
|
178
|
+
[
|
179
|
+
[[ 1, 1], 1],
|
180
|
+
[[ 1, 0], 1],
|
181
|
+
[[ 0, 1], 1],
|
182
|
+
[[ 0, 0], 0],
|
183
|
+
[[16, 17], 1],
|
184
|
+
[[-1, 0], 1],
|
185
|
+
#[[1 ], :invalid],
|
186
|
+
].each{|stack, expected|
|
187
|
+
op(:boolor, stack).should == [ expected ]
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should do op_lessthan" do
|
192
|
+
[
|
193
|
+
[[ 11, 10], 0],
|
194
|
+
[[ 4, 4], 0],
|
195
|
+
[[ 10, 11], 1],
|
196
|
+
[[-11, 11], 1],
|
197
|
+
[[-11,-10], 1],
|
198
|
+
[[ -1, 0], 1],
|
199
|
+
].each{|stack, expected|
|
200
|
+
op(:lessthan, stack).should == [ expected ]
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should do op_lessthanorequal" do
|
205
|
+
[
|
206
|
+
[[ 11, 10], 0],
|
207
|
+
[[ 4, 4], 1],
|
208
|
+
[[ 10, 11], 1],
|
209
|
+
[[-11, 11], 1],
|
210
|
+
[[-11,-10], 1],
|
211
|
+
[[ -1, 0], 1],
|
212
|
+
].each{|stack, expected|
|
213
|
+
op(:lessthanorequal, stack).should == [ expected ]
|
214
|
+
}
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should do op_greaterthan" do
|
218
|
+
[
|
219
|
+
[[ 11, 10], 1],
|
220
|
+
[[ 4, 4], 0],
|
221
|
+
[[ 10, 11], 0],
|
222
|
+
[[-11, 11], 0],
|
223
|
+
[[-11,-10], 0],
|
224
|
+
[[ -1, 0], 0],
|
225
|
+
[[ 1, 0], 1],
|
226
|
+
].each{|stack, expected|
|
227
|
+
op(:greaterthan, stack).should == [expected]
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should do op_greaterthanorequal" do
|
232
|
+
[
|
233
|
+
[[ 11, 10], 1],
|
234
|
+
[[ 4, 4], 1],
|
235
|
+
[[ 10, 11], 0],
|
236
|
+
[[-11, 11], 0],
|
237
|
+
[[-11,-10], 0],
|
238
|
+
[[ -1, 0], 0],
|
239
|
+
[[ 1, 0], 1],
|
240
|
+
[[ 0, 0], 1],
|
241
|
+
].each{|stack, expected|
|
242
|
+
op(:greaterthanorequal, stack).should == [expected]
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should do op_not" do
|
247
|
+
op(:not, [0]).should == [1]
|
248
|
+
op(:not, [1]).should == [0]
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should do op_0notequal" do
|
252
|
+
[
|
253
|
+
[[0], 0],
|
254
|
+
[[1], 1],
|
255
|
+
[[111], 1],
|
256
|
+
[[-111], 1],
|
257
|
+
].each{|stack, expected|
|
258
|
+
op("0notequal", stack).should == [expected]
|
259
|
+
}
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should do op_abs" do
|
263
|
+
[
|
264
|
+
[[0], 0],
|
265
|
+
[[16], 16],
|
266
|
+
[[-16], 16],
|
267
|
+
[[-1], 1],
|
268
|
+
].each{|stack, expected|
|
269
|
+
op(:abs, stack).should == [expected]
|
270
|
+
}
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should do op_2div" do
|
274
|
+
op("2div", [ 2]).should == [ 1]
|
275
|
+
op("2div", [ 10]).should == [ 5]
|
276
|
+
op("2div", [-10]).should == [-5]
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should do op_2mul" do
|
280
|
+
op("2mul", [ 2]).should == [ 4]
|
281
|
+
op("2mul", [ 10]).should == [ 20]
|
282
|
+
op("2mul", [-10]).should == [-20]
|
283
|
+
end
|
284
|
+
|
285
|
+
it "should do op_1add" do
|
286
|
+
op("1add", [ 2]).should == [ 3]
|
287
|
+
op("1add", [ 10]).should == [11]
|
288
|
+
op("1add", [-10]).should == [-9]
|
289
|
+
end
|
290
|
+
|
291
|
+
it "should do op_1sub" do
|
292
|
+
op("1sub", [ 2]).should == [ 1]
|
293
|
+
op("1sub", [ 10]).should == [ 9]
|
294
|
+
op("1sub", [-10]).should == [-11]
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should do op_negate" do
|
298
|
+
op("negate", [-2]).should == [ 2]
|
299
|
+
op("negate", [ 2]).should == [-2]
|
300
|
+
op("negate", [ 0]).should == [ 0]
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should do op_within" do
|
304
|
+
[
|
305
|
+
[[0, 0, 1], 1],
|
306
|
+
[[1, 0, 1], 0],
|
307
|
+
[[0, -2147483647, 2147483647], 1],
|
308
|
+
[[-1, -100, 100], 1],
|
309
|
+
[[11, -100, 100], 1],
|
310
|
+
[[-2147483647, -100, 100], 0],
|
311
|
+
[[2147483647, -100, 100], 0],
|
312
|
+
[[-1, -1, 0], 1],
|
313
|
+
].each{|stack, expected|
|
314
|
+
op(:within, stack).should == [expected]
|
315
|
+
}
|
316
|
+
end
|
317
|
+
|
318
|
+
it "should do op_numequal" do
|
319
|
+
[
|
320
|
+
[[0, 0], 1],
|
321
|
+
[[0, 1], 0],
|
322
|
+
].each{|stack, expected|
|
323
|
+
op(:numequal, stack).should == [expected]
|
324
|
+
}
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should do op_numequalverify" do
|
328
|
+
[
|
329
|
+
[[0, 0], []],
|
330
|
+
[[0, 1], [0]],
|
331
|
+
].each{|stack, expected|
|
332
|
+
op(:numequalverify, stack).should == expected
|
333
|
+
}
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should do op_numnotequal" do
|
337
|
+
[
|
338
|
+
[[0, 0], 0],
|
339
|
+
[[0, 1], 1],
|
340
|
+
].each{|stack, expected|
|
341
|
+
op(:numnotequal, stack).should == [expected]
|
342
|
+
}
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should do op_over" do
|
346
|
+
[
|
347
|
+
[[1, 0], [1,0,1]],
|
348
|
+
[[-1, 1], [-1,1,-1]],
|
349
|
+
[[1], [1]],
|
350
|
+
].each{|stack, expected|
|
351
|
+
op(:over, stack).should == expected
|
352
|
+
}
|
353
|
+
end
|
354
|
+
|
355
|
+
it "should do op_pick" do
|
356
|
+
[
|
357
|
+
[[1, 0, 0, 0, 3], [1,0,0,0,1]],
|
358
|
+
[[1, 0], [1,1]],
|
359
|
+
].each{|stack, expected|
|
360
|
+
op(:pick, stack).should == expected
|
361
|
+
}
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should do op_roll" do
|
365
|
+
[
|
366
|
+
[[1, 0, 0, 0, 3], [0,0,0,1]],
|
367
|
+
[[1, 0], [1]],
|
368
|
+
].each{|stack, expected|
|
369
|
+
op(:roll, stack).should == expected
|
370
|
+
}
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should do op_rot" do
|
374
|
+
op(:rot, [22, 21, 20]).should == [21, 20, 22]
|
375
|
+
op(:rot, [21, 20]).should == [21, 20]
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should do op_2drop" do
|
379
|
+
op('2drop', [1,2,3]).should == [1]
|
380
|
+
op('2drop', [ 2,3]).should == [ ]
|
381
|
+
end
|
382
|
+
|
383
|
+
it "should do op_2dup" do
|
384
|
+
op('2dup', [2,3]).should == [2,3,2,3]
|
385
|
+
op('2dup', [3 ]).should == [ 3 ]
|
386
|
+
end
|
387
|
+
|
388
|
+
it "should do op_3dup" do
|
389
|
+
op('3dup', [1,2,3]).should == [1,2,3,1,2,3]
|
390
|
+
op('3dup', [ 2,3]).should == [ 2,3 ]
|
391
|
+
op('3dup', [ 3]).should == [ 3 ]
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should do op_nip" do
|
395
|
+
op(:nip, [1,2]).should == [2]
|
396
|
+
op(:nip, [1,2,3]).should == [1,3]
|
397
|
+
end
|
398
|
+
|
399
|
+
it "should do op_size" do
|
400
|
+
[
|
401
|
+
[[0], [0,0]],
|
402
|
+
[[1], [1,1]],
|
403
|
+
[[127], [127,1]],
|
404
|
+
[[128], [128,2]],
|
405
|
+
[[32767], [32767,2]],
|
406
|
+
[[32768], [32768,3]],
|
407
|
+
[[8388607], [8388607,3]],
|
408
|
+
[[8388608], [8388608,4]],
|
409
|
+
[[2147483647], [2147483647,4]],
|
410
|
+
[[2147483648], [2147483648,5]],
|
411
|
+
[[-1], [-1,1]],
|
412
|
+
[[-127], [-127,1]],
|
413
|
+
[[-128], [-128,2]],
|
414
|
+
[[-32767], [-32767,2]],
|
415
|
+
[[-32768], [-32768,3]],
|
416
|
+
[[-8388607], [-8388607,3]],
|
417
|
+
[[-8388608], [-8388608,4]],
|
418
|
+
[[-2147483647], [-2147483647,4]],
|
419
|
+
[[-2147483648], [-2147483648,5]],
|
420
|
+
[["abcdefghijklmnopqrstuvwxyz"], ["abcdefghijklmnopqrstuvwxyz",26]],
|
421
|
+
].each{|stack, expected|
|
422
|
+
op(:size, stack).should == expected
|
423
|
+
}
|
424
|
+
end
|
425
|
+
|
426
|
+
it "should do if/notif/else/end" do
|
427
|
+
[
|
428
|
+
"1 1 OP_IF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ENDIF",
|
429
|
+
"1 0 OP_IF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ENDIF",
|
430
|
+
"1 1 OP_IF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ELSE OP_IF 0 OP_ELSE 1 OP_ENDIF OP_ENDIF",
|
431
|
+
"0 0 OP_IF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ELSE OP_IF 0 OP_ELSE 1 OP_ENDIF OP_ENDIF",
|
432
|
+
"1 1 OP_NOTIF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ENDIF",
|
433
|
+
"1 0 OP_NOTIF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ENDIF",
|
434
|
+
"1 0 OP_NOTIF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ELSE OP_IF 0 OP_ELSE 1 OP_ENDIF OP_ENDIF",
|
435
|
+
"0 1 OP_NOTIF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ELSE OP_IF 0 OP_ELSE 1 OP_ENDIF OP_ENDIF",
|
436
|
+
"0 OP_IF OP_RETURN OP_ENDIF 1",
|
437
|
+
"1 OP_IF 1 OP_ENDIF",
|
438
|
+
"0 OP_IF 50 OP_ENDIF 1",
|
439
|
+
"0 OP_IF OP_VER OP_ELSE 1 OP_ENDIF",
|
440
|
+
"0 OP_IF 50 40 OP_ELSE 1 OP_ENDIF",
|
441
|
+
"1 OP_DUP OP_IF OP_ENDIF",
|
442
|
+
"1 OP_IF 1 OP_ENDIF",
|
443
|
+
"1 OP_DUP OP_IF OP_ELSE OP_ENDIF",
|
444
|
+
"1 OP_IF 1 OP_ELSE OP_ENDIF",
|
445
|
+
"0 OP_IF OP_ELSE 1 OP_ENDIF",
|
446
|
+
].each{|script|
|
447
|
+
Bitcoin::Script.from_string(script).run.should == true
|
448
|
+
}
|
200
449
|
end
|
201
450
|
|
202
451
|
it "should do OP_CHECKSIG" do
|
@@ -287,6 +536,9 @@ describe "Bitcoin::Script OPCODES" do
|
|
287
536
|
sig2 = (k2.sign("foobar") + "\x01").unpack("H*")[0]
|
288
537
|
sig3 = (k3.sign("foobar") + "\x01").unpack("H*")[0]
|
289
538
|
|
539
|
+
script = "0 #{sig1} 1 #{k1.pub} 1 OP_CHECKMULTISIG"
|
540
|
+
run_script(script, "foobar").should == true
|
541
|
+
|
290
542
|
script = "0 #{sig1} #{sig2} 2 #{k1.pub} #{k2.pub} 2 OP_CHECKMULTISIG"
|
291
543
|
run_script(script, "foobar").should == true
|
292
544
|
|
@@ -335,6 +587,15 @@ describe "Bitcoin::Script OPCODES" do
|
|
335
587
|
script = "0 #{sig1} f0f0f0f0 #{sig3} 3 #{k1.pub} #{k2.pub} #{k3.pub} 3 OP_CHECKMULTISIG"
|
336
588
|
run_script(script, "foobar").should == false
|
337
589
|
|
590
|
+
# mainnet tx output: 514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58
|
591
|
+
script = "0 #{sig1} 1 0 #{k1.pub} OP_SWAP OP_1ADD OP_CHECKMULTISIG"
|
592
|
+
run_script(script, "foobar").should == true
|
593
|
+
Bitcoin::Script.from_string(script).get_addresses.should == []
|
594
|
+
Bitcoin::Script.from_string(script).is_multisig?.should == false
|
595
|
+
script = "#{k1.pub} OP_SWAP OP_1ADD OP_CHECKMULTISIG"
|
596
|
+
Bitcoin::Script.from_string(script).get_addresses.should == []
|
597
|
+
Bitcoin::Script.from_string(script).is_multisig?.should == false
|
598
|
+
|
338
599
|
# # TODO: check signature order; these assertions should fail:
|
339
600
|
# script = "0 #{sig2} #{sig1} 2 #{k1.pub} #{k2.pub} #{k3.pub} 3 OP_CHECKMULTISIG"
|
340
601
|
# run_script(script, "foobar").should == false
|
@@ -344,57 +605,6 @@ describe "Bitcoin::Script OPCODES" do
|
|
344
605
|
# run_script(script, "foobar").should == false
|
345
606
|
end
|
346
607
|
|
347
|
-
|
348
|
-
it "should do OP_CHECKHASHVERIFY" do # https://en.bitcoin.it/wiki/BIP_0017
|
349
|
-
k1 = Bitcoin::Key.new; k1.generate
|
350
|
-
k2 = Bitcoin::Key.new; k2.generate
|
351
|
-
k3 = Bitcoin::Key.new; k2.generate
|
352
|
-
sig1 = (k1.sign("foobar") + "\x01").unpack("H*")[0]
|
353
|
-
sig2 = (k2.sign("foobar") + "\x01").unpack("H*")[0]
|
354
|
-
sig3 = (k2.sign("foobar") + "\x01").unpack("H*")[0]
|
355
|
-
|
356
|
-
|
357
|
-
# scriptSig: [signatures...] OP_CODESEPARATOR 1 [pubkey1] [pubkey2] 2 OP_CHECKMULTISIG
|
358
|
-
# scriptPubKey: [20-byte-hash of {1 [pubkey1] [pubkey2] 2 OP_CHECKMULTISIG} ] OP_CHECKHASHVERIFY OP_DROP
|
359
|
-
script = "1 #{k1.pub} #{k2.pub} 2 OP_CHECKMULTISIG"
|
360
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
361
|
-
script = "0 #{sig1} OP_CODESEPARATOR #{script} #{checkhash} OP_CHECKHASHVERIFY OP_DROP"
|
362
|
-
run_script(script, "foobar").should == true
|
363
|
-
|
364
|
-
script = "1 #{k1.pub} #{k2.pub} 2 OP_CHECKMULTISIG"
|
365
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
366
|
-
script = "0 #{sig1} OP_CODESEPARATOR #{script} #{checkhash} OP_NOP2 OP_DROP" # tests OP_NOP2 as OP_CHECKHASHVERIFY
|
367
|
-
run_script(script, "foobar").should == true
|
368
|
-
|
369
|
-
# invalid checkhashverify
|
370
|
-
script = "1 #{k1.pub} #{k2.pub} 2 OP_CHECKMULTISIG"
|
371
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
372
|
-
script = "1 #{k1.pub} #{k3.pub} 2 OP_CHECKMULTISIG"
|
373
|
-
script = "0 #{sig1} OP_CODESEPARATOR #{script} #{checkhash} OP_NOP2 OP_DROP" # tests OP_NOP2 as OP_CHECKHASHVERIFY
|
374
|
-
run_script(script, "foobar").should == false
|
375
|
-
|
376
|
-
|
377
|
-
# scriptSig: [signature] OP_CODESEPARATOR [pubkey] OP_CHECKSIG
|
378
|
-
# scriptPubKey: [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_CHECKHASHVERIFY OP_DROP
|
379
|
-
script = "#{k1.pub} OP_CHECKSIG"
|
380
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
381
|
-
script = "#{sig1} OP_CODESEPARATOR #{script} #{checkhash} OP_CHECKHASHVERIFY OP_DROP"
|
382
|
-
run_script(script, "foobar").should == true
|
383
|
-
|
384
|
-
# invalid checkhashverify
|
385
|
-
script = "#{k2.pub} OP_CHECKSIG"
|
386
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
387
|
-
script = "#{k1.pub} OP_CHECKSIG"
|
388
|
-
script = "#{sig1} OP_CODESEPARATOR #{script} #{checkhash} OP_CHECKHASHVERIFY OP_DROP"
|
389
|
-
run_script(script, "foobar").should == false
|
390
|
-
|
391
|
-
# invalid signature in checksig
|
392
|
-
script = "#{k1.pub} OP_CHECKSIG"
|
393
|
-
checkhash = Bitcoin.hash160(Bitcoin::Script.binary_from_string(script).unpack("H*")[0])
|
394
|
-
script = "#{sig2} OP_CODESEPARATOR #{script} #{checkhash} OP_CHECKHASHVERIFY OP_DROP"
|
395
|
-
run_script(script, "foobar").should == false
|
396
|
-
end
|
397
|
-
|
398
608
|
it "should do P2SH" do
|
399
609
|
k1 = Bitcoin::Key.new; k1.generate
|
400
610
|
sig = (k1.sign("foobar") + "\x01").unpack("H*")[0]
|
@@ -405,6 +615,10 @@ describe "Bitcoin::Script OPCODES" do
|
|
405
615
|
run_script(script.to_string, "foobar").should == true
|
406
616
|
run_script(script.to_string, "barbaz").should == false
|
407
617
|
|
618
|
+
script = Bitcoin::Script.from_string("0 #{sig} #{inner_script} OP_HASH160 #{script_hash} OP_EQUAL")
|
619
|
+
script.is_p2sh?.should == true
|
620
|
+
run_script(script.to_string, "foobar").should == true
|
621
|
+
|
408
622
|
script = Bitcoin::Script.from_string("OP_HASH160 #{script_hash} OP_EQUAL")
|
409
623
|
script.is_p2sh?.should == true
|
410
624
|
run_script(script.to_string, "foobar").should == false
|
@@ -414,4 +628,69 @@ describe "Bitcoin::Script OPCODES" do
|
|
414
628
|
script.type.should == :p2sh
|
415
629
|
end
|
416
630
|
|
631
|
+
it "should skip OP_EVAL" do
|
632
|
+
Bitcoin::Script.from_string("1 OP_EVAL").to_string.should == "1 OP_NOP1"
|
633
|
+
Bitcoin::Script.from_string("1 OP_EVAL").run.should == true
|
634
|
+
Bitcoin::Script.from_string("0 OP_EVAL").run.should == false
|
635
|
+
end
|
636
|
+
|
637
|
+
it "should do testnet3 scripts" do
|
638
|
+
[
|
639
|
+
"OP_1NEGATE OP_1NEGATE OP_ADD 82 OP_EQUAL",
|
640
|
+
"6f 1 OP_ADD 12 OP_SUB 64 OP_EQUAL",
|
641
|
+
"76:1:07 7 OP_EQUAL",
|
642
|
+
"OP_1NEGATE e4 64 OP_WITHIN",
|
643
|
+
"0 ffffffff ffffff7f OP_WITHIN",
|
644
|
+
"6162636465666768696a6b6c6d6e6f707172737475767778797a OP_SIZE 1a OP_EQUAL",
|
645
|
+
"0 OP_IFDUP OP_DEPTH 1 OP_EQUALVERIFY 0 OP_EQUAL",
|
646
|
+
"1 OP_NOP1 OP_CHECKHASHVERIFY OP_NOP3 OP_NOP4 OP_NOP5 OP_NOP6 OP_NOP7 OP_NOP8 OP_NOP9 OP_NOP10 1 OP_EQUAL",
|
647
|
+
"1 OP_NOP1 OP_NOP2 OP_NOP3 OP_NOP4 OP_NOP5 OP_NOP6 OP_NOP7 OP_NOP8 OP_NOP9 OP_NOP10 1 OP_EQUAL",
|
648
|
+
"0 ffffffff ffffff7f OP_WITHIN",
|
649
|
+
"0:1:16 0:1:15 0:1:14 OP_ROT OP_ROT 0:1:15 OP_EQUAL",
|
650
|
+
"ffffff7f OP_NEGATE OP_DUP OP_ADD feffffff80 OP_EQUAL",
|
651
|
+
"90 OP_ABS 90 OP_NEGATE OP_EQUAL",
|
652
|
+
"0 OP_DROP OP_DEPTH 0 OP_EQUAL",
|
653
|
+
"1 0 OP_NOTIF OP_IF 1 OP_ELSE 0 OP_ENDIF OP_ELSE OP_IF 0 OP_ELSE 1 OP_ENDIF OP_ENDIF",
|
654
|
+
"6f OP_1SUB 6e OP_EQUAL",
|
655
|
+
"13 14 OP_2DUP OP_ROT OP_EQUALVERIFY OP_EQUAL",
|
656
|
+
"10 0 11 OP_TOALTSTACK OP_DROP OP_FROMALTSTACK OP_ADD 0:1:15 OP_EQUAL",
|
657
|
+
"ffffff7f OP_DUP OP_ADD feffffff00 OP_EQUAL",
|
658
|
+
"77:1:08 8 OP_EQUAL",
|
659
|
+
"1 OP_NOT 0 OP_EQUAL",
|
660
|
+
"0 OP_DROP OP_DEPTH 0 OP_EQUAL",
|
661
|
+
"6f 1 OP_ADD 12 OP_SUB 64 OP_EQUAL",
|
662
|
+
"0:1:0b 11 OP_EQUAL",
|
663
|
+
"13 14 OP_2DUP OP_ROT OP_EQUALVERIFY OP_EQUAL",
|
664
|
+
"ffffff7f OP_DUP OP_ADD feffffff00 OP_EQUAL",
|
665
|
+
"0 OP_DROP OP_DEPTH 0 OP_EQUAL",
|
666
|
+
"0 ffffffff OP_MIN ffffffff OP_NUMEQUAL",
|
667
|
+
"90 OP_ABS 90 OP_NEGATE OP_EQUAL",
|
668
|
+
"OP_1NEGATE e803 OP_ADD e703 OP_EQUAL",
|
669
|
+
"0:1:16 0:1:15 0:1:14 OP_ROT OP_ROT OP_ROT 0:1:14 OP_EQUAL",
|
670
|
+
"13 14 OP_2DUP OP_ROT OP_EQUALVERIFY OP_EQUAL",
|
671
|
+
"8b 11 OP_LESSTHANOREQUAL",
|
672
|
+
"ffffff7f ffffffff OP_ADD 0 OP_EQUAL",
|
673
|
+
"ffffff7f OP_NEGATE OP_DUP OP_ADD feffffff80 OP_EQUAL",
|
674
|
+
"8b 11 OP_GREATERTHANOREQUAL OP_NOT",
|
675
|
+
"0 OP_0NOTEQUAL 0 OP_EQUAL",
|
676
|
+
"2 82 OP_ADD 0 OP_EQUAL",
|
677
|
+
].each{|script|
|
678
|
+
Bitcoin::Script.from_string(script).run.should == true
|
679
|
+
}
|
680
|
+
end
|
681
|
+
|
682
|
+
it "should do OP_VER" do
|
683
|
+
s = Bitcoin::Script.from_string("OP_VER"); s.run; s.invalid?.should == true
|
684
|
+
s = Bitcoin::Script.from_string("1 OP_IF OP_VER 1 OP_ELSE 0 OP_ENDIF"); s.run.should == false; s.invalid?.should == true
|
685
|
+
s = Bitcoin::Script.from_string("1 OP_IF 1 OP_ELSE OP_VER 0 OP_ENDIF"); s.run.should == true; s.invalid?.should == false
|
686
|
+
end
|
687
|
+
|
688
|
+
it "should not allow DISABLED_OPCODES" do
|
689
|
+
Bitcoin::Script::DISABLED_OPCODES.each{|opcode|
|
690
|
+
s = Bitcoin::Script.from_string(Bitcoin::Script::OPCODES[opcode] + " 1"); s.run.should == false; s.invalid?.should == true
|
691
|
+
s = Bitcoin::Script.from_string("1 OP_IF #{Bitcoin::Script::OPCODES[opcode]} 1 OP_ELSE 1 OP_ENDIF"); s.run.should == false; s.invalid?.should == true
|
692
|
+
s = Bitcoin::Script.from_string("1 OP_IF 1 OP_ELSE #{Bitcoin::Script::OPCODES[opcode]} 1 OP_ENDIF"); s.run.should == false; s.invalid?.should == true
|
693
|
+
}
|
694
|
+
end
|
695
|
+
|
417
696
|
end
|