bitcoin-ruby 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +2 -2
  4. data/COPYING +1 -1
  5. data/Gemfile +5 -11
  6. data/README.rdoc +11 -5
  7. data/Rakefile +5 -0
  8. data/bin/bitcoin_node +11 -29
  9. data/bin/bitcoin_node_cli +81 -0
  10. data/bin/bitcoin_wallet +9 -6
  11. data/doc/NODE.rdoc +79 -26
  12. data/examples/bbe_verify_tx.rb +1 -1
  13. data/examples/index_nhash.rb +24 -0
  14. data/examples/reindex_p2sh_addrs.rb +44 -0
  15. data/lib/bitcoin.rb +135 -20
  16. data/lib/bitcoin/builder.rb +233 -63
  17. data/lib/bitcoin/key.rb +89 -16
  18. data/lib/bitcoin/litecoin.rb +13 -11
  19. data/lib/bitcoin/namecoin.rb +5 -4
  20. data/lib/bitcoin/network/command_client.rb +23 -13
  21. data/lib/bitcoin/network/command_handler.rb +336 -131
  22. data/lib/bitcoin/network/connection_handler.rb +14 -13
  23. data/lib/bitcoin/network/node.rb +61 -20
  24. data/lib/bitcoin/protocol.rb +5 -1
  25. data/lib/bitcoin/protocol/block.rb +15 -3
  26. data/lib/bitcoin/protocol/parser.rb +3 -3
  27. data/lib/bitcoin/protocol/tx.rb +82 -20
  28. data/lib/bitcoin/protocol/txin.rb +7 -0
  29. data/lib/bitcoin/protocol/txout.rb +12 -9
  30. data/lib/bitcoin/script.rb +329 -75
  31. data/lib/bitcoin/storage/dummy/dummy_store.rb +23 -4
  32. data/lib/bitcoin/storage/models.rb +6 -11
  33. data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +14 -0
  34. data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +31 -0
  35. data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +16 -0
  36. data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +31 -0
  37. data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +56 -0
  38. data/lib/bitcoin/storage/sequel/sequel_store.rb +168 -70
  39. data/lib/bitcoin/storage/storage.rb +161 -97
  40. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +1 -1
  41. data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +14 -0
  42. data/lib/bitcoin/storage/utxo/utxo_store.rb +25 -12
  43. data/lib/bitcoin/validation.rb +87 -56
  44. data/lib/bitcoin/version.rb +1 -1
  45. data/spec/bitcoin/bitcoin_spec.rb +38 -0
  46. data/spec/bitcoin/builder_spec.rb +177 -0
  47. data/spec/bitcoin/fixtures/litecoin-tx-f5aa30f574e3b6f1a3d99c07a6356ba812aabb9661e1d5f71edff828cbd5c996.json +259 -0
  48. data/spec/bitcoin/fixtures/rawblock-testnet-265322.bin +0 -0
  49. data/spec/bitcoin/fixtures/tx-0295028ef826b2a188409cb905b631faebb9bb3cdf14510571c5f4bd8591338f.json +64 -0
  50. data/spec/bitcoin/fixtures/tx-03339a725007a279484fb6f5361f522dd1cf4d0923d30e6b973290dba4275f92.json +64 -0
  51. data/spec/bitcoin/fixtures/tx-0ce7e5238fbdb6c086cf1b384b21b827e91cc23f360417265874a5a0d86ce367.json +64 -0
  52. data/spec/bitcoin/fixtures/tx-0ef34c49f630aea17df0080728b0fc67bf5f87fbda936934a4b11b4a69d7821e.json +64 -0
  53. data/spec/bitcoin/fixtures/tx-1129d2a8bd5bb3a81e54dc96a90f1f6b2544575748caa17243470935c5dd91b7.json +28 -0
  54. data/spec/bitcoin/fixtures/tx-19aa42fee0fa57c45d3b16488198b27caaacc4ff5794510d0c17f173f05587ff.json +23 -0
  55. data/spec/bitcoin/fixtures/tx-1a4f3b9dc4494aeedeb39f30dd37e60541b2abe3ed4977992017cc0ad4f44956.json +64 -0
  56. data/spec/bitcoin/fixtures/tx-1f9191dcf2b1844ca28c6ef4b969e1d5fab70a5e3c56b7007949e55851cb0c4f.json +64 -0
  57. data/spec/bitcoin/fixtures/tx-22cd5fef23684d7b304e119bedffde6f54538d3d54a5bfa237e20dc2d9b4b5ad.json +64 -0
  58. data/spec/bitcoin/fixtures/tx-2958fb00b4fd6fe0353503b886eb9a193d502f4fd5fc042d5e03216ba918bbd6.json +64 -0
  59. data/spec/bitcoin/fixtures/tx-29f277145749ad6efbed3ae6ce301f8d33c585ec26b7c044ad93c2f866e9e942.json +64 -0
  60. data/spec/bitcoin/fixtures/tx-2c5e5376c20e9cc78d0fb771730e5d840cc2096eff0ef045b599fe92475ace1c.json +28 -0
  61. data/spec/bitcoin/fixtures/tx-2c63aa814701cef5dbd4bbaddab3fea9117028f2434dddcdab8339141e9b14d1.json +30 -0
  62. data/spec/bitcoin/fixtures/tx-326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e.json +23 -0
  63. data/spec/bitcoin/fixtures/tx-345bed8785c3282a264ffb0dbee61cde54854f10e16f1b3e75b7f2d9f62946f2.json +64 -0
  64. data/spec/bitcoin/fixtures/tx-39ba7440b7103557560cc8ce258009936796485aaf8b478e66ab4cb97c66e31b.json +32 -0
  65. data/spec/bitcoin/fixtures/tx-3a04d57a833367f1655cc5ec3beb587888ef4977a86caa8c8ad4ba7cc717eae7.json +64 -0
  66. data/spec/bitcoin/fixtures/tx-4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9.json +38 -0
  67. data/spec/bitcoin/fixtures/tx-46224764c7870f95b58f155bce1e38d4da8e99d42dbb632d0dd7c07e092ee5aa.json +23 -0
  68. data/spec/bitcoin/fixtures/tx-5df1375ffe61ac35ca178ebb0cab9ea26dedbd0e96005dfcee7e379fa513232f.json +30 -0
  69. data/spec/bitcoin/fixtures/tx-62d9a565bd7b5344c5352e3e9e5f40fa4bbd467fa19c87357216ec8777ba1cce.json +64 -0
  70. data/spec/bitcoin/fixtures/tx-6327783a064d4e350c454ad5cd90201aedf65b1fc524e73709c52f0163739190.json +23 -0
  71. data/spec/bitcoin/fixtures/tx-6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba.json +27 -0
  72. data/spec/bitcoin/fixtures/tx-6aaf18b9f1283b939d8e5d40ff5f8a435229f4178372659cc3a0bce4e262bf78.json +28 -0
  73. data/spec/bitcoin/fixtures/tx-6b48bba6f6d2286d7ec0883c0fc3085955090813a4c94980466611c798b868cc.json +64 -0
  74. data/spec/bitcoin/fixtures/tx-70cfbc6690f9ab46712db44e3079ac227962b2771a9341d4233d898b521619ef.json +40 -0
  75. data/spec/bitcoin/fixtures/tx-7a1a9db42f065f75110fcdb1bc415549c8ef7670417ba1d35a67f1b8adc562c1.json +64 -0
  76. data/spec/bitcoin/fixtures/tx-9a768fc7d0c4bdc86e25154357ef7c0063ca21310e5740a2f12f90b7455184a7.json +64 -0
  77. data/spec/bitcoin/fixtures/tx-9cad8d523a0694f2509d092c39cebc8046adae62b4e4297102d568191d9478d8.json +64 -0
  78. data/spec/bitcoin/fixtures/tx-9e052eb694bd7e15906433f064dff0161a12fd325c1124537766377004023c6f.json +64 -0
  79. data/spec/bitcoin/fixtures/tx-a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944.json +23 -0
  80. data/spec/bitcoin/fixtures/tx-aab7ef280abbb9cc6fbaf524d2645c3daf4fcca2b3f53370e618d9cedf65f1f8.json +23 -0
  81. data/spec/bitcoin/fixtures/tx-ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742.json +27 -0
  82. data/spec/bitcoin/fixtures/tx-ad4bcf3241e5d2ad140564e20db3567d41594cf4c2012433fe46a2b70e0d87b8.json +64 -0
  83. data/spec/bitcoin/fixtures/tx-b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9.json +27 -0
  84. data/spec/bitcoin/fixtures/tx-b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d.json +28 -0
  85. data/spec/bitcoin/fixtures/tx-bbca0628c42cb8bf7c3f4b2ad688fa56da5308dd2a10255da89fb1f46e6e413d.json +36 -0
  86. data/spec/bitcoin/fixtures/tx-bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224.json +23 -0
  87. data/spec/bitcoin/fixtures/tx-c192b74844e4837a34c4a5a97b438f1c111405b01b99e2d12b7c96d07fc74c04.json +28 -0
  88. data/spec/bitcoin/fixtures/tx-e335562f7e297aadeed88e5954bc4eeb8dc00b31d829eedb232e39d672b0c009.json +406 -0
  89. data/spec/bitcoin/fixtures/tx-eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb.json +35 -0
  90. data/spec/bitcoin/fixtures/tx-fee1b9b85531c8fb6cd7831f83490c7f2aa768b6eefe29854ef5e89ce7b9ecb1.json +64 -0
  91. data/spec/bitcoin/fixtures/txscript-invalid-too-many-sigops-followed-by-invalid-pushdata.bin +1 -0
  92. data/spec/bitcoin/helpers/fake_blockchain.rb +183 -0
  93. data/spec/bitcoin/key_spec.rb +79 -8
  94. data/spec/bitcoin/namecoin_spec.rb +1 -1
  95. data/spec/bitcoin/node/command_api_spec.rb +373 -86
  96. data/spec/bitcoin/performance/storage_spec.rb +41 -0
  97. data/spec/bitcoin/protocol/addr_spec.rb +7 -5
  98. data/spec/bitcoin/protocol/aux_pow_spec.rb +1 -0
  99. data/spec/bitcoin/protocol/block_spec.rb +6 -0
  100. data/spec/bitcoin/protocol/tx_spec.rb +184 -1
  101. data/spec/bitcoin/protocol/txin_spec.rb +27 -0
  102. data/spec/bitcoin/protocol/txout_spec.rb +27 -0
  103. data/spec/bitcoin/script/opcodes_spec.rb +74 -3
  104. data/spec/bitcoin/script/script_spec.rb +271 -0
  105. data/spec/bitcoin/spec_helper.rb +34 -6
  106. data/spec/bitcoin/storage/models_spec.rb +104 -0
  107. data/spec/bitcoin/storage/reorg_spec.rb +42 -11
  108. data/spec/bitcoin/storage/storage_spec.rb +58 -15
  109. data/spec/bitcoin/storage/validation_spec.rb +44 -14
  110. data/spec/bitcoin/wallet/keygenerator_spec.rb +6 -3
  111. data/spec/bitcoin/wallet/keystore_spec.rb +3 -3
  112. data/spec/bitcoin/wallet/wallet_spec.rb +87 -89
  113. metadata +117 -11
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e801e5256acce9c4fc02ef046d2388365111fd23
4
+ data.tar.gz: 81781d99c978635c078d7aae95a2e29c892f6e52
5
+ SHA512:
6
+ metadata.gz: 84a5f6f668b5fb3590ab5e3d9bc58255f06fbcc2adad65e8fe3943253630e12510a348257ce7181e382411ab2ae68171f5d9787fa5780e7a5c9f410910f568f0
7
+ data.tar.gz: d07c7abc49e3f1eb0caf2244808be898855a82001504f1747c7c1328e960a2dccad6c0291740a02320bd59e84ba02adbc79af67656e0ceb6aee7b506edbf7313
data/.gitignore CHANGED
@@ -9,7 +9,9 @@ tmp/
9
9
  log/
