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.
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
data/bitcoin-ruby.gemspec CHANGED
@@ -8,8 +8,9 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["lian"]
9
9
  s.email = ["meta.rb@gmail.com"]
10
10
  s.homepage = ""
11
- s.summary = %q{Gem for working with Bitcoin network}
12
- s.description = %q{Gem for working with Bitcoin network}
11
+ s.summary = %q{bitcoin utils and protocol in ruby}
12
+ s.description = %q{This is a ruby library for interacting with the bitcoin protocol/network}
13
+ s.homepage = "https://github.com/lian/bitcoin-ruby"
13
14
 
14
15
  s.rubyforge_project = "bitcoin-ruby"
15
16
 
@@ -19,9 +20,5 @@ Gem::Specification.new do |s|
19
20
  s.require_paths = ["lib"]
20
21
 
21
22
  s.required_rubygems_version = ">= 1.3.6"
22
- s.add_dependency "rake", ">= 0.8.0"
23
- s.add_dependency "eventmachine"
24
-
25
- s.add_development_dependency "bacon"
26
-
23
+ #s.add_development_dependency "bacon"
27
24
  end
@@ -11,7 +11,7 @@ require 'digest/sha2'
11
11
 
12
12
  def do_work(data, target, nonce=0)
13
13
  found = nil
14
- while !found
14
+ until found
15
15
  d = data + [nonce].pack("I")
16
16
  h = Digest::SHA256.hexdigest( Digest::SHA256.digest( d ) ).to_i(16)
17
17
 
data/doc/CONFIG.rdoc CHANGED
@@ -6,9 +6,9 @@ All commands accept configuration, either via config file, or at the command lin
6
6
 
7
7
  There are 3 default locations where configfiles are loaded from:
8
8
 
9
- * +/etc/bitcoin-ruby.yml+
10
- * +~/.bitcoin-ruby.yml+
11
- * +./bitcoin-ruby.yml+
9
+ * /etc/bitcoin-ruby.yml
10
+ * ~/.bitcoin-ruby.yml
11
+ * ./bitcoin-ruby.yml
12
12
 
13
13
  Files are loaded in order (if they exist) and override each others settings.
14
14
 
@@ -42,7 +42,7 @@ from the +all+ category (ie. +bitcoin_wallet+ loads +all+ and +wallet+).
42
42
  command: "127.0.0.1:9999" # IP:Port to listen for incomming command connections
43
43
  listen: "0.0.0.0:8332" # IP:Port to listen for incoming peer connections
44
44
  connect: "" # List of IP:Port,IP:Port of nodes to connect to
45
- storage: "sequel::sqlite://bitcoin.db" # storage backend to use (see STORAGE)
45
+ storage: "sequel::sqlite://~/.bitcoin-ruby/<network>/blocks.db" # storage backend to use (see STORAGE)
46
46
  node:
47
47
  headers_only: false # download/store only block headers (experimental)
48
48
  dns: true # query peers from dns server
@@ -63,4 +63,4 @@ from the +all+ category (ie. +bitcoin_wallet+ loads +all+ and +wallet+).
63
63
  addrs: 15 # collect new peer addrs
64
64
  connect: 30 # connect to new peers
65
65
  wallet:
66
- keystore: "simple::file=~/.bitcoin-ruby/keys.json" # keystore to use
66
+ keystore: "simple::file=~/.bitcoin-ruby/<network>/keys.json" # keystore to use
data/doc/EXAMPLES.rdoc CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  There are a few demo scripts in `examples/` that might give you an idea where to start.
4
4
 
