bitcoin-ruby 0.0.1 → 0.0.2
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.
- 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
|