10
10
  rdoc/
11
11
  coverage/
12
+ spec/bitcoin/fixtures/fake_chain
12
13
  *.conf
13
14
  *.db
14
15
  .rbx/
15
16
  /vendor
17
+ .ruby-version
data/.travis.yml CHANGED
@@ -2,9 +2,9 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
+ - 2.1.0
5
6
  before_script:
6
7
  - psql -c 'create database bitcoin_test;' -U postgres
7
8
  - mysql -e 'create database bitcoin_test;'
8
9
  env:
9
- - TEST_DB_POSTGRES="postgres://postgres@localhost/bitcoin_test"
10
- - TEST_DB_MYSQL="mysql:/bitcoin_test"
10
+ - TEST_DB_POSTGRES="postgres://postgres@localhost/bitcoin_test" TEST_DB_MYSQL="mysql:/bitcoin_test"
data/COPYING CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Julian Langschaedel <meta.rb@gmail.com>
1
+ Copyright (c) 2014 Julian Langschaedel <meta.rb@gmail.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
data/Gemfile CHANGED
@@ -3,23 +3,17 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in bitcoin-ruby.gemspec
4
4
  gemspec
5
5
 
6
- group :test do
7
- gem 'sqlite3', :platforms => :ruby
8
-
9
- gem 'bacon', '>= 1.2.0'
10
- gem 'simplecov', :require => false
11
-
12
- gem 'rake', '>= 0.8.0'
13
- end
14
-
15
6
  group :development do
