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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.travis.yml +2 -7
  4. data/COPYING +1 -1
  5. data/Gemfile +2 -6
  6. data/Gemfile.lock +34 -0
  7. data/README.rdoc +16 -68
  8. data/Rakefile +3 -6
  9. data/bin/bitcoin_shell +0 -1
  10. data/{concept-examples/blockchain-pow.rb → examples/concept-blockchain-pow.rb} +0 -0
  11. data/lib/bitcoin.rb +350 -296
  12. data/lib/bitcoin/builder.rb +3 -1
  13. data/lib/bitcoin/connection.rb +2 -1
  14. data/lib/bitcoin/contracthash.rb +76 -0
  15. data/lib/bitcoin/dogecoin.rb +97 -0
  16. data/lib/bitcoin/ffi/bitcoinconsensus.rb +74 -0
  17. data/lib/bitcoin/ffi/openssl.rb +98 -2
  18. data/lib/bitcoin/ffi/secp256k1.rb +144 -0
  19. data/lib/bitcoin/key.rb +12 -2
  20. data/lib/bitcoin/logger.rb +3 -12
  21. data/lib/bitcoin/protocol/block.rb +3 -9
  22. data/lib/bitcoin/protocol/parser.rb +6 -2
  23. data/lib/bitcoin/protocol/tx.rb +44 -13
  24. data/lib/bitcoin/protocol/txin.rb +4 -2
  25. data/lib/bitcoin/protocol/txout.rb +2 -2
  26. data/lib/bitcoin/script.rb +212 -37
  27. data/lib/bitcoin/trezor/mnemonic.rb +130 -0
  28. data/lib/bitcoin/version.rb +1 -1
  29. data/spec/bitcoin/bitcoin_spec.rb +32 -3
  30. data/spec/bitcoin/builder_spec.rb +18 -0
  31. data/spec/bitcoin/contracthash_spec.rb +45 -0
  32. data/spec/bitcoin/dogecoin_spec.rb +176 -0
  33. data/spec/bitcoin/ffi_openssl.rb +45 -0
  34. data/spec/bitcoin/fixtures/156e6e1b84c5c3bd3a0927b25e4119fadce6e6d5186f363317511d1d680fae9a.json +24 -0
  35. data/spec/bitcoin/fixtures/8d0b238a06b5a70be75d543902d02d7a514d68d3252a949a513865ac3538874c.json +24 -0
  36. data/spec/bitcoin/fixtures/coinbase-toshi.json +33 -0
  37. data/spec/bitcoin/fixtures/coinbase.json +24 -0
  38. data/spec/bitcoin/fixtures/dogecoin-block-60323982f9c5ff1b5a954eac9dc1269352835f47c2c5222691d80f0d50dcf053.bin +0 -0
  39. data/spec/bitcoin/fixtures/rawtx-01-toshi.json +46 -0
  40. data/spec/bitcoin/fixtures/rawtx-02-toshi.json +46 -0
  41. data/spec/bitcoin/fixtures/rawtx-03-toshi.json +73 -0
  42. data/spec/bitcoin/fixtures/rawtx-testnet-04fdc38d6722ab4b12d79113fc4b2896bdcc5169710690ee4e78541b98e467b4.bin +0 -0
  43. data/spec/bitcoin/fixtures/rawtx-testnet-0b294c7d11dd21bcccb8393e6744fed7d4d1981a08c00e3e88838cc421f33c9f.bin +0 -0
  44. data/spec/bitcoin/fixtures/rawtx-testnet-3bc52ac063291ad92d95ddda5fd776a342083b95607ad32ed8bc6f8f7d30449e.bin +0 -0
  45. data/spec/bitcoin/fixtures/rawtx-testnet-6f0bbdd4e71a8af4305018d738184df32dbb6f27284fdebd5b56d16947f7c181.bin +0 -0
  46. data/spec/bitcoin/fixtures/rawtx-testnet-a7c9b06e275e8674cc19a5f7d3e557c72c6d93576e635b33212dbe08ab7cdb60.bin +0 -0
  47. data/spec/bitcoin/fixtures/rawtx-testnet-f80acbd2f594d04ddb0e1cacba662132104909157dff526935a3c88abe9201a5.bin +0 -0
  48. data/spec/bitcoin/protocol/block_spec.rb +0 -22
  49. data/spec/bitcoin/protocol/tx_spec.rb +145 -2
  50. data/spec/bitcoin/script/script_spec.rb +282 -0
  51. data/spec/bitcoin/secp256k1_spec.rb +48 -0
  52. data/spec/bitcoin/spec_helper.rb +0 -51
  53. data/spec/bitcoin/trezor/mnemonic_spec.rb +161 -0
  54. metadata +48 -98
  55. data/bin/bitcoin_dns_seed +0 -130
  56. data/bin/bitcoin_gui +0 -80
  57. data/bin/bitcoin_node +0 -153
  58. data/bin/bitcoin_node_cli +0 -81
  59. data/bin/bitcoin_wallet +0 -402
  60. data/doc/CONFIG.rdoc +0 -66
  61. data/doc/EXAMPLES.rdoc +0 -13
  62. data/doc/NAMECOIN.rdoc +0 -34
  63. data/doc/NODE.rdoc +0 -225
  64. data/doc/STORAGE.rdoc +0 -33
  65. data/doc/WALLET.rdoc +0 -102
  66. data/examples/balance.rb +0 -66
  67. data/examples/forwarder.rb +0 -73
  68. data/examples/index_nhash.rb +0 -24
  69. data/examples/reindex_p2sh_addrs.rb +0 -44
  70. data/examples/relay_tx.rb +0 -22
  71. data/examples/verify_tx.rb +0 -57
  72. data/lib/bitcoin/config.rb +0 -58
  73. data/lib/bitcoin/gui/addr_view.rb +0 -44
  74. data/lib/bitcoin/gui/bitcoin-ruby.png +0 -0
  75. data/lib/bitcoin/gui/bitcoin-ruby.svg +0 -80
  76. data/lib/bitcoin/gui/conn_view.rb +0 -38
  77. data/lib/bitcoin/gui/connection.rb +0 -70
  78. data/lib/bitcoin/gui/em_gtk.rb +0 -30
  79. data/lib/bitcoin/gui/gui.builder +0 -1643
  80. data/lib/bitcoin/gui/gui.rb +0 -292
  81. data/lib/bitcoin/gui/helpers.rb +0 -115
  82. data/lib/bitcoin/gui/tree_view.rb +0 -84
  83. data/lib/bitcoin/gui/tx_view.rb +0 -69
  84. data/lib/bitcoin/namecoin.rb +0 -280
  85. data/lib/bitcoin/network/command_client.rb +0 -104
  86. data/lib/bitcoin/network/command_handler.rb +0 -570
  87. data/lib/bitcoin/network/connection_handler.rb +0 -387
  88. data/lib/bitcoin/network/node.rb +0 -565
  89. data/lib/bitcoin/storage/dummy/dummy_store.rb +0 -179
  90. data/lib/bitcoin/storage/models.rb +0 -171
  91. data/lib/bitcoin/storage/sequel/migrations.rb +0 -99
  92. data/lib/bitcoin/storage/sequel/migrations/001_base_schema.rb +0 -52
  93. data/lib/bitcoin/storage/sequel/migrations/002_tx.rb +0 -45
  94. data/lib/bitcoin/storage/sequel/migrations/003_change_txin_script_sig_to_blob.rb +0 -18
  95. data/lib/bitcoin/storage/sequel/migrations/004_change_txin_prev_out_to_blob.rb +0 -18
  96. data/lib/bitcoin/storage/sequel/migrations/005_change_tx_hash_to_bytea.rb +0 -14
  97. data/lib/bitcoin/storage/sequel/migrations/006_add_tx_nhash.rb +0 -31
  98. data/lib/bitcoin/storage/sequel/migrations/007_add_prev_out_index_index.rb +0 -16
  99. data/lib/bitcoin/storage/sequel/migrations/008_add_txin_p2sh_type.rb +0 -31
  100. data/lib/bitcoin/storage/sequel/migrations/009_add_addrs_type.rb +0 -56
  101. data/lib/bitcoin/storage/sequel/sequel_store.rb +0 -551
  102. data/lib/bitcoin/storage/storage.rb +0 -517
  103. data/lib/bitcoin/storage/utxo/migrations/001_base_schema.rb +0 -52
  104. data/lib/bitcoin/storage/utxo/migrations/002_utxo.rb +0 -18
  105. data/lib/bitcoin/storage/utxo/migrations/003_update_indices.rb +0 -14
  106. data/lib/bitcoin/storage/utxo/migrations/004_add_addrs_type.rb +0 -14
  107. data/lib/bitcoin/storage/utxo/utxo_store.rb +0 -374
  108. data/lib/bitcoin/validation.rb +0 -400
  109. data/lib/bitcoin/wallet/coinselector.rb +0 -33
  110. data/lib/bitcoin/wallet/keygenerator.rb +0 -77
  111. data/lib/bitcoin/wallet/keystore.rb +0 -207
  112. data/lib/bitcoin/wallet/txdp.rb +0 -118
  113. data/lib/bitcoin/wallet/wallet.rb +0 -281
  114. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.bin +0 -0
  115. data/spec/bitcoin/fixtures/freicoin-block-000000005d231b285e63af83edae2d8f5e50e70d396468643092b9239fd3be3c.json +0 -43
  116. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.bin +0 -0
  117. data/spec/bitcoin/fixtures/freicoin-genesis-block-000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c.json +0 -67
  118. data/spec/bitcoin/namecoin_spec.rb +0 -182
  119. data/spec/bitcoin/node/command_api_spec.rb +0 -663
  120. data/spec/bitcoin/storage/models_spec.rb +0 -104
  121. data/spec/bitcoin/storage/reorg_spec.rb +0 -236
  122. data/spec/bitcoin/storage/storage_spec.rb +0 -387
  123. data/spec/bitcoin/storage/validation_spec.rb +0 -300
  124. data/spec/bitcoin/wallet/coinselector_spec.rb +0 -38
  125. data/spec/bitcoin/wallet/keygenerator_spec.rb +0 -69
  126. data/spec/bitcoin/wallet/keystore_spec.rb +0 -190
  127. data/spec/bitcoin/wallet/txdp_spec.rb +0 -76
  128. data/spec/bitcoin/wallet/wallet_spec.rb +0 -238
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e801e5256acce9c4fc02ef046d2388365111fd23
4
- data.tar.gz: 81781d99c978635c078d7aae95a2e29c892f6e52
3
+ metadata.gz: a8a85933bb6f2c36c0262cbfc0b254bfb5449e9d
4
+ data.tar.gz: a61c9750f801b78ccb01350d2f777560f73bdb9b
5
5
  SHA512:
6
- metadata.gz: 84a5f6f668b5fb3590ab5e3d9bc58255f06fbcc2adad65e8fe3943253630e12510a348257ce7181e382411ab2ae68171f5d9787fa5780e7a5c9f410910f568f0
7
- data.tar.gz: d07c7abc49e3f1eb0caf2244808be898855a82001504f1747c7c1328e960a2dccad6c0291740a02320bd59e84ba02adbc79af67656e0ceb6aee7b506edbf7313
6
+ metadata.gz: 7cb472579d3e819c18025e3fef9b2db6c36e3bdab701b6984482920ada6d07b736af0170512fc7598fd904d8c9104c311c64fa3f3bb87d77acc9310db49e1e71
7
+ data.tar.gz: 1d0f4d2c551a89433620e87ec391be57edbca0af200df5e9df6b80ab6cd73b8092f36b4030caa3b12671f920a03b2f7dad5189c473e594427f09520641f0db01
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
4
3
  pkg/*
5
4
  *.swp
6
5
  .rvmrc
@@ -1,10 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.0.0
5
- - 2.1.0
6
- before_script:
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) 2014 Julian Langschaedel <meta.rb@gmail.com>
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
@@ -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
@@ -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 (almost?) all protocol messages
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::Wallet is a draft implementation of a simple wallet
17
- * Bitcoin::Namecoin implements all the namecoin-specific differences (see NAMECOIN)
18
- * Bitcoin::Litecoin implements all the litecoin-sepcific differences
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 RDoc
182
+ Documentation is generated using yardoc:
230
183
 
231
- rake rdoc
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/wallet/*_spec.rb'] +
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 'http://github.com/mhanne/bitcoin-ruby/tree/master/%s' -o rdoc -m README.rdoc examples/ doc/ lib/ README.rdoc COPYING")
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'
@@ -4,7 +4,6 @@ require 'bitcoin'
4
4
 
5
5
  include Bitcoin
6
6
  include Bitcoin::Util
7
- include Bitcoin::Storage
8
7
 
9
8
  Bitcoin.network = ARGV.shift || :bitcoin
10
9
 
@@ -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 :Namecoin, 'bitcoin/namecoin'
20
+ autoload :Dogecoin, 'bitcoin/dogecoin'
24
21
  autoload :Litecoin, 'bitcoin/litecoin'
25
22
 
26
- module Network
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 Gui
43
- autoload :Gui, 'bitcoin/gui/gui'
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
- Bitcoin.checksum( hex[0...42] ) == hex[-8..-1]
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
- bytes = Array.new(size=((bits >> 24) & 255), 0)
175
- bytes[0] = (bits >> 16) & 255 if size >= 1
176
- bytes[1] = (bits >> 8) & 255 if size >= 2
177
- bytes[2] = (bits ) & 255 if size >= 3
178
- bytes.pack("C*").unpack("H*")[0].rjust(64, '0')
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.unpack("H*")[0]
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 = Bitcoin.bitcoin_mrkl( a, b || a )
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.map do |hash|
270
+ branch.each do |hash|
283
271
  a, b = *( idx & 1 == 0 ? [target, hash] : [hash, target] )
284
- idx >>= 1; target = Bitcoin.bitcoin_mrkl( a, b )
285
- end.last
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
- key.dsa_verify_asn1(hash, signature)
296
- rescue OpenSSL::PKey::ECError, OpenSSL::PKey::EC::Point::Error
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
- Bitcoin::OpenSSL_EC.regenerate_key(private_key)[1]
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 = Bitcoin::OpenSSL_EC.sign_compact(hash, private_key_hex, public_key_hex)
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
- raise "invalid address" unless valid_address?(address)
328
- raise "malformed base64 encoding" unless signature
329
- raise "malformed signature" unless signature.bytesize == 65
330
- pubkey = Bitcoin::OpenSSL_EC.recover_compact(hash, signature)
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 = Bitcoin.decode_compact_bits(target_nbits).to_i(16)
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 = Bitcoin.decode_compact_bits(target_nbits).to_i(16)
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) / Bitcoin::COIN # satoshis to btc
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 = 5000000000, 210000
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
- 5000000000 / (2 ** (block_height / 210000.0).floor)
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
- def hth; unpack("H*")[0]; end
398
- def reverse_hth; reverse.hth; end
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
- Bitcoin::Namecoin.load if namecoin?
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, :freicoin].each do |n|
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
- :bitcoin => {
497
- :project => :bitcoin,
498
- :magic_head => "\xF9\xBE\xB4\xD9",
499
- :address_version => "00",
500
- :p2sh_version => "05",
501
- :privkey_version => "80",
502
- :default_port => 8333,
503
- :protocol_version => 70001,
504
- :coinbase_maturity => 100,
505
- :retarget_interval => 2016,
506
- :retarget_time => 1209600, # 2 weeks
507
- :target_spacing => 600, # block interval
508
- :max_money => 21_000_000 * COIN,
509
- :min_tx_fee => 10_000,
510
- :min_relay_tx_fee => 10_000,
511
- :free_tx_bytes => 1_000,
512
- :dust => CENT,
513
- :per_dust_fee => false,
514
- :dns_seeds => [
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
- :genesis_hash => "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
521
- :proof_of_work_limit => 0x1d00ffff,
522
- :alert_pubkeys => ["04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"],
523
- :known_nodes => [
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
- :checkpoints => {
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
- :regtest => {
547
- :project => :bitcoin,
548
- :magic_head => "\xFA\xBF\xB5\xDA",
549
- :address_version => "6f",
550
- :p2sh_version => "c4",
551
- :privkey_version => "ef",
552
- :default_port => 18444,
553
- :max_money => 21_000_000 * COIN,
554
- :dns_seeds => [ ],
555
- :genesis_hash => "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
556
- :proof_of_work_limit => (1<<255) - 1,
557
- :alert_pubkeys => ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
558
- :known_nodes => [],
559
- :checkpoints => {},
560
- :coinbase_maturity => 100,
561
- :retarget_interval => 2016,
562
- :retarget_time => 1209600, # 2 weeks
563
- :target_spacing => 600, # block interval
564
- :max_money => 21_000_000 * COIN,
565
- :min_tx_fee => 10_000,
566
- :min_relay_tx_fee => 10_000,
567
- :free_tx_bytes => 1_000,
568
- :dust => CENT,
569
- :per_dust_fee => false,
570
- },
571
-
572
- :testnet => {
573
- :project => :bitcoin,
574
- :magic_head => "\xFA\xBF\xB5\xDA",
575
- :address_version => "6f",
576
- :p2sh_version => "c4",
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
- :genesis_hash => "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943",
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
- :litecoin => {
635
- :project => :litecoin,
636
- :magic_head => "\xfb\xc0\xb6\xdb",
637
- :address_version => "30",
638
- :p2sh_version => "05",
639
- :privkey_version => "b0",
640
- :default_port => 9333,
641
- :protocol_version => 70002,
642
- :max_money => 84_000_000 * COIN,
643
- :min_tx_fee => 100_000, # 0.001 LTC
644
- :min_relay_tx_fee => 100_000, # 0.001 LTC
645
- :free_tx_bytes => 5_000,
646
- :dust => CENT / 10,
647
- :per_dust_fee => true,
648
- :coinbase_maturity => 100,
649
- :retarget_interval => 2016,
650
- :retarget_time => 302400, # 3.5 days
651
- :dns_seeds => [
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
- :genesis_hash => "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2",
659
- :proof_of_work_limit => 0,
660
- :alert_pubkeys => ["040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9"],
661
- :known_nodes => [],
662
- :checkpoints => {
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
- :litecoin_testnet => {
684
- :project => :litecoin,
685
- :magic_head => "\xfc\xc1\xb7\xdc",
686
- :address_version => "6f",
687
- :p2sh_version => "c4",
688
- :privkey_version => "ef",
689
- :default_port => 19333,
690
- :protocol_version => 70002,
691
- :min_tx_fee => 100_000, # 0.001 LTC
692
- :min_relay_tx_fee => 100_000, # 0.001 LTC
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
- :genesis_hash => "f5ae71e26c74beacc88382716aced69cddf3dffff24f384e1808905e0188f68f",
706
- :proof_of_work_limit => 0,
707
- :alert_pubkeys => ["04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"],
708
- :known_nodes => [],
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
- :freicoin => {
716
- :project => :freicoin,
717
- :magic_head => "\x2c\xfe\x7e\x6d",
718
- :address_version => "00",
719
- :p2sh_version => "05",
720
- :privkey_version => "80",
721
- :default_port => 8639,
722
- :protocol_version => 60002,
723
- :max_money => 21_000_000 * COIN,
724
- :min_tx_fee => 50_000,
725
- :min_relay_tx_fee => 10_000,
726
- :free_tx_bytes => 1_000,
727
- :dust => CENT,
728
- :per_dust_fee => false,
729
- :dns_seeds => [ "seed.freico.in", "fledge.freico.in" ],
730
- :genesis_hash => "000000005b1e3d23ecfd2dd4a6e1a35238aa0392c0a8528c40df52376d7efe2c",
731
- :proof_of_work_limit => 0,
732
- :alert_pubkeys => [],
733
- :known_nodes => [],
734
- :checkpoints => {
735
- 10080 => "00000000003ff9c4b806639ec4376cc9acafcdded0e18e9dbcc2fc42e8e72331",
736
- 15779 => "000000000003eb31742b35f5efd8ffb5cdd19dcd8e82cdaad90e592c450363b6",
737
- }
738
- },
739
-
740
- :namecoin => {
741
- :project => :namecoin,
742
- :magic_head => "\xF9\xBE\xB4\xFE",
743
- :address_version => "34",
744
- :default_port => 8334,
745
- :protocol_version => 35000,
746
- :max_money => 21_000_000 * COIN,
747
- :min_tx_fee => 50_000,
748
- :min_relay_tx_fee => 10_000,
749
- :free_tx_bytes => 1_000,
750
- :dust => CENT,
751
- :per_dust_fee => true,
752
- :dns_seeds => [],
753
- :genesis_hash => "000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770",
754
- :proof_of_work_limit => 0x1d00ffff,
755
- :known_nodes => ["bitcoin.tunl.in", "webbtc.com", "178.32.31.41",
756
- "78.47.86.43", "69.164.206.88", ""],
757
- :checkpoints => {
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
- :namecoin_testnet => {
767
- :project => :namecoin,
768
- :magic_head => "\xFA\xBF\xB5\xFE",
769
- :address_version => "34",
770
- :default_port => 18334,
771
- :protocol_version => 35000,
772
- :min_tx_fee => 50_000,
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