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
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 }