16
7
  gem 'eventmachine'
17
8
  gem 'ffi'
18
9
  gem 'log4r'
19
10
  gem 'sequel'
11
+ gem 'scrypt'
20
12
 
21
- gem 'sqlite3', :platforms => :ruby, :require => false
22
- gem 'pg', :platforms => :ruby, :require => false
13
+ gem 'sqlite3', platforms: :ruby, require: false
14
+ gem 'pg', platforms: :ruby, require: false
23
15
 
24
16
  gem "rake", ">= 0.8.0"
17
+ gem 'bacon', '>= 1.2.0'
18
+ gem 'simplecov', require: false
25
19
  end
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = Bitcoin-ruby {<img src="https://api.travis-ci.org/lian/bitcoin-ruby.png?branch=master" />}[http://travis-ci.org/lian/bitcoin-ruby]
1
+ = Bitcoin-ruby {<img src="https://api.travis-ci.org/lian/bitcoin-ruby.svg?branch=master" />}[http://travis-ci.org/lian/bitcoin-ruby]
2
2
 
3
3
  This is a ruby library for interacting with the bitcoin protocol/network.
4
4
 
@@ -15,11 +15,13 @@ Some of the main features are:
15
15
  * Bitcoin::Builder provides a high-level API for creating transactions (and blocks)
16
16
  * Bitcoin::Wallet is a draft implementation of a simple wallet
17
17
  * Bitcoin::Namecoin implements all the namecoin-specific differences (see NAMECOIN)
18
+ * Bitcoin::Litecoin implements all the litecoin-sepcific differences
18
19
 
19
20
  == Compatible with...
20
21
 
21
22
  * ruby 1.9.3
22
23
  * ruby 2.0.0
24
+ * ruby 2.1.2
23
25
 
24
26
  == Installation
25
27
 
@@ -30,7 +32,7 @@ We assume you already have a ruby 1.9 or 2.0 compatible interpreter and rubygems
30
32
 
31
33
  if you want to have it available system-wide, just build the gem and install it:
32
34
 
33
- gem build bitcoin-ruby.gemspec && gem install bitcoin-ruby-0.0.2.gem
35
+ gem build bitcoin-ruby.gemspec && gem install bitcoin-ruby-0.0.5.gem
34
36
 
35
37
  now you can just call +bitcoin_node+ from anywhere.
36
38
 
@@ -44,6 +46,7 @@ intentionally kept to a minimum, so nobody has to install unneeded dependencies.
44
46
  * +em-dns+ or +nslookup+ to get peer addrs from DNS seeds
45
47
  * +gir_ffi+ for the gui
46
48
  * +bacon+ to run the specs
49
+ * +scrypt+ to use a much faster scrypt hash implementation for Litecoin
47
50
 
48
51
  If you would like to install using Bundler, put it in your Gemfile and run bundle install
49
52
  gem 'bitcoin-ruby', git: 'https://github.com/lian/bitcoin-ruby', branch: 'master', require: 'bitcoin'
@@ -54,7 +57,7 @@ There is a node which connects to the network and downloads
54
57
  the blockchain into a database. see NODE, Bitcoin::Network::Node.
55
58
 
56
59
  It also opens an extra socket where local clients can query statistics,
57
- monitor blockchain data, and relay there transactions to the network.
60
+ monitor blockchain data, and relay their own transactions to the network.
58
61
  see NODE, Bitcoin::Network::CommandHandler, Bitcoin::Network::CommandClient.
59
62
 
60
63
  There is a WALLET implementation to manage a set of keys, list balances and create
@@ -185,7 +188,7 @@ as well as the private key for the address required to sign for it.
185
188
 
186
189
  end
187
190
 
188
- # examine your transaction. you can relay it through http://webbtc.com/relay_tx
191
+ # examine your transaction. you can relay it through http://test.webbtc.com/relay_tx
189
192
  # that will also give you a hint on the error if something goes wrong
190
193
  puts new_tx.to_json
191
194
 
@@ -194,7 +197,7 @@ as well as the private key for the address required to sign for it.
194
197
  The Bitcoin::Network::Node can connect to peers and download the blockchain into a
195
198
  Bitcoin::Storage backend. For now it works completely self-contained:
196
199
 
197
- node = Bitcoin::Network::Node.new(options) # options = {:network => :bitcoin, ...}
200
+ node = Bitcoin::Network::Node.new(options) # options = {network: :bitcoin, ...}
198
201
  node.run
199
202
 
200
203
  In the future you will be able to register callbacks to the node and control many aspects
@@ -254,3 +257,6 @@ Even if you are completely lost, just pointing out what is unclear helps a lot!
254
257
 
255
258
  If you are curious or like to participate in development, drop by \#bitcoin-ruby on irc.freenode.net!
256
259
 
260
+ == License
261
+
262
+ Available here: [link:COPYING]
data/Rakefile CHANGED
@@ -29,6 +29,11 @@ task :bacon do
29
29
  specs = PROJECT_SPECS
30
30
  #specs.delete_if{|i| File.basename(i) == 'storage_spec.rb' } # skip for now
31
31
 
32
+ # E.g. SPEC=specs/bitcoin/script/ to run script-related specs only.
33
+ if spec_mask = ENV["SPEC"]
34
+ specs.delete_if{|s| !s[spec_mask] }
35
+ end
36
+
32
37
  some_failed = false
33
38
  specs_size = specs.size
34
39
  len = specs.map{|s| s.size }.sort.last
data/bin/bitcoin_node CHANGED
@@ -43,6 +43,16 @@ optparse = OptionParser.new do |opts|
43
43
  end
44
44
  end
45
45
 
46
+ opts.on("-a", "--announce",
47
+ "Announce our own address to the network, so we will get incoming connections.") do
48
+ options[:announce] = true
49
+ end
50
+
51
+ opts.on("--external-port PORT",
52
+ "Specify external port that can be used to reach this node (uses local port otherwise).") do |port|
53
+ options[:external_port] = port.to_i
54
+ end
55
+
46
56
  opts.on("-s", "--storage [BACKEND::CONFIG]",
47
57
  "Use storage backend (default: #{options[:storage]})") do |storage|
48
58
  options[:storage] = storage
@@ -136,35 +146,7 @@ Bitcoin.network = options[:network]
136
146
  FileUtils.mkdir_p File.join(ENV['HOME'], ".bitcoin-ruby/#{Bitcoin.network_name}")
137
147
 
138
148
  if ARGV.any?
139
- EM.run do
140
- Bitcoin::Network::CommandClient.connect(*options[:command]) do
141
- on_response do |cmd, data|
142
- unless cmd == "monitor"
143
- puts JSON.pretty_generate data
144
- EM.stop
145
- end
146
- end
147
- on_block do |block, depth|
148
- puts "block: #{block['hash']} (#{depth})"
149
- end
150
- on_tx do |tx, confirmations|
151
- puts "tx(#{confirmations}): #{tx['hash']}"
152
- end
153
- on_output do |tx_hash, address, value, confirmations|
154
- puts "output(#{confirmations}): tx #{tx_hash[0..8]}: #{address} received #{value.to_f / 1e8} BTC"
155
- end
156
- on_connection do |type, host|
157
- if type == "connected"
158
- puts "Connected: #{host['host']}:#{host['port']}"
159
- else
160
- puts "Disconnected: #{host.inspect}"
161
- end
162
- end
163
- on_connected do
164
- request(ARGV[0], *(ARGV[1] || "").split(" "))
165
- end
166
- end
167
- end
149
+ system(File.join(File.dirname(__FILE__), "bitcoin_node_cli"), *ARGV)
168
150
  else
169
151
  node = Bitcoin::Network::Node.new(options)
170
152
  node.run
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift( File.expand_path("../../lib", __FILE__) )
3
+
4
+ require 'bitcoin'
5
+ require 'optparse'
6
+ require 'fileutils'
7
+ Bitcoin.require_dependency :eventmachine
8
+ Bitcoin.require_dependency :json
9
+
10
+ defaults = Bitcoin::Network::Node::DEFAULT_CONFIG
11
+
12
+ options = Bitcoin::Config.load(defaults, :blockchain)
13
+
14
+ optparse = OptionParser.new do |opts|
15
+ opts.banner = "Usage: bitcoin_node [options]"
16
+
17
+ opts.separator("\nAvailable options:\n")
18
+
19
+ opts.on("-c", "--config FILE",
20
+ "Config file (default: #{Bitcoin::Config::CONFIG_PATHS})") do |file|
21
+ options = Bitcoin::Config.load_file(options, file, :blockchain)
22
+ end
23
+
24
+ opts.on("-n", "--network [NETWORK]",
25
+ "User Network (default: #{options[:network]})") do |network|
26
+ options[:network] = network
27
+ end
28
+
29
+ opts.on("--command [HOST:PORT]",
30
+ "Command socket (default: #{options[:command].join(':')})") do |command|
31
+ options[:command] = command.split(":")
32
+ end
33
+
34
+ opts.on( '-h', '--help', 'Display this screen' ) do
35
+ puts opts; exit
36
+ end
37
+ end
38
+
39
+ optparse.parse!
40
+
41
+ Bitcoin.network = options[:network]
42
+ FileUtils.mkdir_p File.join(ENV['HOME'], ".bitcoin-ruby/#{Bitcoin.network_name}")
43
+
44
+ EM.run do
45
+ Bitcoin::Network::CommandClient.connect(*options[:command]) do
46
+ on_response do |cmd, data|
47
+ unless cmd == "monitor"
48
+ puts JSON.pretty_generate data
49
+ EM.stop
50
+ end
51
+ end
52
+ on_block do |block, depth|
53
+ hash = Bitcoin::P::Block.new(block['hex'].htb).to_hash.merge("depth" => block['depth'])
54
+ puts JSON.pretty_generate(hash)
55
+ end
56
+ on_tx do |tx, confirmations|
57
+ hash = Bitcoin::P::Tx.new(tx['hex'].htb).to_hash.merge("nhash" => tx['nhash'], "conf" => tx['conf'])
58
+ puts JSON.pretty_generate(hash)
59
+ end
60
+ on_output do |data|
61
+ puts JSON.pretty_generate(data)
62
+ end
63
+ on_connection do |data|
64
+ p data
65
+ end
66
+ on_connected do
67
+ cmd, params = ARGV.shift, Hash[ARGV.map {|a| a.split("=") }]
68
+ case cmd
69
+ when "create_tx"
70
+ params["keys"] = JSON.parse(params["keys"])
71
+ params["recipients"] = JSON.parse(params["recipients"])
72
+ when "assemble_tx"
73
+ params["sig_pubs"] = JSON.parse(params["sig_pubs"])
74
+ when "monitor"
75
+ params["addresses"] = JSON.parse(params["addresses"]) if params["addresses"]
76
+ $stdout.sync = true
77
+ end
78
+ request(cmd, params)
79
+ end
80
+ end
81
+ end
data/bin/bitcoin_wallet CHANGED
@@ -69,7 +69,7 @@ optparse.parse!
69
69
 
70
70
  cmd = ARGV.shift; cmdopts = ARGV
71
71
  unless cmd
72
- exit puts optparse
72
+ puts optparse; exit
73
73
  end
74
74
 
75
75
  Bitcoin.network = options[:network]
@@ -120,6 +120,8 @@ def send_transaction(storage, options, tx, ask = true)
120
120
  puts "#{script.get_address} (address)"
121
121
  elsif script.is_multisig?
122
122
  puts "#{script.get_addresses.join(' ')} (multisig)"
123
+ elsif script.is_op_return?
124
+ puts "#{script.get_op_return_data} (op_return)"
123
125
  elsif script.is_namecoin?
124
126
  puts "#{script.get_address} (#{script.type})"
125
127
  print " " * 16
@@ -141,7 +143,7 @@ def send_transaction(storage, options, tx, ask = true)
141
143
  end
142
144
  end
143
145
  EM.run do
144
- Bitcoin::Network::CommandClient.connect(*options[:command].split(":")) do
146
+ Bitcoin::Network::CommandClient.connect(*options[:command]) do
145
147
  on_connected do
146
148
  request(:relay_tx, tx.to_payload.hth)
147
149
  end
@@ -311,8 +313,9 @@ when "name_update"
311
313
  puts tx.hash
312
314
 
313
315
  when "send"
314
- to = cmdopts[0].split(',').map do |pair|
315
- type, *addrs, value = pair.split(":")
316
+ to = cmdopts[0].split(',').map do |opts|
317
+ o = opts.split(":")
318
+ type, *addrs, value = *(o.size == 2 ? [:address, *o] : o)
316
319
  value = val_str(value)
317
320
  [type.to_sym, *addrs, value]
318
321
  end
@@ -382,7 +385,7 @@ when "relay"
382
385
  end
383
386
 
384
387
  EM.run do
385
- EM.connect(*options[:command].split(":")) do |conn|
388
+ EM.connect(*options[:command]) do |conn|
386
389
  conn.send_data(["relay_tx", tx.to_payload.unpack("H*")[0]].to_json)
387
390
  def conn.receive_data(data)
388
391
  (@buf ||= BufferedTokenizer.new("\x00")).extract(data).each do |packet|
@@ -395,5 +398,5 @@ when "relay"
395
398
  end
396
399
 
397
400
  else
398
- puts "Unknown command."
401
+ puts "Unknown command. See --help for available commands."
399
402
  end
data/doc/NODE.rdoc CHANGED
@@ -33,7 +33,7 @@ Some common options you might want to use:
33
33
  Skip validation of received blockchain data. Can be used to speed up import/sync when
34
34
  blockchain data is received from a trusted source.
35
35
 
36
- <tt>--check-blocks <i><count></i>::
36
+ <tt>--check-blocks <i><count></i></tt>::
37
37
  Check consistency of the +count+ most recent blocks. Pass -1 to check all blocks.
38
38
 
39
39
  <tt>-v --verbose</tt>::
@@ -49,15 +49,18 @@ It will take a long time to download/store the entire blockchain at first, so be
49
49
 
50
50
  The node opens a separate command socket which you can connect to and query statistics
51
51
  or get notified about new blocks/tx, etc. See below for a list of available commands.
52
+ For more details, see Bitcoin::Network::CommandHandler.
52
53
 
53
54
  === CLI interface
54
55
 
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:
56
+ The `bitcoin_node_cli` command can be used to interface with a running node, send it commands
57
+ and subscribe to notifications about new blocks/txs, etc.
58
+ The easiest way is to just call `bitcoin_node_cli` in the same way you started
59
+ `bitcoin_node`, but with extra command arguments:
57
60
 
58
- bitcoin_node info
59
- bitcoin_node -c config.yml info
60
- bitcoin_node monitor "block tx"
61
+ bitcoin_node_cli info
62
+ bitcoin_node_cli -c config.yml info
63
+ bitcoin_node_cli monitor "block tx"
61
64
 
62
65
 
63
66
  === CommandClient
@@ -68,11 +71,18 @@ Bitcoin::Network::CommandClient convenient.
68
71
  === Raw socket
69
72
 
70
73
  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):
74
+ your commands as valid JSON, like:
73
75
 
74
- $ echo -e '["tslb", []]\0' | nc 127.0.0.1 9999
75
- ["tslb",{"tslb":2700}]
76
+ {"id": 0, "method": <command>, "params": <params>}
77
+
78
+ and you'll receive responses in the form:
79
+
80
+ {"id": <id>, "method": <method>, "result": <result>}
81
+
82
+ For example:
83
+
84
+ $ echo -e '{"id": 1, "method": "tslb", "params": {}}\0' | nc 127.0.0.1 9999
85
+ {"id":1,"method":"tslb","result":{"tslb":10}}
76
86
 
77
87
 
78
88
  === Commands
@@ -81,92 +91,135 @@ encoded in JSON):
81
91
 
