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.
Files changed (136) hide show
  1. data/.gitignore +4 -1
  2. data/Gemfile +21 -0
  3. data/README.rdoc +85 -25
  4. data/Rakefile +7 -3
  5. data/bin/bitcoin_node +39 -42
  6. data/bin/bitcoin_shell +1 -0
  7. data/bin/bitcoin_wallet +129 -53
  8. data/bitcoin-ruby.gemspec +4 -7
  9. data/concept-examples/blockchain-pow.rb +1 -1
  10. data/doc/CONFIG.rdoc +5 -5
  11. data/doc/EXAMPLES.rdoc +9 -5
  12. data/doc/NAMECOIN.rdoc +34 -0
  13. data/doc/NODE.rdoc +147 -10
  14. data/examples/balance.rb +10 -4
  15. data/examples/bbe_verify_tx.rb +7 -2
  16. data/examples/forwarder.rb +73 -0
  17. data/examples/generate_tx.rb +34 -0
  18. data/examples/simple_network_monitor_and_util.rb +187 -0
  19. data/examples/verify_tx.rb +1 -1
  20. data/lib/bitcoin.rb +308 -18
  21. data/lib/bitcoin/builder.rb +62 -36
  22. data/lib/bitcoin/config.rb +2 -0
  23. data/lib/bitcoin/connection.rb +11 -8
  24. data/lib/bitcoin/electrum/mnemonic.rb +162 -0
  25. data/lib/bitcoin/ffi/openssl.rb +187 -21
  26. data/lib/bitcoin/gui/addr_view.rb +2 -0
  27. data/lib/bitcoin/gui/conn_view.rb +2 -0
  28. data/lib/bitcoin/gui/connection.rb +2 -0
  29. data/lib/bitcoin/gui/em_gtk.rb +2 -0
  30. data/lib/bitcoin/gui/gui.rb +2 -0
  31. data/lib/bitcoin/gui/helpers.rb +2 -0
  32. data/lib/bitcoin/gui/tree_view.rb +2 -0
  33. data/lib/bitcoin/gui/tx_view.rb +2 -0
  34. data/lib/bitcoin/key.rb +77 -11
  35. data/lib/bitcoin/litecoin.rb +81 -0
  36. data/lib/bitcoin/logger.rb +20 -1
  37. data/lib/bitcoin/namecoin.rb +279 -0
  38. data/lib/bitcoin/network/command_client.rb +7 -6
  39. data/lib/bitcoin/network/command_handler.rb +229 -43
  40. data/lib/bitcoin/network/connection_handler.rb +182 -70
  41. data/lib/bitcoin/network/node.rb +231 -106
  42. data/lib/bitcoin/protocol.rb +44 -23
  43. data/lib/bitcoin/protocol/address.rb +5 -3
  44. data/lib/bitcoin/protocol/alert.rb +3 -4
  45. data/lib/bitcoin/protocol/aux_pow.rb +123 -0
  46. data/lib/bitcoin/protocol/block.rb +98 -18
  47. data/lib/bitcoin/protocol/handler.rb +6 -5
  48. data/lib/bitcoin/protocol/parser.rb +44 -19
  49. data/lib/bitcoin/protocol/tx.rb +105 -52
  50. data/lib/bitcoin/protocol/txin.rb +39 -19
  51. data/lib/bitcoin/protocol/txout.rb +28 -13
  52. data/lib/bitcoin/protocol/version.rb +16 -7
  53. data/lib/bitcoin/script.rb +579 -122
  54. data/lib/bitcoin/storage/{dummy.rb → dummy/dummy_store.rb} +8 -14
  55. data/lib/bitcoin/storage/models.rb +20 -7
  56. data/lib/bitcoin/storage/{sequel_store/sequel_migrations.rb → sequel/migrations.rb} +22 -7
  57. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +52 -0
  58. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +50 -0
  59. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +18 -0
  60. data/lib/bitcoin/storage/sequel/sequel_store.rb +436 -0
  61. data/lib/bitcoin/storage/storage.rb +233 -28
  62. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +52 -0
  63. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +18 -0
  64. data/lib/bitcoin/storage/utxo/utxo_store.rb +361 -0
  65. data/lib/bitcoin/validation.rb +369 -0
  66. data/lib/bitcoin/version.rb +1 -1
  67. data/lib/bitcoin/wallet/coinselector.rb +3 -0
  68. data/lib/bitcoin/wallet/keygenerator.rb +3 -1
  69. data/lib/bitcoin/wallet/keystore.rb +6 -2
  70. data/lib/bitcoin/wallet/txdp.rb +6 -4
  71. data/lib/bitcoin/wallet/wallet.rb +54 -16
  72. data/spec/bitcoin/bitcoin_spec.rb +48 -3
  73. data/spec/bitcoin/builder_spec.rb +40 -17
  74. data/spec/bitcoin/fixtures/000000000000056b1a3d84a1e2b33cde8915a4b61c0cae14fca6d3e1490b4f98.json +3697 -0
  75. data/spec/bitcoin/fixtures/03d7e1fa4d5fefa169431f24f7798552861b255cd55d377066fedcd088fb0e99.json +23 -0
  76. data/spec/bitcoin/fixtures/0961c660358478829505e16a1f028757e54b5bbf9758341a7546573738f31429.json +24 -0
  77. data/spec/bitcoin/fixtures/0f24294a1d23efbb49c1765cf443fba7930702752aba6d765870082fe4f13cae.json +37 -0
  78. data/spec/bitcoin/fixtures/315ac7d4c26d69668129cc352851d9389b4a6868f1509c6c8b66bead11e2619f.json +31 -0
  79. data/spec/bitcoin/fixtures/35e2001b428891fefa0bfb73167c7360669d3cbd7b3aa78e7cad125ddfc51131.json +27 -0
  80. data/spec/bitcoin/fixtures/3a17dace09ffb919ed627a93f1873220f4c975c1248558b18d16bce25d38c4b7.json +72 -0
  81. data/spec/bitcoin/fixtures/3e58b7eed0fdb599019af08578effea25c8666bbe8e200845453cacce6314477.json +27 -0
  82. data/spec/bitcoin/fixtures/514c46f0b61714092f15c8dfcb576c9f79b3f959989b98de3944b19d98832b58.json +24 -0
  83. data/spec/bitcoin/fixtures/51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e.json +30 -0
  84. data/spec/bitcoin/fixtures/69216b8aaa35b76d6613e5f527f4858640d986e1046238583bdad79b35e938dc.json +28 -0
  85. data/spec/bitcoin/fixtures/7208e5edf525f04e705fb3390194e316205b8f995c8c9fcd8c6093abe04fa27d.json +27 -0
  86. data/spec/bitcoin/fixtures/761d8c5210fdfd505f6dff38f740ae3728eb93d7d0971fb433f685d40a4c04f6.json +27 -0
  87. data/spec/bitcoin/fixtures/aea682d68a3ea5e3583e088dcbd699a5d44d4b083f02ad0aaf2598fe1fa4dfd4.json +27 -0
  88. data/spec/bitcoin/fixtures/bd1715f1abfdc62bea3f605bdb461b3ba1f2cca6ec0d73a18a548b7717ca8531.json +34 -0
  89. data/spec/bitcoin/fixtures/block-testnet-0000000000ac85bb2530a05a4214a387e6be02b22d3348abc5e7a5d9c4ce8dab.bin +0 -0
  90. data/spec/bitcoin/fixtures/cd874fa8cb0e2ec2d385735d5e1fd482c4fe648533efb4c50ee53bda58e15ae2.json +24 -0
  91. data/spec/bitcoin/fixtures/ce5fad9b4ef094d8f4937b0707edaf0a6e6ceeaf67d5edbfd51f660eac8f398b.json +41 -0
  92. data/spec/bitcoin/fixtures/f003f0c1193019db2497a675fd05d9f2edddf9b67c59e677c48d3dbd4ed5f00b.json +23 -0
  93. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  94. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +43 -0
  95. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  96. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +67 -0
  97. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.bin +0 -0
  98. data/spec/bitcoin/fixtures/litecoin-block-80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f.json +39 -0
  99. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.bin +0 -0
  100. data/spec/bitcoin/fixtures/litecoin-genesis-block-12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2.json +39 -0
  101. data/spec/bitcoin/fixtures/rawblock-auxpow.bin +0 -0
  102. data/spec/bitcoin/fixtures/tx-313897799b1e37e9ecae15010e56156dddde4e683c96b0e713af95272c38aee0.json +30 -0
  103. data/spec/bitcoin/fixtures/tx-3da75972766f0ad13319b0b461fd16823a731e44f6e9de4eb3c52d6a6fb6c8ae.json +23 -0
  104. data/spec/bitcoin/fixtures/tx-44b833074e671120ba33106877b49e86ece510824b9af477a3853972bcd8d06a.json +30 -0
  105. data/spec/bitcoin/fixtures/tx-d3d77d63709e47d9ef58f0b557800115a6b676c6a423012fbb96f45d8fcef830.json +28 -0
  106. data/spec/bitcoin/key_spec.rb +128 -3
  107. data/spec/bitcoin/namecoin_spec.rb +182 -0
  108. data/spec/bitcoin/network_spec.rb +5 -3
  109. data/spec/bitcoin/node/command_api_spec.rb +376 -0
  110. data/spec/bitcoin/protocol/addr_spec.rb +2 -0
  111. data/spec/bitcoin/protocol/alert_spec.rb +2 -0
  112. data/spec/bitcoin/protocol/aux_pow_spec.rb +44 -0
  113. data/spec/bitcoin/protocol/block_spec.rb +134 -39
  114. data/spec/bitcoin/protocol/getblocks_spec.rb +32 -0
  115. data/spec/bitcoin/protocol/inv_spec.rb +10 -8
  116. data/spec/bitcoin/protocol/notfound_spec.rb +31 -0
  117. data/spec/bitcoin/protocol/ping_spec.rb +2 -0
  118. data/spec/bitcoin/protocol/tx_spec.rb +83 -17
  119. data/spec/bitcoin/protocol/version_spec.rb +7 -5
  120. data/spec/bitcoin/script/opcodes_spec.rb +412 -133
  121. data/spec/bitcoin/script/script_spec.rb +112 -13
  122. data/spec/bitcoin/spec_helper.rb +68 -0
  123. data/spec/bitcoin/storage/reorg_spec.rb +199 -0
  124. data/spec/bitcoin/storage/storage_spec.rb +337 -0
  125. data/spec/bitcoin/storage/validation_spec.rb +261 -0
  126. data/spec/bitcoin/wallet/coinselector_spec.rb +10 -7
  127. data/spec/bitcoin/wallet/keygenerator_spec.rb +2 -0
  128. data/spec/bitcoin/wallet/keystore_spec.rb +2 -0
  129. data/spec/bitcoin/wallet/txdp_spec.rb +2 -0
  130. data/spec/bitcoin/wallet/wallet_spec.rb +91 -58
  131. metadata +105 -51
  132. data/lib/bitcoin/storage/sequel.rb +0 -335
  133. data/spec/bitcoin/fixtures/0d0affb5964abe804ffe85e53f1dbb9f29e406aa3046e2db04fba240e63c7fdd.json +0 -27
  134. data/spec/bitcoin/fixtures/477fff140b363ec2cc51f3a65c0c58eda38f4d41f04a295bbd62babf25e4c590.json +0 -27
  135. data/spec/bitcoin/reorg_spec.rb +0 -129
  136. data/spec/bitcoin/storage_spec.rb +0 -229