5
- examples/connect.rb:: Connect to a network node and chat a little.
6
- examples/verify_tx.rb:: Fetch a transaction from local storage and verify signatures.
7
- examples/bbe_verify_tx.rb:: Fetch transaction from blockexplorer.com and verify signatures.
8
- examples/balance.rb:: Display balance/transactions for given address.
9
- examples/relay_tx.rb:: Relay transaction to the network.
5
+ connect.rb:: Connect to a network node and chat a little.
6
+ verify_tx.rb:: Fetch a transaction from local storage and verify signatures.
7
+ bbe_verify_tx.rb:: Fetch transaction from blockexplorer.com and verify signatures.
8
+ balance.rb:: Display balance/transactions for given address.
9
+ relay_tx.rb:: Relay transaction to the network.
10
+ generate_tx.rb:: Create a transaction.
11
+ validate_tx.rb:: Verify transaction signatures.
12
+ simple_network_monitor_and_util:: Connects to the network and lets you monitor and query blocks/txs.
13
+ forwarder.rb:: Waits for tx sent to your address and forwards them to another address.
data/doc/NAMECOIN.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = Namecoin
2
+
3
+ Namecoin is almost fully supported.
4
+ * connect to the network,
5
+ * store and query the blockchain
6
+ * transact NMC
7
+ * create/handle name_new/first/update transaction types
8
+
9
+ The AuxPow is parsed from the block header, the only thing missing is actually verifying it.
10
+
11
+ == Usage
12
+
13
+ It should suffice to just set the network to :namecoin when running the node/wallet.
14
+
15
+ bitcoin_node -n namecoin
16
+
17
+ bitcoin_wallet -n namecoin list
18
+ bitcoin_wallet -n namecoin send address:NCme95FewQEjTeBhBfXTyqjz1GTxw4bo56:1.0 0.1
19
+
20
+ bitcoin_wallet -n namecoin name_show d/bitcoin
21
+ bitcoin_wallet -n namecoin name_history d/bitcoin
22
+
23
+ bitcoin_wallet -n namecoin name_new d/bitcoin
24
+ bitcoin_wallet -n namecoin name_firstupdate d/bitcoin abcdef '{"foo": "bar"}'
25
+ bitcoin_wallet -n namecoin name_update d/bitcoin '{"bar": "baz"}'
26
+ bitcoin_wallet -n namecoin name_update d/bitcoin 'transferring...' NCme95FewQEjTeBhBfXTyqjz1GTxw4bo56
27
+
28
+ == Implementation Details
29
+
30
+ All the differences from regular bitcoin behaviour should be in separate modules inside
31
+ Bitcoin::Namecoin. (this is still a work in progress)
32
+
33
+ The AuxPow parsing is implemented in the Bitcoin::Protocol/::Block, because there might
34
+ be other altchains using it one day.
data/doc/NODE.rdoc CHANGED
@@ -11,25 +11,162 @@ using the sequel::sqlite3 STORAGE backend):
11
11
 
12
12
  You can specify options (see +--help+) or pass a config file with +--config+ (see CONFIG).
13
13
 
14
- Some common options you might want to change:
14
+ Some common options you might want to use:
15
15
 
16
16
  <tt>-n --network</tt> <i><name></i>::
17
- +bitcoin+ or +testnet+ network
17
+ Network to use. Usually +bitcoin+. Support for +namecoin+ is also quite good.
18
+ Use +testnet+ for development.
19
+
20
+ <tt>-c --config</tt> <i><file></i>::
21
+ Read options from config file. See also CONFIG.
22
+
18
23
  <tt>--connect</tt> <i><ip:port></i>::
19
- list of peers to connect to
24
+ List of peers to connect to.
25
+
20
26
  <tt>-s --storage</tt> <i><backend-string></i>::
21
- storage backend to use (see STORAGE)
27
+ Storage backend to use. See also STORAGE.
28
+
29
+ <tt>--import</tt> <i><blockchain dir></i>::
30
+ Import blockchain in bitcoind/qt format from given directory.
31
+
32
+ <tt>--skip-validation</tt>::
33
+ Skip validation of received blockchain data. Can be used to speed up import/sync when
34
+ blockchain data is received from a trusted source.
35
+
36
+ <tt>--check-blocks <i><count></i>::
37
+ Check consistency of the +count+ most recent blocks. Pass -1 to check all blocks.
38
+
39
+ <tt>-v --verbose</tt>::
40
+ Display debug output.
41
+
42
+ <tt>-h --help</tt>::
43
+ Display all available options.
22
44
 