82
92
  Get various statistics.
83
93
 
84
- bitcoin_node info
94
+ bitcoin_node_cli info
85
95
 
86
96
  ==== config
87
97
 
88
98
  Get the currently active configuration.
89
99
 
90
- bitcoin_node config
100
+ bitcoin_node_cli config
91
101
 
92
102
  ==== connections
93
103
 
94
104
  Get currently connected peers.
95
105
 
96
- bitcoin_node connections
106
+ bitcoin_node_cli connections
97
107
 
98
108
  ==== connect
99
109
 
100
110
  Connect to given peer(s).
101
111
 
102
- bitcoin_node connect <ip>:<port>[,<ip>:<port>]
112
+ bitcoin_node_cli connect <ip>:<port>[,<ip>:<port>]
103
113
 
104
114
  ==== disconnect
105
115
 
106
116
  Disconnect given peer(s).
107
117
 
108
- bitcoin_node disconnect <ip>:<port>[,<ip>,<port>]
118
+ bitcoin_node_cli disconnect <ip>:<port>[,<ip>,<port>]
109
119
 
110
120
  ==== getblocks
111
121
 
112
122
  Trigger the node to ask its peers for new blocks.
113
123
 
114
- bitcoin_node getblocks
124
+ bitcoin_node_cli getblocks
115
125
 
