bitcoin-ruby 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +2 -7
- data/COPYING +1 -1
- data/Gemfile +2 -6
- data/Gemfile.lock +34 -0
- data/README.rdoc +16 -68
- data/Rakefile +3 -6
- data/bin/bitcoin_shell +0 -1
- data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
- data/lib/bitcoin.rb +350 -296
- data/lib/bitcoin/builder.rb +3 -1
- data/lib/bitcoin/connection.rb +2 -1
- data/lib/bitcoin/contracthash.rb +76 -0
- data/lib/bitcoin/dogecoin.rb +97 -0
- data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
- data/lib/bitcoin/ffi/openssl.rb +98 -2
- data/lib/bitcoin/ffi/secp256k1.rb +144 -0
- data/lib/bitcoin/key.rb +12 -2
- data/lib/bitcoin/logger.rb +3 -12
- data/lib/bitcoin/protocol/block.rb +3 -9
- data/lib/bitcoin/protocol/parser.rb +6 -2
- data/lib/bitcoin/protocol/tx.rb +44 -13
- data/lib/bitcoin/protocol/txin.rb +4 -2
- data/lib/bitcoin/protocol/txout.rb +2 -2
- data/lib/bitcoin/script.rb +212 -37
- data/lib/bitcoin/trezor/mnemonic.rb +130 -0
- data/lib/bitcoin/version.rb +1 -1
- data/spec/bitcoin/bitcoin_spec.rb +32 -3
- data/spec/bitcoin/builder_spec.rb +18 -0
- data/spec/bitcoin/contracthash_spec.rb +45 -0
- data/spec/bitcoin/dogecoin_spec.rb +176 -0
- data/spec/bitcoin/ffi_openssl.rb +45 -0
- data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
- data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
- data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
- data/spec/bitcoin/fixtures/coinbase.json +24 -0
- data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
- data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
- data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
- data/spec/bitcoin/protocol/block_spec.rb +0 -22
- data/spec/bitcoin/protocol/tx_spec.rb +145 -2
- data/spec/bitcoin/script/script_spec.rb +282 -0
- data/spec/bitcoin/secp256k1_spec.rb +48 -0
- data/spec/bitcoin/spec_helper.rb +0 -51
- data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
- metadata +48 -98
- data/bin/bitcoin_dns_seed +0 -130
- data/bin/bitcoin_gui +0 -80
- data/bin/bitcoin_node +0 -153
- data/bin/bitcoin_node_cli +0 -81
- data/bin/bitcoin_wallet +0 -402
- data/doc/CONFIG.rdoc +0 -66
- data/doc/EXAMPLES.rdoc +0 -13
- data/doc/NAMECOIN.rdoc +0 -34
- data/doc/NODE.rdoc +0 -225
- data/doc/STORAGE.rdoc +0 -33
- data/doc/WALLET.rdoc +0 -102
- data/examples/balance.rb +0 -66
- data/examples/forwarder.rb +0 -73
- data/examples/index_nhash.rb +0 -24
- data/examples/reindex_p2sh_addrs.rb +0 -44
- data/examples/relay_tx.rb +0 -22
- data/examples/verify_tx.rb +0 -57
- data/lib/bitcoin/config.rb +0 -58
- data/lib/bitcoin/gui/addr_view.rb +0 -44
- data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
- data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
- data/lib/bitcoin/gui/conn_view.rb +0 -38
- data/lib/bitcoin/gui/connection.rb +0 -70
- data/lib/bitcoin/gui/em_gtk.rb +0 -30
- data/lib/bitcoin/gui/gui.builder +0 -1643
- data/lib/bitcoin/gui/gui.rb +0 -292
- data/lib/bitcoin/gui/helpers.rb +0 -115
- data/lib/bitcoin/gui/tree_view.rb +0 -84
- data/lib/bitcoin/gui/tx_view.rb +0 -69
- data/lib/bitcoin/namecoin.rb +0 -280
- data/lib/bitcoin/network/command_client.rb +0 -104
- data/lib/bitcoin/network/command_handler.rb +0 -570
- data/lib/bitcoin/network/connection_handler.rb +0 -387
- data/lib/bitcoin/network/node.rb +0 -565
- data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
- data/lib/bitcoin/storage/models.rb +0 -171
- data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
- data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
- data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
- data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
- data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
- data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
- data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
- data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
- data/lib/bitcoin/storage/storage.rb +0 -517
- data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
- data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
- data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
- data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
- data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
- data/lib/bitcoin/validation.rb +0 -400
- data/lib/bitcoin/wallet/coinselector.rb +0 -33
- data/lib/bitcoin/wallet/keygenerator.rb +0 -77
- data/lib/bitcoin/wallet/keystore.rb +0 -207
- data/lib/bitcoin/wallet/txdp.rb +0 -118
- data/lib/bitcoin/wallet/wallet.rb +0 -281
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
- data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
- data/spec/bitcoin/namecoin_spec.rb +0 -182
- data/spec/bitcoin/node/command_api_spec.rb +0 -663
- data/spec/bitcoin/storage/models_spec.rb +0 -104
- data/spec/bitcoin/storage/reorg_spec.rb +0 -236
- data/spec/bitcoin/storage/storage_spec.rb +0 -387
- data/spec/bitcoin/storage/validation_spec.rb +0 -300
- data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
- data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
- data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
- data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
- data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8a85933bb6f2c36c0262cbfc0b254bfb5449e9d
|
4
|
+
data.tar.gz: a61c9750f801b78ccb01350d2f777560f73bdb9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cb472579d3e819c18025e3fef9b2db6c36e3bdab701b6984482920ada6d07b736af0170512fc7598fd904d8c9104c311c64fa3f3bb87d77acc9310db49e1e71
|
7
|
+
data.tar.gz: 1d0f4d2c551a89433620e87ec391be57edbca0af200df5e9df6b80ab6cd73b8092f36b4030caa3b12671f920a03b2f7dad5189c473e594427f09520641f0db01
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9.3
|
4
3
|
- 2.0.0
|
5
|
-
- 2.1.
|
6
|
-
|
7
|
-
- psql -c 'create database bitcoin_test;' -U postgres
|
8
|
-
- mysql -e 'create database bitcoin_test;'
|
9
|
-
env:
|
10
|
-
- TEST_DB_POSTGRES="postgres://postgres@localhost/bitcoin_test" TEST_DB_MYSQL="mysql:/bitcoin_test"
|
4
|
+
- 2.1.2
|
5
|
+
- 2.2.0
|
data/COPYING
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2015 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
@@ -6,14 +6,10 @@ gemspec
|
|
6
6
|
group :development do
|
7
7
|
gem 'eventmachine'
|
8
8
|
gem 'ffi'
|
9
|
-
gem 'log4r'
|
10
|
-
gem 'sequel'
|
11
9
|
gem 'scrypt'
|
12
|
-
|
13
|
-
gem 'sqlite3', platforms: :ruby, require: false
|
14
|
-
gem 'pg', platforms: :ruby, require: false
|
10
|
+
gem 'minitest'
|
15
11
|
|
16
12
|
gem "rake", ">= 0.8.0"
|
17
13
|
gem 'bacon', '>= 1.2.0'
|
18
|
-
gem 'simplecov', require: false
|
14
|
+
#gem 'simplecov', require: false
|
19
15
|
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bitcoin-ruby (0.0.7)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
bacon (1.2.0)
|
10
|
+
eventmachine (1.0.7)
|
11
|
+
ffi (1.9.8)
|
12
|
+
ffi-compiler (0.1.3)
|
13
|
+
ffi (>= 1.0.0)
|
14
|
+
rake
|
15
|
+
minitest (5.7.0)
|
16
|
+
rake (10.4.2)
|
17
|
+
scrypt (2.0.0)
|
18
|
+
ffi-compiler (>= 0.0.2)
|
19
|
+
rake
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
bacon (>= 1.2.0)
|
26
|
+
bitcoin-ruby!
|
27
|
+
eventmachine
|
28
|
+
ffi
|
29
|
+
minitest
|
30
|
+
rake (>= 0.8.0)
|
31
|
+
scrypt
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
1.10.2
|
data/README.rdoc
CHANGED
@@ -1,76 +1,59 @@
|
|
1
|
-
= Bitcoin-ruby {<img src="https://api.travis-ci.org/lian/bitcoin-ruby.svg?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] {<img src="http://inch-ci.org/github/lian/bitcoin-ruby.svg?branch=master" alt="Inline docs" />}[http://inch-ci.org/github/lian/bitcoin-ruby] {<img src="https://tip4commit.com/projects/108.svg" alt="tip for next commit" />}[https://tip4commit.com/github/lian/bitcoin-ruby]
|
2
2
|
|
3
3
|
This is a ruby library for interacting with the bitcoin protocol/network.
|
4
4
|
|
5
5
|
Some of the main features are:
|
6
6
|
|
7
7
|
* Bitcoin::Util provides the basic bitcoin utility functions for base58, ECC, etc.
|
8
|
-
* Bitcoin::Protocol can parse/create
|
9
|
-
* Bitcoin::Network::Node connects to peers, fetches the blockchain and keeps it up to date
|
10
|
-
(see NODE for usage)
|
11
|
-
* Bitcoin::Validation validates block and transaction rules
|
12
|
-
* Bitcoin::Storage stores the blockchain and can be queried for transaction data
|
8
|
+
* Bitcoin::Protocol can parse/create all protocol messages
|
13
9
|
* Bitcoin::Script implementation, create/run scripts and verify signatures
|
14
10
|
* Bitcoin::Key provides a high-level API for creating and handling keys/addresses
|
15
11
|
* Bitcoin::Builder provides a high-level API for creating transactions (and blocks)
|
16
|
-
* Bitcoin::
|
17
|
-
|
18
|
-
|
12
|
+
* Bitcoin::Litecoin implements all the litecoin-specific differences
|
13
|
+
|
14
|
+
== Related Projects
|
15
|
+
|
16
|
+
* toshi[https://github.com/coinbase/toshi]
|
17
|
+
* bitcoin-ruby-blockchain[http://github.com/mhanne/bitcoin-ruby-blockchain]
|
18
|
+
* bitcoin-ruby-node[http://github.com/mhanne/bitcoin-ruby-node]
|
19
|
+
* bitcoin-ruby-wallet[http://github.com/mhanne/bitcoin-ruby-wallet]
|
20
|
+
* bitcoin-ruby-gui[http://github.com/mhanne/bitcoin-ruby-gui]
|
21
|
+
* namecoin-ruby[http://github.com/mhanne/namecoin-ruby]
|
19
22
|
|
20
23
|
== Compatible with...
|
21
24
|
|
22
25
|
* ruby 1.9.3
|
23
26
|
* ruby 2.0.0
|
24
27
|
* ruby 2.1.2
|
28
|
+
* ruby 2.2.0
|
29
|
+
* ruby 2.2.2
|
25
30
|
|
26
31
|
== Installation
|
27
32
|
|
28
33
|
We assume you already have a ruby 1.9 or 2.0 compatible interpreter and rubygems environment.
|
29
34
|
|
30
35
|
git clone https://github.com/lian/bitcoin-ruby.git; cd bitcoin-ruby
|
31
|
-
ruby -Ilib bin/bitcoin_node
|
32
36
|
|
33
37
|
if you want to have it available system-wide, just build the gem and install it:
|
34
38
|
|
35
39
|
gem build bitcoin-ruby.gemspec && gem install bitcoin-ruby-0.0.5.gem
|
36
40
|
|
37
|
-
now you can just call +bitcoin_node+ from anywhere.
|
38
|
-
|
39
|
-
|
40
41
|
Note that some aspects of the library (such as networking, storage, etc.) need
|
41
42
|
additional dependencies which are not specified in the gemspec. The core requirements are
|
42
43
|
intentionally kept to a minimum, so nobody has to install unneeded dependencies.
|
43
44
|
|
44
|
-
* +eventmachine+ to run a node / connect to peers
|
45
|
-
* +sequel+, +sqlite3+/+pg+/+mysql+ to use a storage backend
|
46
|
-
* +em-dns+ or +nslookup+ to get peer addrs from DNS seeds
|
47
|
-
* +gir_ffi+ for the gui
|
48
45
|
* +bacon+ to run the specs
|
49
46
|
* +scrypt+ to use a much faster scrypt hash implementation for Litecoin
|
50
47
|
|
51
48
|
If you would like to install using Bundler, put it in your Gemfile and run bundle install
|
52
49
|
gem 'bitcoin-ruby', git: 'https://github.com/lian/bitcoin-ruby', branch: 'master', require: 'bitcoin'
|
53
50
|
|
54
|
-
== Client
|
55
|
-
|
56
|
-
There is a node which connects to the network and downloads
|
57
|
-
the blockchain into a database. see NODE, Bitcoin::Network::Node.
|
58
|
-
|
59
|
-
It also opens an extra socket where local clients can query statistics,
|
60
|
-
monitor blockchain data, and relay their own transactions to the network.
|
61
|
-
see NODE, Bitcoin::Network::CommandHandler, Bitcoin::Network::CommandClient.
|
62
|
-
|
63
|
-
There is a WALLET implementation to manage a set of keys, list balances and create
|
64
|
-
transactions. see WALLET, Bitcoin::Wallet.
|
65
|
-
|
66
|
-
|
67
51
|
== Library Usage
|
68
52
|
|
69
53
|
There are different aspects to the library which can be used separately or in combination.
|
70
54
|
Here are some ideas of what you could do. There are also some demo scripts in examples/,
|
71
55
|
see EXAMPLES.
|
72
56
|
|
73
|
-
|
74
57
|
=== Keys/Addresses
|
75
58
|
|
76
59
|
Generate a Bitcoin::Key
|
@@ -192,43 +175,13 @@ as well as the private key for the address required to sign for it.
|
|
192
175
|
# that will also give you a hint on the error if something goes wrong
|
193
176
|
puts new_tx.to_json
|
194
177
|
|
195
|
-
=== Node / Network connections
|
196
|
-
|
197
|
-
The Bitcoin::Network::Node can connect to peers and download the blockchain into a
|
198
|
-
Bitcoin::Storage backend. For now it works completely self-contained:
|
199
|
-
|
200
|
-
node = Bitcoin::Network::Node.new(options) # options = {network: :bitcoin, ...}
|
201
|
-
node.run
|
202
|
-
|
203
|
-
In the future you will be able to register callbacks to the node and control many aspects
|
204
|
-
of its operation yourself. Also see NODE.
|
205
|
-
|
206
|
-
If you want to implement your own node, see lib/bitcoin/connection.rb or
|
207
|
-
lib/bitcoin/network/node.rb for examples.
|
208
|
-
|
209
|
-
|
210
|
-
=== Storage / Database backends
|
211
|
-
|
212
|
-
There is support for different storage backends. Each backend can be used with
|
213
|
-
sqlite, postgres or mysql. All backends implement the interface defined in
|
214
|
-
Bitcoin::Storage::Backends::StoreBase and return Bitcoin::Storage::Models.
|
215
|
-
|
216
|
-
store = Bitcoin::Storage.sequel(:db => "sqlite://bitcoin.db") # in-memory db
|
217
|
-
store.get_head #=> block
|
218
|
-
txouts = store.get_txouts_for_address("15yN7NPEpu82sHhB6TzCW5z5aXoamiKeGy")
|
219
|
-
txouts.first.value #=> 5000000000
|
220
|
-
txouts.first.type #=> :pubkey
|
221
|
-
txouts.first.get_address #=> "15yN7NPEpu82sHhB6TzCW5z5aXoamiKeGy"
|
222
|
-
|
223
|
-
See also STORAGE, Bitcoin::Storage::Backends::UtxoStore, Bitcoin::Storage::Backends::SequelStore and Bitcoin::Storage::Backends::DummyStore for details.
|
224
|
-
|
225
178
|
== Documentation
|
226
179
|
|
227
180
|
Always trying to improve, any help appreciated! If anything is unclear to you, let us know!
|
228
181
|
|
229
|
-
Documentation is generated using
|
182
|
+
Documentation is generated using yardoc:
|
230
183
|
|
231
|
-
rake
|
184
|
+
rake doc
|
232
185
|
|
233
186
|
The specs are also a good place to see how something works.
|
234
187
|
|
@@ -242,11 +195,6 @@ or, if you want to run a single spec
|
|
242
195
|
|
243
196
|
ruby spec/bitcoin/bitcoin_spec.rb
|
244
197
|
|
245
|
-
To test the postgres/mysql storage backend, create a database and set it as an environment variable:
|
246
|
-
|
247
|
-
echo "create database bitcoin_test" | psql
|
248
|
-
TEST_DB_POSTGRES="postgres:/bitcoin_test" rake bacon
|
249
|
-
|
250
198
|
If you make changes to the code or add functionality, please also add specs.
|
251
199
|
|
252
200
|
== Development
|
data/Rakefile
CHANGED
@@ -7,11 +7,7 @@ end
|
|
7
7
|
PROJECT_SPECS = ( FileList['spec/bitcoin/bitcoin_spec.rb'] +
|
8
8
|
FileList['spec/bitcoin/protocol/*_spec.rb'] +
|
9
9
|
FileList['spec/bitcoin/script/*_spec.rb'] +
|
10
|
-
FileList['spec/bitcoin/
|
11
|
-
['spec/bitcoin/storage/storage_spec.rb',
|
12
|
-
'spec/bitcoin/storage/reorg_spec.rb',
|
13
|
-
'spec/bitcoin/storage/validation_spec.rb'] +
|
14
|
-
FileList['spec/bitcoin/node/*_spec.rb'] +
|
10
|
+
FileList['spec/bitcoin/trezor/*_spec.rb'] +
|
15
11
|
FileList['spec/bitcoin/*_spec.rb'] ).uniq
|
16
12
|
|
17
13
|
RUBY = 'ruby' unless defined?(RUBY)
|
@@ -28,6 +24,7 @@ task :bacon do
|
|
28
24
|
|
29
25
|
specs = PROJECT_SPECS
|
30
26
|
#specs.delete_if{|i| File.basename(i) == 'storage_spec.rb' } # skip for now
|
27
|
+
specs.delete_if{|i| File.basename(i) == 'secp256k1_spec.rb' } # skip for now
|
31
28
|
|
32
29
|
# E.g. SPEC=specs/bitcoin/script/ to run script-related specs only.
|
33
30
|
if spec_mask = ENV["SPEC"]
|
@@ -97,7 +94,7 @@ end
|
|
97
94
|
desc 'Generate RDoc documentation'
|
98
95
|
task :rdoc do
|
99
96
|
`rm -rf rdoc`
|
100
|
-
system("rdoc -a -A -H -t 'bitcoin-ruby RDoc' -W '
|
97
|
+
system("rdoc -a -A -H -t 'bitcoin-ruby RDoc' -W 'https://github.com/mhanne/bitcoin-ruby/tree/master/%s' -o rdoc -m README.rdoc examples/ doc/ lib/ README.rdoc COPYING")
|
101
98
|
end
|
102
99
|
|
103
100
|
desc 'Generate test coverage report'
|
data/bin/bitcoin_shell
CHANGED
File without changes
|
data/lib/bitcoin.rb
CHANGED
@@ -13,51 +13,19 @@ module Bitcoin
|
|
13
13
|
autoload :P, 'bitcoin/protocol'
|
14
14
|
autoload :Script, 'bitcoin/script'
|
15
15
|
autoload :VERSION, 'bitcoin/version'
|
16
|
-
autoload :Storage, 'bitcoin/storage/storage'
|
17
16
|
autoload :Logger, 'bitcoin/logger'
|
18
17
|
autoload :Key, 'bitcoin/key'
|
19
|
-
autoload :Config, 'bitcoin/config'
|
20
18
|
autoload :Builder, 'bitcoin/builder'
|
21
|
-
autoload :Validation, 'bitcoin/validation'
|
22
19
|
|
23
|
-
autoload :
|
20
|
+
autoload :Dogecoin, 'bitcoin/dogecoin'
|
24
21
|
autoload :Litecoin, 'bitcoin/litecoin'
|
25
22
|
|
26
|
-
|
27
|
-
autoload :ConnectionHandler, 'bitcoin/network/connection_handler'
|
28
|
-
autoload :CommandHandler, 'bitcoin/network/command_handler'
|
29
|
-
autoload :CommandClient, 'bitcoin/network/command_client'
|
30
|
-
autoload :Node, 'bitcoin/network/node'
|
31
|
-
end
|
32
|
-
|
33
|
-
module Wallet
|
34
|
-
autoload :KeyGenerator, 'bitcoin/wallet/keygenerator'
|
35
|
-
autoload :SimpleKeyStore, 'bitcoin/wallet/keystore'
|
36
|
-
autoload :DeterministicKeyStore, 'bitcoin/wallet/keystore'
|
37
|
-
autoload :SimpleCoinSelector, 'bitcoin/wallet/coinselector'
|
38
|
-
autoload :Wallet, 'bitcoin/wallet/wallet'
|
39
|
-
autoload :TxDP, 'bitcoin/wallet/txdp'
|
40
|
-
end
|
23
|
+
autoload :ContractHash, 'bitcoin/contracthash'
|
41
24
|
|
42
|
-
module
|
43
|
-
autoload :
|
44
|
-
autoload :Connection, 'bitcoin/gui/connection'
|
25
|
+
module Trezor
|
26
|
+
autoload :Mnemonic, 'bitcoin/trezor/mnemonic'
|
45
27
|
end
|
46
28
|
|
47
|
-
def self.require_dependency name, opts = {}
|
48
|
-
begin
|
49
|
-
require name.to_s
|
50
|
-
rescue LoadError
|
51
|
-
return false if name.to_s == "log4r"
|
52
|
-
print "Cannot load #{opts[:exit] == false ? 'optional' : 'required'} dependency '#{name}'"
|
53
|
-
(opts[:gem] == false) ? puts("") :
|
54
|
-
puts(" - install with `gem install #{opts[:gem] || name}`")
|
55
|
-
puts opts[:message] if opts[:message]
|
56
|
-
exit 1 unless opts[:exit] == false
|
57
|
-
return false
|
58
|
-
end
|
59
|
-
true
|
60
|
-
end
|
61
29
|
|
62
30
|
module Util
|
63
31
|
|
@@ -80,7 +48,7 @@ module Bitcoin
|
|
80
48
|
def base58_checksum?(base58)
|
81
49
|
hex = decode_base58(base58) rescue nil
|
82
50
|
return false unless hex
|
83
|
-
|
51
|
+
checksum( hex[0...42] ) == hex[-8..-1]
|
84
52
|
end
|
85
53
|
alias :address_checksum? :base58_checksum?
|
86
54
|
|
@@ -93,6 +61,14 @@ module Bitcoin
|
|
93
61
|
address_checksum?(address)
|
94
62
|
end
|
95
63
|
|
64
|
+
# check if given +pubkey+ is valid.
|
65
|
+
def valid_pubkey?(pubkey)
|
66
|
+
::OpenSSL::PKey::EC::Point.from_hex(bitcoin_elliptic_curve.group, pubkey)
|
67
|
+
true
|
68
|
+
rescue OpenSSL::PKey::EC::Point::Error
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
96
72
|
# get hash160 for given +address+. returns nil if address is invalid.
|
97
73
|
def hash160_from_address(address)
|
98
74
|
return nil unless valid_address?(address)
|
@@ -159,7 +135,6 @@ module Bitcoin
|
|
159
135
|
("1"*leading_zero_bytes) + int_to_base58( hex.to_i(16) )
|
160
136
|
end
|
161
137
|
|
162
|
-
|
163
138
|
def decode_base58(base58_val)
|
164
139
|
s = base58_to_int(base58_val).to_s(16); s = (s.bytesize.odd? ? '0'+s : s)
|
165
140
|
s = '' if s == '00'
|
@@ -171,11 +146,25 @@ module Bitcoin
|
|
171
146
|
|
172
147
|
# target compact bits (int) to bignum hex
|
173
148
|
def decode_compact_bits(bits)
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
149
|
+
if Bitcoin.network_project == :dogecoin
|
150
|
+
bytes = Array.new(size=((bits >> 24) & 255), 0)
|
151
|
+
bytes[0] = (bits >> 16) & 0x7f if size >= 1
|
152
|
+
bytes[1] = (bits >> 8) & 255 if size >= 2
|
153
|
+
bytes[2] = (bits ) & 255 if size >= 3
|
154
|
+
target = bytes.pack("C*").unpack("H*")[0].rjust(64, '0')
|
155
|
+
# Bit number 24 represents the sign
|
156
|
+
if (bits & 0x00800000) != 0
|
157
|
+
"-" + target
|
158
|
+
else
|
159
|
+
target
|
160
|
+
end
|
161
|
+
else
|
162
|
+
bytes = Array.new(size=((bits >> 24) & 255), 0)
|
163
|
+
bytes[0] = (bits >> 16) & 255 if size >= 1
|
164
|
+
bytes[1] = (bits >> 8) & 255 if size >= 2
|
165
|
+
bytes[2] = (bits ) & 255 if size >= 3
|
166
|
+
bytes.pack("C*").unpack("H*")[0].rjust(64, '0')
|
167
|
+
end
|
179
168
|
end
|
180
169
|
|
181
170
|
# target bignum hex to compact bits (int)
|
@@ -219,7 +208,7 @@ module Bitcoin
|
|
219
208
|
def bitcoin_hash(hex)
|
220
209
|
Digest::SHA256.digest(
|
221
210
|
Digest::SHA256.digest( [hex].pack("H*").reverse )
|
222
|
-
).reverse.
|
211
|
+
).reverse.bth
|
223
212
|
end
|
224
213
|
|
225
214
|
def bitcoin_byte_hash(bytes)
|
@@ -256,8 +245,7 @@ module Bitcoin
|
|
256
245
|
return [nil] if tx != tx.uniq
|
257
246
|
chunks = [ tx.dup ]
|
258
247
|
while chunks.last.size >= 2
|
259
|
-
chunks << chunks.last.each_slice(2).map {|a, b|
|
260
|
-
Bitcoin.bitcoin_mrkl( a, b || a ) }
|
248
|
+
chunks << chunks.last.each_slice(2).map {|a, b| bitcoin_mrkl( a, b || a ) }
|
261
249
|
end
|
262
250
|
chunks.flatten
|
263
251
|
end
|
@@ -268,7 +256,7 @@ module Bitcoin
|
|
268
256
|
branch, chunks = [], [ tx.dup ]
|
269
257
|
while chunks.last.size >= 2
|
270
258
|
chunks << chunks.last.each_slice(2).map {|a, b|
|
271
|
-
hash =
|
259
|
+
hash = bitcoin_mrkl( a, b || a )
|
272
260
|
next hash unless [a, b].include?(target)
|
273
261
|
branch << (a == target ? (b || a) : a)
|
274
262
|
target = hash
|
@@ -279,21 +267,33 @@ module Bitcoin
|
|
279
267
|
|
280
268
|
# get merkle root from +branch+ and +target+.
|
281
269
|
def mrkl_branch_root(branch, target, idx)
|
282
|
-
branch.
|
270
|
+
branch.each do |hash|
|
283
271
|
a, b = *( idx & 1 == 0 ? [target, hash] : [hash, target] )
|
284
|
-
idx >>= 1;
|
285
|
-
|
272
|
+
idx >>= 1;
|
273
|
+
target = bitcoin_mrkl( a, b )
|
274
|
+
end
|
275
|
+
target
|
286
276
|
end
|
287
277
|
|
288
278
|
def sign_data(key, data)
|
289
|
-
key.dsa_sign_asn1(data)
|
279
|
+
sig = key.dsa_sign_asn1(data)
|
280
|
+
if Script.is_low_der_signature?(sig)
|
281
|
+
sig
|
282
|
+
else
|
283
|
+
Bitcoin::OpenSSL_EC.signature_to_low_s(sig)
|
284
|
+
end
|
290
285
|
end
|
291
286
|
|
292
287
|
def verify_signature(hash, signature, public_key)
|
293
288
|
key = bitcoin_elliptic_curve
|
294
289
|
key.public_key = ::OpenSSL::PKey::EC::Point.from_hex(key.group, public_key)
|
295
|
-
|
296
|
-
|
290
|
+
signature = Bitcoin::OpenSSL_EC.repack_der_signature(signature)
|
291
|
+
if signature
|
292
|
+
key.dsa_verify_asn1(hash, signature)
|
293
|
+
else
|
294
|
+
false
|
295
|
+
end
|
296
|
+
rescue OpenSSL::PKey::ECError, OpenSSL::PKey::EC::Point::Error, OpenSSL::BNError
|
297
297
|
false
|
298
298
|
end
|
299
299
|
|
@@ -306,7 +306,7 @@ module Bitcoin
|
|
306
306
|
end
|
307
307
|
|
308
308
|
def regenerate_public_key(private_key)
|
309
|
-
|
309
|
+
OpenSSL_EC.regenerate_key(private_key)[1]
|
310
310
|
end
|
311
311
|
|
312
312
|
def bitcoin_signed_message_hash(message)
|
@@ -317,23 +317,20 @@ module Bitcoin
|
|
317
317
|
|
318
318
|
def sign_message(private_key_hex, public_key_hex, message)
|
319
319
|
hash = bitcoin_signed_message_hash(message)
|
320
|
-
signature =
|
320
|
+
signature = OpenSSL_EC.sign_compact(hash, private_key_hex, public_key_hex)
|
321
321
|
{ 'address' => pubkey_to_address(public_key_hex), 'message' => message, 'signature' => [ signature ].pack("m0") }
|
322
322
|
end
|
323
323
|
|
324
324
|
def verify_message(address, signature, message)
|
325
|
-
hash = bitcoin_signed_message_hash(message)
|
326
325
|
signature = signature.unpack("m0")[0] rescue nil # decode base64
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
326
|
+
return false unless valid_address?(address)
|
327
|
+
return false unless signature
|
328
|
+
return false unless signature.bytesize == 65
|
329
|
+
hash = bitcoin_signed_message_hash(message)
|
330
|
+
pubkey = OpenSSL_EC.recover_compact(hash, signature)
|
331
331
|
pubkey_to_address(pubkey) == address if pubkey
|
332
|
-
rescue => ex
|
333
|
-
p [ex.message, ex.backtrace]; false
|
334
332
|
end
|
335
333
|
|
336
|
-
|
337
334
|
# block count when the next retarget will take place.
|
338
335
|
def block_next_retarget(block_height)
|
339
336
|
(block_height + (RETARGET_INTERVAL-block_height.divmod(RETARGET_INTERVAL).last)) - 1
|
@@ -348,15 +345,47 @@ module Bitcoin
|
|
348
345
|
"%.7f" % Math.exp(max_body - Math.log(bits&0x00ffffff) + scaland * (0x1d - ((bits&0xff000000)>>24)))
|
349
346
|
end
|
350
347
|
|
348
|
+
# Calculate new difficulty target. Note this takes in details of the preceeding
|
349
|
+
# block, not the current one.
|
350
|
+
#
|
351
|
+
# prev_height is the height of the block before the retarget occurs
|
352
|
+
# prev_block_time "time" field from the block before the retarget occurs
|
353
|
+
# prev_block_bits "bits" field from the block before the retarget occurs (target as a compact value)
|
354
|
+
# last_retarget_time is the "time" field from the block when a retarget last occurred
|
355
|
+
def block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time)
|
356
|
+
# target interval - what is the ideal interval between the blocks
|
357
|
+
retarget_time = Bitcoin.network[:retarget_time]
|
358
|
+
|
359
|
+
actual_time = prev_block_time - last_retarget_time
|
360
|
+
|
361
|
+
min = retarget_time / 4
|
362
|
+
max = retarget_time * 4
|
363
|
+
|
364
|
+
actual_time = min if actual_time < min
|
365
|
+
actual_time = max if actual_time > max
|
366
|
+
|
367
|
+
# It could be a bit confusing: we are adjusting difficulty of the previous block, while logically
|
368
|
+
# we should use difficulty of the previous retarget block
|
369
|
+
|
370
|
+
prev_target = decode_compact_bits(prev_block_bits).to_i(16)
|
371
|
+
|
372
|
+
new_target = prev_target * actual_time / retarget_time
|
373
|
+
if new_target < Bitcoin.decode_compact_bits(Bitcoin.network[:proof_of_work_limit]).to_i(16)
|
374
|
+
encode_compact_bits(new_target.to_s(16))
|
375
|
+
else
|
376
|
+
Bitcoin.network[:proof_of_work_limit]
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
351
380
|
# average number of hashes required to win a block with the current target. (nbits)
|
352
381
|
def block_hashes_to_win(target_nbits)
|
353
|
-
current_target =
|
382
|
+
current_target = decode_compact_bits(target_nbits).to_i(16)
|
354
383
|
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff / current_target
|
355
384
|
end
|
356
385
|
|
357
386
|
# probability of a single hash solving a block with the current difficulty.
|
358
387
|
def block_probability(target_nbits)
|
359
|
-
current_target =
|
388
|
+
current_target = decode_compact_bits(target_nbits).to_i(16)
|
360
389
|
"%.55f" % (current_target.to_f / 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
|
361
390
|
end
|
362
391
|
|
@@ -368,13 +397,13 @@ module Bitcoin
|
|
368
397
|
# average mining time (in days) using Mh/s to get btc
|
369
398
|
def block_average_mining_time(block_nbits, block_height, mega_hashes_per_second, target_btc=1.0)
|
370
399
|
seconds = block_average_hashing_time(block_nbits, mega_hashes_per_second * 1_000_000)
|
371
|
-
reward = block_creation_reward(block_height) /
|
400
|
+
reward = block_creation_reward(block_height) / COIN # satoshis to btc
|
372
401
|
(days = seconds / 60 / 60 / 24) * (target_btc / reward)
|
373
402
|
end
|
374
403
|
|
375
404
|
# shows the total number of Bitcoins in circulation, reward era and reward in that era.
|
376
405
|
def blockchain_total_btc(height)
|
377
|
-
reward, interval =
|
406
|
+
reward, interval = Bitcoin.network[:reward_base], Bitcoin.network[:reward_halving]
|
378
407
|
total_btc = reward
|
379
408
|
reward_era, remainder = (height).divmod(interval)
|
380
409
|
reward_era.times{
|
@@ -386,7 +415,7 @@ module Bitcoin
|
|
386
415
|
end
|
387
416
|
|
388
417
|
def block_creation_reward(block_height)
|
389
|
-
|
418
|
+
Bitcoin.network[:reward_base] / (2 ** (block_height / Bitcoin.network[:reward_halving].to_f).floor)
|
390
419
|
end
|
391
420
|
end
|
392
421
|
|
@@ -394,10 +423,14 @@ module Bitcoin
|
|
394
423
|
|
395
424
|
|
396
425
|
module BinaryExtensions
|
397
|
-
|
398
|
-
def
|
426
|
+
# bin-to-hex
|
427
|
+
def bth; unpack("H*")[0]; end
|
428
|
+
# hex-to-bin
|
399
429
|
def htb; [self].pack("H*"); end
|
430
|
+
|
400
431
|
def htb_reverse; htb.reverse; end
|
432
|
+
def hth; unpack("H*")[0]; end
|
433
|
+
def reverse_hth; reverse.hth; end
|
401
434
|
end
|
402
435
|
|
403
436
|
class ::String
|
@@ -422,11 +455,15 @@ module Bitcoin
|
|
422
455
|
end
|
423
456
|
def to_hex; to_bn.to_hex; end
|
424
457
|
def self.bn2mpi(hex) BN.from_hex(hex).to_mpi; end
|
458
|
+
def ec_add(point); self.class.new(group, OpenSSL::BN.from_hex(OpenSSL_EC.ec_add(self, point))); end
|
425
459
|
end
|
426
460
|
end
|
427
461
|
|
428
462
|
autoload :OpenSSL_EC, "bitcoin/ffi/openssl"
|
429
463
|
|
464
|
+
autoload :Secp256k1, "bitcoin/ffi/secp256k1"
|
465
|
+
autoload :BitcoinConsensus, "bitcoin/ffi/bitcoinconsensus"
|
466
|
+
|
430
467
|
@network = :bitcoin
|
431
468
|
|
432
469
|
def self.network
|
@@ -447,11 +484,12 @@ module Bitcoin
|
|
447
484
|
@network_options = nil # clear cached parameters
|
448
485
|
@network = name.to_sym
|
449
486
|
@network_project = network[:project] rescue nil
|
450
|
-
|
487
|
+
Dogecoin.load if dogecoin? || dogecoin_testnet?
|
488
|
+
Namecoin.load if namecoin? && defined?(Namecoin)
|
451
489
|
@network
|
452
490
|
end
|
453
491
|
|
454
|
-
[:bitcoin, :namecoin, :litecoin, :
|
492
|
+
[:bitcoin, :namecoin, :litecoin, :dogecoin, :dogecoin_testnet].each do |n|
|
455
493
|
instance_eval "def #{n}?; network_project == :#{n}; end"
|
456
494
|
end
|
457
495
|
|
@@ -492,41 +530,44 @@ module Bitcoin
|
|
492
530
|
MIN_FEE_MODE = [ :block, :relay, :send ]
|
493
531
|
|
494
532
|
NETWORKS = {
|
495
|
-
|
496
|
-
|
497
|
-
:
|
498
|
-
:
|
499
|
-
:
|
500
|
-
:
|
501
|
-
:
|
502
|
-
:
|
503
|
-
:
|
504
|
-
:
|
505
|
-
:
|
506
|
-
:
|
507
|
-
:
|
508
|
-
:
|
509
|
-
:
|
510
|
-
:
|
511
|
-
:
|
512
|
-
:
|
513
|
-
:
|
514
|
-
:
|
533
|
+
bitcoin: {
|
534
|
+
project: :bitcoin,
|
535
|
+
magic_head: "\xF9\xBE\xB4\xD9",
|
536
|
+
address_version: "00",
|
537
|
+
p2sh_version: "05",
|
538
|
+
privkey_version: "80",
|
539
|
+
extended_privkey_version: "0488ade4",
|
540
|
+
extended_pubkey_version: "0488b21e",
|
541
|
+
default_port: 8333,
|
542
|
+
protocol_version: 70001,
|
543
|
+
coinbase_maturity: 100,
|
544
|
+
reward_base: 50 * COIN,
|
545
|
+
reward_halving: 210_000,
|
546
|
+
retarget_interval: 2016,
|
547
|
+
retarget_time: 1209600, # 2 weeks
|
548
|
+
target_spacing: 600, # block interval
|
549
|
+
max_money: 21_000_000 * COIN,
|
550
|
+
min_tx_fee: 10_000,
|
551
|
+
min_relay_tx_fee: 10_000,
|
552
|
+
free_tx_bytes: 1_000,
|
553
|
+
dust: CENT,
|
554
|
+
per_dust_fee: false,
|
555
|
+
dns_seeds: [
|
515
556
|
"seed.bitcoin.sipa.be",
|
516
557
|
"dnsseed.bluematt.me",
|
517
558
|
"dnsseed.bitcoin.dashjr.org",
|
518
559
|
"bitseed.xf2.org",
|
519
560
|
],
|
520
|
-
:
|
521
|
-
:
|
522
|
-
:
|
523
|
-
:
|
561
|
+
genesis_hash: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
562
|
+
proof_of_work_limit: 0x1d00ffff,
|
563
|
+
alert_pubkeys: ["04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"],
|
564
|
+
known_nodes: [
|
524
565
|
'relay.eligius.st',
|
525
566
|
'mining.bitcoin.cz',
|
526
567
|
'blockchain.info',
|
527
568
|
'blockexplorer.com',
|
528
569
|
],
|
529
|
-
:
|
570
|
+
checkpoints: {
|
530
571
|
11111 => "0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d",
|
531
572
|
33333 => "000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6",
|
532
573
|
74000 => "0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20",
|
@@ -541,125 +582,81 @@ module Bitcoin
|
|
541
582
|
300000 => "000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254",
|
542
583
|
305000 => "0000000000000000142bb90561e1a907d500bf534a6727a63a92af5b6abc6160",
|
543
584
|
}
|
544
|
-
}
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
:
|
549
|
-
:
|
550
|
-
:
|
551
|
-
:
|
552
|
-
:
|
553
|
-
:
|
554
|
-
:
|
555
|
-
:
|
556
|
-
:
|
557
|
-
:
|
558
|
-
:
|
559
|
-
:
|
560
|
-
:
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
:
|
565
|
-
:
|
566
|
-
:
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
:
|
574
|
-
:
|
575
|
-
|
576
|
-
|
577
|
-
:privkey_version => "ef",
|
578
|
-
:default_port => 18333,
|
579
|
-
:max_money => 21_000_000 * COIN,
|
580
|
-
:dns_seeds => [ ],
|
581
|
-
:genesis_hash => "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008",
|
582
|
-
:proof_of_work_limit => 0x1d07fff8,
|
583
|
-
:alert_pubkeys => ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
|
584
|
-
:known_nodes => [],
|
585
|
-
:checkpoints => {},
|
586
|
-
:coinbase_maturity => 100,
|
587
|
-
:retarget_interval => 2016,
|
588
|
-
:retarget_time => 1209600, # 2 weeks
|
589
|
-
:target_spacing => 600, # block interval
|
590
|
-
:max_money => 21_000_000 * COIN,
|
591
|
-
:min_tx_fee => 10_000,
|
592
|
-
:min_relay_tx_fee => 10_000,
|
593
|
-
:free_tx_bytes => 1_000,
|
594
|
-
:dust => CENT,
|
595
|
-
:per_dust_fee => false,
|
596
|
-
},
|
597
|
-
|
598
|
-
:testnet3 => {
|
599
|
-
:project => :bitcoin,
|
600
|
-
:magic_head => "\x0b\x11\x09\x07",
|
601
|
-
:address_version => "6f",
|
602
|
-
:p2sh_version => "c4",
|
603
|
-
:privkey_version => "ef",
|
604
|
-
:default_port => 18333,
|
605
|
-
:protocol_version => 70001,
|
606
|
-
:coinbase_maturity => 100,
|
607
|
-
:retarget_interval => 2016,
|
608
|
-
:retarget_time => 1209600, # 2 weeks
|
609
|
-
:target_spacing => 600, # block interval
|
610
|
-
:max_money => 21_000_000 * COIN,
|
611
|
-
:min_tx_fee => 10_000,
|
612
|
-
:no_difficulty => true, # no good. add right testnet3 difficulty calculation instead
|
613
|
-
:min_relay_tx_fee => 10_000,
|
614
|
-
:free_tx_bytes => 1_000,
|
615
|
-
:dust => CENT,
|
616
|
-
:per_dust_fee => false,
|
617
|
-
:dns_seeds => [
|
585
|
+
}
|
586
|
+
}
|
587
|
+
|
588
|
+
NETWORKS[:testnet] = NETWORKS[:bitcoin].merge({
|
589
|
+
magic_head: "\xFA\xBF\xB5\xDA",
|
590
|
+
address_version: "6f",
|
591
|
+
p2sh_version: "c4",
|
592
|
+
privkey_version: "ef",
|
593
|
+
extended_privkey_version: "04358394",
|
594
|
+
extended_pubkey_version: "043587cf",
|
595
|
+
default_port: 18333,
|
596
|
+
dns_seeds: [ ],
|
597
|
+
genesis_hash: "00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008",
|
598
|
+
proof_of_work_limit: 0x1d07fff8,
|
599
|
+
alert_pubkeys: ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
|
600
|
+
known_nodes: [],
|
601
|
+
checkpoints: {},
|
602
|
+
})
|
603
|
+
|
604
|
+
NETWORKS[:regtest] = NETWORKS[:testnet].merge({
|
605
|
+
default_port: 18444,
|
606
|
+
genesis_hash: "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
|
607
|
+
proof_of_work_limit: (1 << 255) - 1,
|
608
|
+
})
|
609
|
+
|
610
|
+
NETWORKS[:testnet3] = NETWORKS[:testnet].merge({
|
611
|
+
magic_head: "\x0B\x11\x09\x07",
|
612
|
+
no_difficulty: true, # no good. add right testnet3 difficulty calculation instead
|
613
|
+
genesis_hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943",
|
614
|
+
proof_of_work_limit: 0x1d00ffff,
|
615
|
+
dns_seeds: [
|
616
|
+
"testnet-seed.alexykot.me",
|
617
|
+
"testnet-seed.bitcoin.schildbach.de",
|
618
618
|
"testnet-seed.bitcoin.petertodd.org",
|
619
619
|
"testnet-seed.bluematt.me",
|
620
620
|
],
|
621
|
-
:
|
622
|
-
:proof_of_work_limit => 0x1d00ffff,
|
623
|
-
:alert_pubkeys => ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
|
624
|
-
:known_nodes => [],
|
625
|
-
:checkpoints => {
|
621
|
+
checkpoints: {
|
626
622
|
# 542 contains invalid transaction
|
627
623
|
542 => "0000000083c1f82cf72c6724f7a317325806384b06408bce7a4327f418dfd5ad",
|
628
624
|
71018 => "000000000010dd93dc55541116b2744eb8f4c3b706df6e8512d231a03fb9e435",
|
629
625
|
200000 => "0000000000287bffd321963ef05feab753ebe274e1d78b2fd4e2bfe9ad3aa6f2",
|
630
626
|
250000 => "0000000005910c146e4e8d71e8aa6617393738a9794b43cf113076dbaf08460b",
|
631
627
|
}
|
632
|
-
}
|
633
|
-
|
634
|
-
|
635
|
-
:
|
636
|
-
:
|
637
|
-
:
|
638
|
-
:
|
639
|
-
:
|
640
|
-
:
|
641
|
-
:
|
642
|
-
:
|
643
|
-
:
|
644
|
-
:
|
645
|
-
:
|
646
|
-
:
|
647
|
-
:
|
648
|
-
:
|
649
|
-
:
|
650
|
-
:
|
651
|
-
:
|
628
|
+
})
|
629
|
+
|
630
|
+
NETWORKS[:litecoin] = NETWORKS[:bitcoin].merge({
|
631
|
+
project: :litecoin,
|
632
|
+
magic_head: "\xfb\xc0\xb6\xdb",
|
633
|
+
address_version: "30",
|
634
|
+
p2sh_version: "05",
|
635
|
+
privkey_version: "b0",
|
636
|
+
extended_privkey_version: "019d9cfe",
|
637
|
+
extended_pubkey_version: "019da462",
|
638
|
+
default_port: 9333,
|
639
|
+
protocol_version: 70002,
|
640
|
+
max_money: 84_000_000 * COIN,
|
641
|
+
min_tx_fee: 100_000, # 0.001 LTC
|
642
|
+
min_relay_tx_fee: 100_000, # 0.001 LTC
|
643
|
+
free_tx_bytes: 5_000,
|
644
|
+
dust: CENT / 10,
|
645
|
+
per_dust_fee: true,
|
646
|
+
reward_halving: 840_000,
|
647
|
+
retarget_time: 302400, # 3.5 days
|
648
|
+
dns_seeds: [
|
652
649
|
"dnsseed.litecointools.com",
|
653
650
|
"dnsseed.litecoinpool.org",
|
654
651
|
"dnsseed.ltc.xurious.com",
|
655
652
|
"dnsseed.koin-project.com",
|
656
653
|
"dnsseed.weminemnc.com",
|
657
654
|
],
|
658
|
-
:
|
659
|
-
:
|
660
|
-
:
|
661
|
-
:
|
662
|
-
:
|
655
|
+
genesis_hash: "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2",
|
656
|
+
proof_of_work_limit: 0x1e0fffff,
|
657
|
+
alert_pubkeys: ["040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9"],
|
658
|
+
known_nodes: [],
|
659
|
+
checkpoints: {
|
663
660
|
1 => "80ca095ed10b02e53d769eb6eaf92cd04e9e0759e5be4a8477b42911ba49c78f",
|
664
661
|
2 => "13957807cdd1d02f993909fa59510e318763f99a506c4c426e3b254af09f40d7",
|
665
662
|
1500 => "841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967",
|
@@ -677,113 +674,170 @@ module Bitcoin
|
|
677
674
|
409004 => "487518d663d9f1fa08611d9395ad74d982b667fbdc0e77e9cf39b4f1355908a3",
|
678
675
|
456000 => "bf34f71cc6366cd487930d06be22f897e34ca6a40501ac7d401be32456372004",
|
679
676
|
541794 => "1cbccbe6920e7c258bbce1f26211084efb19764aa3224bec3f4320d77d6a2fd2",
|
680
|
-
}
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
:
|
686
|
-
:
|
687
|
-
:
|
688
|
-
:
|
689
|
-
:
|
690
|
-
:
|
691
|
-
:
|
692
|
-
:
|
693
|
-
:dust => CENT / 10,
|
694
|
-
:per_dust_fee => true,
|
695
|
-
:free_tx_bytes => 5_000,
|
696
|
-
:coinbase_maturity => 100,
|
697
|
-
:retarget_interval => 2016,
|
698
|
-
:retarget_time => 302400, # 3.5 days
|
699
|
-
:max_money => 84_000_000 * COIN,
|
700
|
-
:dns_seeds => [
|
677
|
+
},
|
678
|
+
auxpow_chain_id: 1,
|
679
|
+
})
|
680
|
+
|
681
|
+
NETWORKS[:litecoin_testnet] = NETWORKS[:litecoin].merge({
|
682
|
+
magic_head: "\xfc\xc1\xb7\xdc",
|
683
|
+
address_version: "6f",
|
684
|
+
p2sh_version: "c4",
|
685
|
+
privkey_version: "ef",
|
686
|
+
extended_privkey_version: "0436ef7d",
|
687
|
+
extended_pubkey_version: "0436f6e1",
|
688
|
+
default_port: 19333,
|
689
|
+
dns_seeds: [
|
701
690
|
"testnet-seed.litecointools.com",
|
702
691
|
"testnet-seed.ltc.xurious.com",
|
703
692
|
"testnet-seed.weminemnc.com",
|
704
693
|
],
|
705
|
-
:
|
706
|
-
:
|
707
|
-
:
|
708
|
-
:
|
709
|
-
:checkpoints => {
|
694
|
+
genesis_hash: "f5ae71e26c74beacc88382716aced69cddf3dffff24f384e1808905e0188f68f",
|
695
|
+
alert_pubkeys: ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
|
696
|
+
known_nodes: [],
|
697
|
+
checkpoints: {
|
710
698
|
546 => "a0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602",
|
711
699
|
}
|
712
|
-
}
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
:
|
717
|
-
:
|
718
|
-
:
|
719
|
-
:
|
720
|
-
:
|
721
|
-
:
|
722
|
-
:
|
723
|
-
:
|
724
|
-
:
|
725
|
-
:
|
726
|
-
:
|
727
|
-
:
|
728
|
-
:
|
729
|
-
:
|
730
|
-
:
|
731
|
-
:
|
732
|
-
:
|
733
|
-
:
|
734
|
-
:
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
:
|
743
|
-
:
|
744
|
-
:
|
745
|
-
:
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
:
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
700
|
+
})
|
701
|
+
|
702
|
+
NETWORKS[:dogecoin] = NETWORKS[:litecoin].merge({
|
703
|
+
project: :dogecoin,
|
704
|
+
magic_head: "\xc0\xc0\xc0\xc0",
|
705
|
+
address_version: "1e",
|
706
|
+
p2sh_version: "16",
|
707
|
+
privkey_version: "9e",
|
708
|
+
extended_privkey_version: "02fac398",
|
709
|
+
extended_pubkey_version: "02facafd",
|
710
|
+
default_port: 22556,
|
711
|
+
protocol_version: 70003,
|
712
|
+
max_money: 100_000_000_000 * COIN,
|
713
|
+
min_tx_fee: COIN,
|
714
|
+
min_relay_tx_fee: COIN,
|
715
|
+
free_tx_bytes: 26_000,
|
716
|
+
dust: COIN,
|
717
|
+
per_dust_fee: true,
|
718
|
+
coinbase_maturity: 30,
|
719
|
+
coinbase_maturity_new: 240,
|
720
|
+
reward_base: 500_000 * COIN,
|
721
|
+
reward_halving: 100_000,
|
722
|
+
retarget_interval: 240,
|
723
|
+
retarget_time: 14400, # 4 hours
|
724
|
+
retarget_time_new: 60, # 1 minute
|
725
|
+
target_spacing: 60, # block interval
|
726
|
+
dns_seeds: [
|
727
|
+
"seed.dogechain.info",
|
728
|
+
"seed.dogecoin.com",
|
729
|
+
],
|
730
|
+
genesis_hash: "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691",
|
731
|
+
proof_of_work_limit: 0x1e0fffff,
|
732
|
+
alert_pubkeys: [],
|
733
|
+
known_nodes: [
|
734
|
+
"daemons.chain.so",
|
735
|
+
"bootstrap.chain.so",
|
736
|
+
],
|
737
|
+
checkpoints: {
|
738
|
+
0 => "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691",
|
739
|
+
42279 => "8444c3ef39a46222e87584ef956ad2c9ef401578bd8b51e8e4b9a86ec3134d3a",
|
740
|
+
42400 => "557bb7c17ed9e6d4a6f9361cfddf7c1fc0bdc394af7019167442b41f507252b4",
|
741
|
+
104679 => "35eb87ae90d44b98898fec8c39577b76cb1eb08e1261cfc10706c8ce9a1d01cf",
|
742
|
+
128370 => "3f9265c94cab7dc3bd6a2ad2fb26c8845cb41cff437e0a75ae006997b4974be6",
|
743
|
+
145000 => "cc47cae70d7c5c92828d3214a266331dde59087d4a39071fa76ddfff9b7bde72",
|
744
|
+
165393 => "7154efb4009e18c1c6a6a79fc6015f48502bcd0a1edd9c20e44cd7cbbe2eeef1",
|
745
|
+
186774 => "3c712c49b34a5f34d4b963750d6ba02b73e8a938d2ee415dcda141d89f5cb23a",
|
746
|
+
199992 => "3408ff829b7104eebaf61fd2ba2203ef2a43af38b95b353e992ef48f00ebb190",
|
747
|
+
225000 => "be148d9c5eab4a33392a6367198796784479720d06bfdd07bd547fe934eea15a",
|
748
|
+
250000 => "0e4bcfe8d970979f7e30e2809ab51908d435677998cf759169407824d4f36460",
|
749
|
+
270639 => "c587a36dd4f60725b9dd01d99694799bef111fc584d659f6756ab06d2a90d911",
|
750
|
+
299742 => "1cc89c0c8a58046bf0222fe131c099852bd9af25a80e07922918ef5fb39d6742",
|
751
|
+
323141 => "60c9f919f9b271add6ef5671e9538bad296d79f7fdc6487ba702bf2ba131d31d",
|
752
|
+
339202 => "8c29048df5ae9df38a67ea9470fdd404d281a3a5c6f33080cd5bf14aa496ab03"
|
753
|
+
},
|
754
|
+
auxpow_chain_id: 0x0062,
|
755
|
+
# Doge-specific hard-fork cutoffs
|
756
|
+
difficulty_change_block: 145000,
|
757
|
+
maturity_change_block: 145000,
|
758
|
+
auxpow_start_block: 371337
|
759
|
+
})
|
760
|
+
|
761
|
+
NETWORKS[:dogecoin_testnet] = NETWORKS[:dogecoin].merge({
|
762
|
+
project: :dogecoin,
|
763
|
+
magic_head: "\xfc\xc1\xb7\xdc",
|
764
|
+
address_version: "71",
|
765
|
+
p2sh_version: "c4",
|
766
|
+
privkey_version: "f1",
|
767
|
+
extended_privkey_version: "0432a243",
|
768
|
+
extended_pubkey_version: "0432a9a8",
|
769
|
+
default_port: 44556,
|
770
|
+
protocol_version: 70003,
|
771
|
+
min_tx_fee: COIN,
|
772
|
+
min_relay_tx_fee: COIN,
|
773
|
+
dust: COIN,
|
774
|
+
per_dust_fee: true,
|
775
|
+
free_tx_bytes: 26_000,
|
776
|
+
coinbase_maturity: 30,
|
777
|
+
coinbase_maturity_new: 240,
|
778
|
+
reward_base: 500_000 * COIN,
|
779
|
+
reward_halving: 100_000,
|
780
|
+
retarget_interval: 240,
|
781
|
+
retarget_time: 14400, # 4 hours
|
782
|
+
retarget_time_new: 60, # 1 minute
|
783
|
+
target_spacing: 60, # block interval
|
784
|
+
max_money: 100_000_000_000 * COIN,
|
785
|
+
dns_seeds: [
|
786
|
+
"testdoge-seed.lionservers.de",
|
787
|
+
],
|
788
|
+
genesis_hash: "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e",
|
789
|
+
proof_of_work_limit: 0x1e0fffff,
|
790
|
+
alert_pubkeys: [],
|
791
|
+
known_nodes: [
|
792
|
+
"localhost",
|
793
|
+
"testnets.chain.so",
|
794
|
+
],
|
795
|
+
checkpoints: {
|
796
|
+
546 => "ac537cfeda975e45040e9938d08e40a16e0fbd6388d02d9b4928b8ae0108c626",
|
797
|
+
},
|
798
|
+
auxpow_chain_id: 0x0062,
|
799
|
+
# Doge-specific hard-fork cutoffs
|
800
|
+
difficulty_change_block: 145000,
|
801
|
+
maturity_change_block: 145000,
|
802
|
+
reset_target_block: 157500,
|
803
|
+
auxpow_start_block: 158100
|
804
|
+
})
|
805
|
+
|
806
|
+
NETWORKS[:namecoin] = NETWORKS[:bitcoin].merge({
|
807
|
+
project: :namecoin,
|
808
|
+
magic_head: "\xF9\xBE\xB4\xFE",
|
809
|
+
address_version: "34",
|
810
|
+
default_port: 8334,
|
811
|
+
protocol_version: 35000,
|
812
|
+
min_tx_fee: 50_000,
|
813
|
+
per_dust_fee: true,
|
814
|
+
dns_seeds: [],
|
815
|
+
genesis_hash: "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770",
|
816
|
+
known_nodes: [
|
817
|
+
"bitcoin.tunl.in",
|
818
|
+
"webbtc.com",
|
819
|
+
"178.32.31.41",
|
820
|
+
"78.47.86.43",
|
821
|
+
"69.164.206.88",
|
822
|
+
],
|
823
|
+
checkpoints: {
|
758
824
|
0 => "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770",
|
759
825
|
19200 => "d8a7c3e01e1e95bcee015e6fcc7583a2ca60b79e5a3aa0a171eddd344ada903d",
|
760
826
|
24000 => "425ab0983cf04f43f346a4ca53049d0dc2db952c0a68eb0b55c3bb64108d5371",
|
761
827
|
97778 => "7553b1e43da01cfcda4335de1caf623e941d43894bd81c2af27b6582f9d83c6f",
|
762
828
|
165000 => "823d7a54ebab04d14c4ba3508f6b5f25977406f4d389539eac0174d52c6b4b62",
|
763
|
-
}
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
:
|
769
|
-
:
|
770
|
-
:
|
771
|
-
:
|
772
|
-
:
|
773
|
-
:min_relay_tx_fee => 10_000,
|
774
|
-
:free_tx_bytes => 1_000,
|
775
|
-
:dust => CENT,
|
776
|
-
:per_dust_fee => true,
|
777
|
-
:max_money => 21_000_000 * COIN,
|
778
|
-
:dns_seeds => [],
|
779
|
-
:genesis_hash => "00000001f8ab0d14bceaeb50d163b0bef15aecf62b87bd5f5c864d37f201db97",
|
780
|
-
:proof_of_work_limit => 0x1d00ffff,
|
781
|
-
:known_nodes => ["178.32.31.41"],
|
782
|
-
:checkpoints => {
|
829
|
+
},
|
830
|
+
auxpow_chain_id: 1
|
831
|
+
})
|
832
|
+
|
833
|
+
NETWORKS[:namecoin_testnet] = NETWORKS[:namecoin].merge({
|
834
|
+
magic_head: "\xFA\xBF\xB5\xFE",
|
835
|
+
default_port: 18334,
|
836
|
+
genesis_hash: "00000001f8ab0d14bceaeb50d163b0bef15aecf62b87bd5f5c864d37f201db97",
|
837
|
+
known_nodes: ["178.32.31.41"],
|
838
|
+
checkpoints: {
|
783
839
|
0 => "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770",
|
784
|
-
|
785
840
|
}
|
786
|
-
}
|
787
|
-
}
|
841
|
+
})
|
788
842
|
|
789
843
|
end
|