23
- It will take some time to download/store the entire blockchain at first, so be patient ;)
45
+ It will take a long time to download/store the entire blockchain at first, so be patient ;)
24
46
 
25
47
 
26
- == Command client
48
+ == Command socket
27
49
 
28
50
  The node opens a separate command socket which you can connect to and query statistics
29
- or get notified about new blocks/tx, etc.
51
+ or get notified about new blocks/tx, etc. See below for a list of available commands.
52
+
53
+ === CLI interface
54
+
55
+ The easiest way is to just call `bitcoin_node` again in the same way you started it,
56
+ but with an extra command argument:
57
+
58
+ bitcoin_node info
59
+ bitcoin_node -c config.yml info
60
+ bitcoin_node monitor "block tx"
61
+
62
+
63
+ === CommandClient
64
+
65
+ If you are programming in an EventMachine context, you might find the
66
+ Bitcoin::Network::CommandClient convenient.
67
+
68
+ === Raw socket
69
+
70
+ Of course you can also connect to the socket by any other means you like, just
71
+ send [<command>, <params>] pairs and receive [<command>, <response>] pairs back (both
72
+ encoded in JSON):
73
+
74
+ $ echo -e '["tslb", []]\0' | nc 127.0.0.1 9999
75
+ ["tslb",{"tslb":2700}]
76
+
77
+
78
+ === Commands
79
+
80
+ ==== info
81
+
82
+ Get various statistics.
83
+
84
+ bitcoin_node info
85
+
86
+ ==== config
87
+
88
+ Get the currently active configuration.
89
+
90
+ bitcoin_node config
91
+
92
+ ==== connections
93
+
94
+ Get currently connected peers.
95
+
96
+ bitcoin_node connections
97
+
98
+ ==== connect
99
+
100
+ Connect to given peer(s).
101
+
102
+ bitcoin_node connect <ip>:<port>[,<ip>:<port>]
103
+
104
+ ==== disconnect
105
+
106
+ Disconnect given peer(s).
107
+
108
+ bitcoin_node disconnect <ip>:<port>[,<ip>,<port>]
109
+
110
+ ==== getblocks
111
+
112
+ Trigger the node to ask its peers for new blocks.
113
+
114
+ bitcoin_node getblocks
115
+
116
+ ==== getaddr
117
+
118
+ Trigger the node to ask its for new peer addresses.
119
+
120
+ bitcoin_node getaddr
121
+
122
+ ==== addrs
123
+
124
+ Get known peer addresses (used by bin/bitcoin_dns_seed)
125
+
126
+ bitcoin_node addrs [count]
127
+
128
+ ==== tslb
129
+
130
+ Get Time Since Last Block.
131
+
132
+ bitcoin_node tslb
133
+
134
+ ==== create_tx
135
+
136
+ TODO
137
+
138
+ ==== assemble_tx
139
+
140
+ TODO
141
+
142
+ ==== relay_tx
143
+
144
+ Relay given transaction (in hex).
145
+
146
+ bitcoin_node relay_tx <tx in hex>
147
+
148
+ ==== store_block
149
+
150
+ Validate and store given block (in hex) as if it was received by a peer.
151
+
152
+ bitcoin_node store_block <block in hex>
153
+
154
+ ==== store_tx
155
+
156
+ Store given transaction (in hex) as if it was received by a peer.
157
+
158
+ bitcoin_node store_tx <tx in hex>
159
+
160
+ ==== stop
161
+
162
+ Stop the bitcoin node.
163
+
164
+ bitcoin_node stop
165
+
166
+ ==== help
167
+
168
+ List all available commands.
30
169
 
31
- bitcoin_node info # general statistics
170
+ bitcoin_node help
32
171
 
33
- bitcoin_node help # list all commands
34
172
 
35
- bitcoin_node monitor block # wait for new blocks and output their hashes
data/examples/balance.rb CHANGED
@@ -15,7 +15,7 @@ store = Bitcoin::Storage.sequel(:db => "sqlite://bitcoin.db")
15
15
  address = ARGV.shift
16
16
 
17
17
  unless Bitcoin.valid_address?(address)