116
126
  ==== getaddr
117
127
 
118
128
  Trigger the node to ask its for new peer addresses.
119
129
 
120
- bitcoin_node getaddr
130
+ bitcoin_node_cli getaddr
121
131
 
122
132
  ==== addrs
123
133
 
124
134
  Get known peer addresses (used by bin/bitcoin_dns_seed)
125
135
 
126
- bitcoin_node addrs [count]
136
+ bitcoin_node_cli addrs [count]
127
137
 
128
138
  ==== tslb
129
139
 
130
140
  Get Time Since Last Block.
131
141
 
132
- bitcoin_node tslb
142
+ bitcoin_node_cli tslb
133
143
 
134
144
  ==== create_tx
135
145
 
136
- TODO
146
+ Create a transaction, collecting outputs from given +keys+, spending to +recipients+
147
+ with an optional +fee+.
148
+ Keys is an array that can contain either privkeys, pubkeys or addresses.
149
+ When a privkey is given, the corresponding inputs are signed. If not, the
150
+ signature_hash is computed and passed along with the response.
151
+ After creating an unsigned transaction, one just needs to sign the sig_hashes
152
+ and send everything to #assemble_tx, to receive the complete transaction that
153
+ can be relayed to the network.
154
+
155
+ bitcoin_node_cli create_tx 'keys=[<addr|pub|priv>, <...>]' 'recipients=[[<addr>, <amount>], ...]'
137
156
 
