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