18
- puts "Address #{address} is invalid."
18
+ puts "Address #{address} is invalid for #{Bitcoin.network_name} network."
19
19
  exit 1
20
20
  end
21
21
 
@@ -38,8 +38,14 @@ if ARGV[0] == "--list"
38
38
  total += txout.value
39
39
  puts "#{tx.hash} |#{str_val(txout.value, '+ ')} |=> #{str_val(total)}"
40
40
 
41
- txout.get_tx.in.map(&:get_prev_out).each do |prev_out|
42
- puts " from #{prev_out.get_addresses.join(", ")}"
41
+ tx = txout.get_tx
42
+ if tx.is_coinbase?
43
+ puts " "*12 + "generated (#{tx.get_block.hash})"
44
+ else
45
+ tx.in.each do |txin|
46
+ addresses = txin.get_prev_out.get_addresses.join(", ")
47
+ puts " #{str_val(txin.get_prev_out.value)} from #{addresses}"
48
+ end
43
49
  end
44
50
  puts
45
51
 
@@ -48,7 +54,7 @@ if ARGV[0] == "--list"
48
54
  total -= txout.value
49
55
  puts "#{tx.hash} |#{str_val(txout.value, '- ')} |=> #{str_val(total)}"
50
56
  txin.get_tx.out.each do |out|
51
- puts " to #{out.get_addresses.join(", ")}"
57
+ puts " #{str_val(out.value)} to #{out.get_addresses.join(", ")}"
52
58
  end
53
59
  puts
54
60
  end
@@ -11,11 +11,16 @@ require 'bitcoin'
11
11
  require 'open-uri'
12
12
 
13
13
  tx_hash = ARGV[0]
14
- $testnet = ARGV[1]
14
+ $testnet = ARGV.select{|i| i.downcase == 'testnet' }[0] ? true : false
15
+ $use_coinbase_bbe = ARGV.select{|i| i.downcase == 'coinbase' }[0] ? true : false
15
16
 
16
17
  # fetch transaction from bbe as json and deserialize into Bitcoin::Protocol::Tx object
17
18
  def get_tx(hash)
18
- url = "http://blockexplorer.com/%srawtx/%s" % [$testnet ? 'testnet/' : '', hash]
19
+ if $use_coinbase_bbe && !$testnet
20
+ url = "https://coinbase.com/network/tx/%s.json" % [hash]
21
+ else
22
+ url = "http://blockexplorer.com/%srawtx/%s" % [$testnet ? 'testnet/' : '', hash]
23
+ end
19
24
  json = open(url).read
20
25
  Bitcoin::Protocol::Tx.from_json(json)
