bitcoin-ruby 0.0.5 → 0.0.6
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +2 -2
- data/COPYING +1 -1
- data/Gemfile +5 -11
- data/README.rdoc +11 -5
- data/Rakefile +5 -0
- data/bin/bitcoin_node +11 -29
- data/bin/bitcoin_node_cli +81 -0
- data/bin/bitcoin_wallet +9 -6
- data/doc/NODE.rdoc +79 -26
- data/examples/bbe_verify_tx.rb +1 -1
- data/examples/index_nhash.rb +24 -0
- data/examples/reindex_p2sh_addrs.rb +44 -0
- data/lib/bitcoin.rb +135 -20
- data/lib/bitcoin/builder.rb +233 -63
- data/lib/bitcoin/key.rb +89 -16
- data/lib/bitcoin/litecoin.rb +13 -11
- data/lib/bitcoin/namecoin.rb +5 -4
- data/lib/bitcoin/network/command_client.rb +23 -13
- data/lib/bitcoin/network/command_handler.rb +336 -131
- data/lib/bitcoin/network/connection_handler.rb +14 -13
- data/lib/bitcoin/network/node.rb +61 -20
- data/lib/bitcoin/protocol.rb +5 -1
- data/lib/bitcoin/protocol/block.rb +15 -3
- data/lib/bitcoin/protocol/parser.rb +3 -3
- data/lib/bitcoin/protocol/tx.rb +82 -20
- data/lib/bitcoin/protocol/txin.rb +7 -0
- data/lib/bitcoin/protocol/txout.rb +12 -9
- data/lib/bitcoin/script.rb +329 -75
- data/lib/bitcoin/storage/dummy/dummy_store.rb +23 -4
- data/lib/bitcoin/storage/models.rb +6 -11
- data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +14 -0
- data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +31 -0
- data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +16 -0
- data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +31 -0
- data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +56 -0
- data/lib/bitcoin/storage/sequel/sequel_store.rb +168 -70
- data/lib/bitcoin/storage/storage.rb +161 -97
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +1 -1
- data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +14 -0
- data/lib/bitcoin/storage/utxo/utxo_store.rb +25 -12
- data/lib/bitcoin/validation.rb +87 -56
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bitcoin_spec.rb +38 -0
- data/spec/bitcoin/builder_spec.rb +177 -0
- data/spec/bitcoin/fixtures/litecoin-tx-f5aa30f574e3b6f1a3d99c07a6356ba812aabb9661e1d5f71edff828cbd5c996.json +259 -0
- data/spec/bitcoin/fixtures/rawblock-testnet-265322.bin +0 -0
- data/spec/bitcoin/fixtures/tx-0295028ef826b2a188409cb905b631faebb9bb3cdf14510571c5f4bd8591338f.json +64 -0
- data/spec/bitcoin/fixtures/tx-03339a725007a279484fb6f5361f522dd1cf4d0923d30e6b973290dba4275f92.json +64 -0
- data/spec/bitcoin/fixtures/tx-0ce7e5238fbdb6c086cf1b384b21b827e91cc23f360417265874a5a0d86ce367.json +64 -0
- data/spec/bitcoin/fixtures/tx-0ef34c49f630aea17df0080728b0fc67bf5f87fbda936934a4b11b4a69d7821e.json +64 -0
- data/spec/bitcoin/fixtures/tx-1129d2a8bd5bb3a81e54dc96a90f1f6b2544575748caa17243470935c5dd91b7.json +28 -0
- data/spec/bitcoin/fixtures/tx-19aa42fee0fa57c45d3b16488198b27caaacc4ff5794510d0c17f173f05587ff.json +23 -0
- data/spec/bitcoin/fixtures/tx-1a4f3b9dc4494aeedeb39f30dd37e60541b2abe3ed4977992017cc0ad4f44956.json +64 -0
- data/spec/bitcoin/fixtures/tx-1f9191dcf2b1844ca28c6ef4b969e1d5fab70a5e3c56b7007949e55851cb0c4f.json +64 -0
- data/spec/bitcoin/fixtures/tx-22cd5fef23684d7b304e119bedffde6f54538d3d54a5bfa237e20dc2d9b4b5ad.json +64 -0
- data/spec/bitcoin/fixtures/tx-2958fb00b4fd6fe0353503b886eb9a193d502f4fd5fc042d5e03216ba918bbd6.json +64 -0
- data/spec/bitcoin/fixtures/tx-29f277145749ad6efbed3ae6ce301f8d33c585ec26b7c044ad93c2f866e9e942.json +64 -0
- data/spec/bitcoin/fixtures/tx-2c5e5376c20e9cc78d0fb771730e5d840cc2096eff0ef045b599fe92475ace1c.json +28 -0
- data/spec/bitcoin/fixtures/tx-2c63aa814701cef5dbd4bbaddab3fea9117028f2434dddcdab8339141e9b14d1.json +30 -0
- data/spec/bitcoin/fixtures/tx-326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e.json +23 -0
- data/spec/bitcoin/fixtures/tx-345bed8785c3282a264ffb0dbee61cde54854f10e16f1b3e75b7f2d9f62946f2.json +64 -0
- data/spec/bitcoin/fixtures/tx-39ba7440b7103557560cc8ce258009936796485aaf8b478e66ab4cb97c66e31b.json +32 -0
- data/spec/bitcoin/fixtures/tx-3a04d57a833367f1655cc5ec3beb587888ef4977a86caa8c8ad4ba7cc717eae7.json +64 -0
- data/spec/bitcoin/fixtures/tx-4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9.json +38 -0
- data/spec/bitcoin/fixtures/tx-46224764c7870f95b58f155bce1e38d4da8e99d42dbb632d0dd7c07e092ee5aa.json +23 -0
- data/spec/bitcoin/fixtures/tx-5df1375ffe61ac35ca178ebb0cab9ea26dedbd0e96005dfcee7e379fa513232f.json +30 -0
- data/spec/bitcoin/fixtures/tx-62d9a565bd7b5344c5352e3e9e5f40fa4bbd467fa19c87357216ec8777ba1cce.json +64 -0
- data/spec/bitcoin/fixtures/tx-6327783a064d4e350c454ad5cd90201aedf65b1fc524e73709c52f0163739190.json +23 -0
- data/spec/bitcoin/fixtures/tx-6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba.json +27 -0
- data/spec/bitcoin/fixtures/tx-6aaf18b9f1283b939d8e5d40ff5f8a435229f4178372659cc3a0bce4e262bf78.json +28 -0
- data/spec/bitcoin/fixtures/tx-6b48bba6f6d2286d7ec0883c0fc3085955090813a4c94980466611c798b868cc.json +64 -0
- data/spec/bitcoin/fixtures/tx-70cfbc6690f9ab46712db44e3079ac227962b2771a9341d4233d898b521619ef.json +40 -0
- data/spec/bitcoin/fixtures/tx-7a1a9db42f065f75110fcdb1bc415549c8ef7670417ba1d35a67f1b8adc562c1.json +64 -0
- data/spec/bitcoin/fixtures/tx-9a768fc7d0c4bdc86e25154357ef7c0063ca21310e5740a2f12f90b7455184a7.json +64 -0
- data/spec/bitcoin/fixtures/tx-9cad8d523a0694f2509d092c39cebc8046adae62b4e4297102d568191d9478d8.json +64 -0
- data/spec/bitcoin/fixtures/tx-9e052eb694bd7e15906433f064dff0161a12fd325c1124537766377004023c6f.json +64 -0
- data/spec/bitcoin/fixtures/tx-a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944.json +23 -0
- data/spec/bitcoin/fixtures/tx-aab7ef280abbb9cc6fbaf524d2645c3daf4fcca2b3f53370e618d9cedf65f1f8.json +23 -0
- data/spec/bitcoin/fixtures/tx-ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742.json +27 -0
- data/spec/bitcoin/fixtures/tx-ad4bcf3241e5d2ad140564e20db3567d41594cf4c2012433fe46a2b70e0d87b8.json +64 -0
- data/spec/bitcoin/fixtures/tx-b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9.json +27 -0
- data/spec/bitcoin/fixtures/tx-b8fd633e7713a43d5ac87266adc78444669b987a56b3a65fb92d58c2c4b0e84d.json +28 -0
- data/spec/bitcoin/fixtures/tx-bbca0628c42cb8bf7c3f4b2ad688fa56da5308dd2a10255da89fb1f46e6e413d.json +36 -0
- data/spec/bitcoin/fixtures/tx-bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224.json +23 -0
- data/spec/bitcoin/fixtures/tx-c192b74844e4837a34c4a5a97b438f1c111405b01b99e2d12b7c96d07fc74c04.json +28 -0
- data/spec/bitcoin/fixtures/tx-e335562f7e297aadeed88e5954bc4eeb8dc00b31d829eedb232e39d672b0c009.json +406 -0
- data/spec/bitcoin/fixtures/tx-eb3b82c0884e3efa6d8b0be55b4915eb20be124c9766245bcc7f34fdac32bccb.json +35 -0
- data/spec/bitcoin/fixtures/tx-fee1b9b85531c8fb6cd7831f83490c7f2aa768b6eefe29854ef5e89ce7b9ecb1.json +64 -0
- data/spec/bitcoin/fixtures/txscript-invalid-too-many-sigops-followed-by-invalid-pushdata.bin +1 -0
- data/spec/bitcoin/helpers/fake_blockchain.rb +183 -0
- data/spec/bitcoin/key_spec.rb +79 -8
- data/spec/bitcoin/namecoin_spec.rb +1 -1
- data/spec/bitcoin/node/command_api_spec.rb +373 -86
- data/spec/bitcoin/performance/storage_spec.rb +41 -0
- data/spec/bitcoin/protocol/addr_spec.rb +7 -5
- data/spec/bitcoin/protocol/aux_pow_spec.rb +1 -0
- data/spec/bitcoin/protocol/block_spec.rb +6 -0
- data/spec/bitcoin/protocol/tx_spec.rb +184 -1
- data/spec/bitcoin/protocol/txin_spec.rb +27 -0
- data/spec/bitcoin/protocol/txout_spec.rb +27 -0
- data/spec/bitcoin/script/opcodes_spec.rb +74 -3
- data/spec/bitcoin/script/script_spec.rb +271 -0
- data/spec/bitcoin/spec_helper.rb +34 -6
- data/spec/bitcoin/storage/models_spec.rb +104 -0
- data/spec/bitcoin/storage/reorg_spec.rb +42 -11
- data/spec/bitcoin/storage/storage_spec.rb +58 -15
- data/spec/bitcoin/storage/validation_spec.rb +44 -14
- data/spec/bitcoin/wallet/keygenerator_spec.rb +6 -3
- data/spec/bitcoin/wallet/keystore_spec.rb +3 -3
- data/spec/bitcoin/wallet/wallet_spec.rb +87 -89
- 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
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)
|
|
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', :
|
|
22
|
-
gem 'pg', :
|
|
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.
|
|
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.
|
|
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
|
|
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 = {:
|
|
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
|
-
|
|
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
|
-
|
|
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]
|
|
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 |
|
|
315
|
-
|
|
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]
|
|
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
|
|
56
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
72
|
-
encoded in JSON):
|
|
74
|
+
your commands as valid JSON, like:
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
94
|
+
bitcoin_node_cli info
|
|
85
95
|
|
|
86
96
|
==== config
|
|
87
97
|
|
|
88
98
|
Get the currently active configuration.
|
|
89
99
|
|
|
90
|
-
|
|
100
|
+
bitcoin_node_cli config
|
|
91
101
|
|
|
92
102
|
==== connections
|
|
93
103
|
|
|
94
104
|
Get currently connected peers.
|
|
95
105
|
|
|
96
|
-
|
|
106
|
+
bitcoin_node_cli connections
|
|
97
107
|
|
|
98
108
|
==== connect
|
|
99
109
|
|
|
100
110
|
Connect to given peer(s).
|
|
101
111
|
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
136
|
+
bitcoin_node_cli addrs [count]
|
|
127
137
|
|
|
128
138
|
==== tslb
|
|
129
139
|
|
|
130
140
|
Get Time Since Last Block.
|
|
131
141
|
|
|
132
|
-
|
|
142
|
+
bitcoin_node_cli tslb
|
|
133
143
|
|
|
134
144
|
==== create_tx
|
|
135
145
|
|
|
136
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
189
|
+
bitcoin_node_cli stop
|
|
165
190
|
|
|
166
191
|
==== help
|
|
167
192
|
|
|
168
193
|
List all available commands.
|
|
169
194
|
|
|
170
|
-
|
|
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
|