@@ -1,229 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- [
4
- # { :name => :dummy },
5
- { :name => :sequel, :db => 'sqlite:/' }, # in memory
6
- # { :name => :sequel, :db => 'sqlite:///tmp/bitcoin_test.db' },
7
- # { :name => :sequel, :db => 'postgres://localhost/bitcoin_test' },
8
- ].each do |configuration|
9
- describe "Bitcoin::Storage::Backends::#{configuration[:name].capitalize}Store" do
10
-
11
- before do
12
- Bitcoin::network = :testnet
13
- Bitcoin::Storage.log.level = 3
14
- @store = Bitcoin::Storage.send(configuration[:name], configuration)
15
- @store.reset
16
-
17
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')))
18
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')))
19
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')))
20
- @store.store_block(Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_3.bin')))
21
-
22
- @store.store_tx(Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-01.bin')))
23
- @store.store_tx(Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-02.bin')))
24
-
25
-
26
- @blk = Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_4.bin'))
27
- @tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-03.bin'))
28
- end
29
-
30
- it "should get depth" do
31
- @store.get_depth.should == 3
32
- end
33
-
34
- it "should report depth as -1 if store is empty" do
35
- @store.reset
36
- @store.get_depth.should == -1
37
- end
38
-
39
- it "should get head" do
40
- @store.get_head
41
- .should == @store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
42
- end
43
-
44
- it "should get locator" do
45
- @store.get_locator.should == [
46
- "0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4",
47
- "000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f",
48
- "000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604",
49
- "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008"]
50
- end
51
-
52
- it "should not store if there is no prev block" do
53
- @store.reset
54
- @store.store_block(@blk).should == [0, 2]
55
- @store.get_depth.should == -1
56
- end
57
-
58
- it "should check whether block is already stored" do
59
- @store.has_block(@blk.hash).should == false
60
- @store.store_block(@blk)
61
- @store.has_block(@blk.hash).should == true
62
- end
63
-
64
- it "should get block by depth" do
65
- @store.get_block_by_depth(0).to_hash.should ==
66
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')).to_hash
67
- @store.get_block_by_depth(1).to_hash.should ==
68
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')).to_hash
69
- @store.get_block_by_depth(2).to_hash.should ==
70
- Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')).to_hash
71
- end
72
-
73
- it "should get block by hash" do
74
- @store.get_block(
75
- "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008").to_hash
76
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_0.bin')).to_hash
77
- @store.get_block(
78
- "000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604").to_hash
79
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_1.bin')).to_hash
80
- @store.get_block(
81
- "000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f").to_hash
82
- .should == Bitcoin::Protocol::Block.new(fixtures_file('testnet/block_2.bin')).to_hash
83
- end
84
-
85
- it "should not get block" do
86
- @store.get_block("nonexistant").should == nil
87
- end
88
-
89
- it "should get block depth" do
90
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
91
- .depth.should == 0
92
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
93
- .depth.should == 1
94
- @store.get_block("000000037b21cac5d30fc6fda2581cf7b2612908aed2abbcc429c45b0557a15f")
95
- .depth.should == 2
96
- end
97
-
98
- it "should get prev block" do
99
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
100
- .get_prev_block.should == nil
101
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
102
- .get_prev_block.should ==
103
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
104
- end
105
-
106
- it "should get next block" do
107
- @store.get_block("0000000098932356a236718829dd9e3eb0f9143317ab921333b1a203de336de4")
108
- .get_next_block.should == nil
109
- @store.get_block("00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008")
110
- .get_next_block.should ==
111
- @store.get_block("000000033cc282bc1fa9dcae7a533263fd7fe66490f550d80076433340831604")
112
- end
113
-
114
- it "should get block for tx" do
115
- @store.store_block(@blk)
116
- @store.get_block_by_tx(@blk.tx[0].hash).should == @blk
117
- end
118
-
119
- it "should store tx" do
120
- @store.store_tx(@tx).should != false
121
- end
122
-
123
- it "should not store tx if already stored and return existing id" do
124
- id = @store.store_tx(@tx)
125
- @store.store_tx(@tx).should == id
126
- end
127
-
128
- it "should check if tx is already stored" do
129
- @store.has_tx(@tx.hash).should == false
130
- @store.store_tx(@tx)
131
- @store.has_tx(@tx.hash).should == true
132
- end
133
-
134
- it "should store hash160 for txout" do
135
- @store.store_tx(@tx)
136
- @store.get_tx(@tx.hash).out[0].hash160
137
- .should == "3129d7051d509424d23d533fa2d5258977e822e3"
138
- end
139
-
140
- it "should get tx" do
141
- @store.store_tx(@tx)
142
- @store.get_tx(@tx.hash).should == @tx
143
- end
144
-
145
- it "should not get tx" do
146
- @store.get_tx("nonexistant").should == nil
147
- end
148
-
149
-
150
- it "should get txouts for pk script" do
151
- @store.store_block(@blk)
152
- script = @blk.tx[0].out[0].pk_script
153
- @store.get_txouts_for_pk_script(script)
154
- .should == [@blk.tx[0].out[0]]
155
- end
156
-
157
- it "should get block for tx" do
158
- @store.store_block(@blk)
159
- tx = @blk.tx[0]
160
- @store.get_tx(tx.hash).get_block.should == @blk
161
- end
162
-
163
- it "should get tx for txin" do
164
- @store.store_tx(@tx)
165
- @store.get_tx(@tx.hash).in[0].get_tx.should == @tx
166
- end
167
-
168
- it "should get prev out for txin" do
169
- tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
170
- outpoint_tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
171
- @store.store_tx(outpoint_tx)
172
- @store.store_tx(tx)
173
-
174
- @store.get_tx(tx.hash).in[0].get_prev_out.should == outpoint_tx.out[0]
175
- end
176
-
177
- it "should get tx for txout" do
178
- @store.store_tx(@tx)
179
- @store.get_tx(@tx.hash).out[0].get_tx.should == @tx
180
- end
181
-
182
- it "should get next in for txin" do
183
- tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16.bin'))
184
- outpoint_tx = Bitcoin::Protocol::Tx.new(fixtures_file('rawtx-0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9.bin'))
185
- @store.store_tx(outpoint_tx)
186
- @store.store_tx(tx)
187
-
188
- @store.get_tx(outpoint_tx.hash).out[0].get_next_in.should == tx.in[0]
189
- end
190
-
191
- it "should get txouts for hash160" do
192
- @store.store_tx(@tx)
193
- @store.get_txouts_for_hash160("3129d7051d509424d23d533fa2d5258977e822e3", true)
194
- .should == [@tx.out[0]]
195
- end
196
-
197
- it "should get txouts for address" do
198
- @store.store_tx(@tx)
199
- @store.get_txouts_for_address("mjzuXYR2fncbPzn9nR5Ee5gBgYk9UQx36x", true)
200
- .should == [@tx.out[0]]
201
- end
202
-
203
- it "should get balance for address" do
204
- @store.store_tx(@tx)
205
- @store.get_balance("62e907b15cbf27d5425399ebf6f0fb50ebb88f18").should == 5000000000
206
- @store.get_balance("4580f1b3632948202655fd555fdaaf9b9ef5ac0d").should == 0
207
- end
208
-
209
- it "should store multisig tx and index hash160's" do
210
- (true.should==true) && next if @store.class == Bitcoin::Storage::Backends::DummyStore
211
- *keys = Bitcoin::Key.generate, Bitcoin::Key.generate
212
- pk_script = Bitcoin::Script.to_multisig_script(1, keys[0].pub, keys[1].pub)
213
- txout = Bitcoin::Protocol::TxOut.new(1000, pk_script)
214
- @store.store_txout(0, txout, 0)
215
- keys.each do |key|
216
- hash160 = Bitcoin.hash160(key.pub)
217
- txouts = @store.get_txouts_for_hash160(hash160, true)
218
- txouts.size.should == 1
219
- txouts[0].pk_script.should == txout.pk_script
220
- end
221
- end
222
-
223
- it "should index output script type" do
224
- @store.store_tx(@tx)
225
- @store.get_tx(@tx.hash).out.first.type.should == :hash160
226
- end
227
-
228
- end
229
- end