21
26
  rescue Exception
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Connect to a node's command socket, monitor incoming payments to one address
4
+ # and forward everything to another address.
5
+ # Needs the private key of the receiving address (to sign new tx) and the forwarding
6
+ # address where payments are sent to.
7
+ # Note how the private key does NOT have to be passed to the node, we just sign the
8
+ # sig_hash ourselves.
9
+ #
10
+ # examples/forwarder.rb <base58_privkey> <forwarding_address>
11
+ # examples/forwarder.rb KyZsiZiFyewBswJpdYywz4b5sif252iN5zZQjGzPVVgAsGYyMk8a 12bL22Pynmp7pDtDqD2w9iP7dRzdM1gNUd
12
+
13
+ $:.unshift( File.expand_path("../../lib", __FILE__) )
14
+ require 'eventmachine'
15
+ require 'bitcoin'
16
+
17
+ Bitcoin.network = :testnet3
18
+
19
+ EM.run do
20
+
21
+ # key/address where people can send money
22
+ KEY = Bitcoin::Key.from_base58(ARGV[0])
23
+
24
+ # address where received money is forwarded to
25
+ FORWARD = ARGV[1]
26
+
27
+ # number of confirmations tx need before being forwarded
28
+ CONFIRMATIONS = 1
29
+
30
+ # list of already forwarded txs, to prevent duplicates
31
+ FORWARDED_TXS = []
32
+
33
+ Bitcoin::Network::CommandClient.connect("127.0.0.1", 9999) do
34
+
35
+ on_connected do
36
+ request("monitor", "output", "output_#{CONFIRMATIONS}")
37
+
38
+ puts "Running bitcoin forwarder on address #{KEY.addr}."
39
+ puts "Forwarding every incoming payment to #{FORWARD}."
40
+ end
41
+
42
+ on_output do |tx_hash, recipient_addr, value, confirmations|
43
+ if recipient_addr == KEY.addr
44
+ if confirmations >= CONFIRMATIONS
45
+ next if FORWARDED_TXS.include?(tx_hash)
46
+ FORWARDED_TXS << tx_hash
47
+ puts "Payment of #{value.to_f/1e8} BTC confirmed. Forwarding..."
48
+
49
+ # Note: We could also pass KEY.priv instead of KEY.addr here.
50
+ # Then we would get the complete tx in one step without calling "assemble_tx".
51
+ request("create_tx", [KEY.addr], [[FORWARD, value]])
52
+ else
53
+ puts "Received unconfirmed payment of #{value.to_f/1e8} BTC."
54
+ end
55
+ end
56
+ end
57
+
58
+ on_create_tx do |unsigned_tx, sig_hashes|
59
+ sig_pubkeys = sig_hashes.map do |sig_hash, address|
60
+ [KEY.sign(sig_hash.htb).hth, KEY.pub]
61
+ end
62
+ request("assemble_tx", unsigned_tx, sig_pubkeys)
63
+ end
64
+
65
+ on_assemble_tx do |tx_in_hex|
66
+ tx = Bitcoin::P::Tx.new(tx_in_hex.htb)
67
+ puts "Relaying tx #{tx.hash}..."
68
+ request("relay_tx", tx_in_hex)
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,34 @@
1
+ $:.unshift( File.expand_path("../../lib", __FILE__) )
2
+ require 'bitcoin'
3
+
4
+ # p Bitcoin.generate_address # returns address, privkey, pubkey, hash160
5
+
6
+ prev_tx = Bitcoin::Protocol::Tx.from_json_file('baedb362adba39753a7d2c58fd3dc4897a1b479859f707a819f096696f3facad.json') # <- redeeming transaction input fetchted by for example simple_network_monitor_and_util.rb
7
+ prev_tx_output_index = 0
8
+ value = prev_tx.outputs[prev_tx_output_index].value
9
+ #value = 1337 # maybe change the value (eg subtract for fees)
10
+
11
+
12
+ tx = Bitcoin::Protocol::Tx.new
13
+ tx.add_in Bitcoin::Protocol::TxIn.new(prev_tx.binary_hash, prev_tx_output_index, 0)
14
+
15
+ tx.add_out Bitcoin::Protocol::TxOut.value_to_address(value, "1MiQ3zD3hzZBZ4cUDfPd8Eqnjcedkwt5jy") # <- dest address (our donation address)
16
+
17
+ # if all in and outputs are defined, start signing inputs.
18
+ key = Bitcoin.open_key("9b2f08ebc186d435ffc1d10f3627f05ce4b983b72c76b0aee4fcce99e57b0342") # <- privkey
19
+ sig = Bitcoin.sign_data(key, tx.signature_hash_for_input(0, prev_tx))
20
+ tx.in[0].script_sig = Bitcoin::Script.to_signature_pubkey_script(sig, [key.public_key_hex].pack("H*"))
21
+ #tx.in[0].add_signature_pubkey_script(sig, key.public_key_hex)
22
+
23
+ # finish check
24
+ tx = Bitcoin::Protocol::Tx.new( tx.to_payload )
25
+ p tx.hash
26
+ p tx.verify_input_signature(0, prev_tx) == true
27
+
28
+ puts "json:\n"
29
+ puts tx.to_json # json
30
+ puts "\nhex:\n"
31
+ puts tx.to_payload.unpack("H*")[0] # hex binary
32
+
33
+ # use this json file for example with `ruby simple_network_monitor_and_util.rb send_tx=<filename>` to push/send it to the network
34
+ File.open(tx.hash + ".json", 'wb'){|f| f.print tx.to_json }