138
157
  ==== assemble_tx
139
158
 
140
- TODO
159
+ Assemble an unsigned transaction from the +tx+ and +sig_pubkeys+ params and return
160
+ a valid transaction that can be relayed to the network.
161
+ The +tx+ is the regular transaction structure, with empty input scripts
162
+ (as returned by #create_tx when called without privkeys).
163
+ +sig_pubkeys+ is an array of [signature, pubkey] pairs used to build the input scripts.
164
+
165
+ bitcoin_node_cli assemble_tx tx=<hex> 'sig_pubkeys=[[<sig>, <pub>], ...]'
141
166
 
142
167
  ==== relay_tx
143
168
 
144
169
  Relay given transaction (in hex).
145
170
 
146
- bitcoin_node relay_tx <tx in hex>
171
+ bitcoin_node_cli relay_tx <tx in hex>
147
172
 
148
173
  ==== store_block
149
174
 
150
175
  Validate and store given block (in hex) as if it was received by a peer.
151
176
 
152
- bitcoin_node store_block <block in hex>
177
+ bitcoin_node_cli store_block <block in hex>
153
178
 
154
179
  ==== store_tx
155
180
 
156
181
  Store given transaction (in hex) as if it was received by a peer.
157
182
 
158
- bitcoin_node store_tx <tx in hex>
183
+ bitcoin_node_cli store_tx <tx in hex>
159
184
 
160
185
  ==== stop
161
186
 
162
187
  Stop the bitcoin node.
163
188
 
164
- bitcoin_node stop
189
+ bitcoin_node_cli stop
165
190
 
166
191
  ==== help
167
192
 
168
193
  List all available commands.
169
194
 
170
- bitcoin_node help
195
+ bitcoin_node_cli help
196
+
197
+
198
+ === Monitors
199
+
200
+ ==== block
201
+
202
+ Monitor new blocks that are accepted into the main chain.
203
+ If +last+ parameter is given, it will send all blocks since then.
204
+
205
+ bitcoin_node_cli monitor channel=block
206
+ bitcoin_node_cli monitor channel=block last=1234
207
+
208
+ ==== tx
209
+
210
+ Monitor new transactions.
211
+ If +conf+ parameter is given, it will only send txs with at least that many confirmations.
212
+ If +last+ parameter is given, it will send all txs since then.
213
+
214
+ bitcoin_node_cli monitor channel=tx
215
+ bitcoin_node_cli monitor channel=tx conf=1 last=b187505ce2acbafcb02948657c0cadb855fbcbf0491f12670f9ff8d271de1983
216
+
217
+ ==== output
171
218
 
219
+ Monitor transaction outputs.
220
+ If +conf+ parameter is given, it will only send outputs with at least that many confirmations.
221
+ If +last+ parameter is given, it will send all outputs since then.
222
+ If +addresses+ parameter is given, it will only send outputs related to those addresses.
172
223
 
224
+ bitcoin_node_cli monitor channel=output
225
+ bitcoin_node_cli monitor channel=output conf=1 last=b187505ce2acbafcb02948657c0cadb855fbcbf0491f12670f9ff8d271de1983:0