bitcoinrb 1.12.0 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/bitcoinrb.gemspec +1 -6
  4. data/lib/bitcoin/bip324/fs_chacha20.rb +3 -5
  5. data/lib/bitcoin/bip324/fs_chacha_poly1305.rb +19 -17
  6. data/lib/bitcoin/bip324.rb +1 -1
  7. data/lib/bitcoin/descriptor/expression.rb +2 -2
  8. data/lib/bitcoin/descriptor/sp.rb +219 -0
  9. data/lib/bitcoin/descriptor.rb +20 -0
  10. data/lib/bitcoin/ext_key.rb +3 -3
  11. data/lib/bitcoin/message/ping.rb +4 -2
  12. data/lib/bitcoin/message/version.rb +1 -1
  13. data/lib/bitcoin/message_sign.rb +98 -38
  14. data/lib/bitcoin/rpc.rb +0 -2
  15. data/lib/bitcoin/silent_payment/output.rb +46 -0
  16. data/lib/bitcoin/silent_payment.rb +113 -12
  17. data/lib/bitcoin/util.rb +2 -2
  18. data/lib/bitcoin/version.rb +1 -1
  19. data/lib/bitcoin.rb +0 -6
  20. metadata +18 -108
  21. data/exe/bitcoinrb-cli +0 -5
  22. data/exe/bitcoinrbd +0 -46
  23. data/lib/bitcoin/network/connection.rb +0 -73
  24. data/lib/bitcoin/network/message_handler.rb +0 -243
  25. data/lib/bitcoin/network/peer.rb +0 -228
  26. data/lib/bitcoin/network/peer_discovery.rb +0 -42
  27. data/lib/bitcoin/network/pool.rb +0 -135
  28. data/lib/bitcoin/network.rb +0 -13
  29. data/lib/bitcoin/node/cli.rb +0 -122
  30. data/lib/bitcoin/node/configuration.rb +0 -40
  31. data/lib/bitcoin/node/spv.rb +0 -87
  32. data/lib/bitcoin/node.rb +0 -7
  33. data/lib/bitcoin/rpc/http_server.rb +0 -84
  34. data/lib/bitcoin/rpc/request_handler.rb +0 -150
  35. data/lib/bitcoin/store/chain_entry.rb +0 -68
  36. data/lib/bitcoin/store/db/level_db.rb +0 -98
  37. data/lib/bitcoin/store/db.rb +0 -9
  38. data/lib/bitcoin/store/spv_chain.rb +0 -101
  39. data/lib/bitcoin/store/utxo_db.rb +0 -226
  40. data/lib/bitcoin/store.rb +0 -12
@@ -0,0 +1,46 @@
1
+ module Bitcoin
2
+ module SilentPayment
3
+ # Represents a detected silent payment output.
4
+ class Output
5
+ # @return [Bitcoin::TxOut] The detected transaction output.
6
+ attr_reader :tx_out
7
+
8
+ # @return [String] The tweak value (t_k) used to derive the output key (32 bytes binary).
9
+ attr_reader :tweak
10
+
11
+ # @return [Integer, nil] The label used for this output, or nil if no label was used.
12
+ attr_reader :label
13
+
14
+ # @param [Bitcoin::TxOut] tx_out The detected transaction output.
15
+ # @param [String] tweak The tweak value (t_k) as 32 bytes binary.
16
+ # @param [Integer, nil] label The label integer, or nil if no label was used.
17
+ # @raise [ArgumentError] If any parameter has an invalid type.
18
+ def initialize(tx_out, tweak, label = nil)
19
+ raise ArgumentError, "tx_out must be a Bitcoin::TxOut." unless tx_out.is_a?(Bitcoin::TxOut)
20
+ raise ArgumentError, "tweak must be a 32-byte String." unless tweak.is_a?(String) && tweak.bytesize == 32
21
+ raise ArgumentError, "label must be an Integer or nil." unless label.nil? || label.is_a?(Integer)
22
+ @tx_out = tx_out
23
+ @tweak = tweak
24
+ @label = label
25
+ end
26
+
27
+ # Returns the x-only public key of the output.
28
+ # @return [String] The x-only public key as hex string.
29
+ def pubkey
30
+ tx_out.script_pubkey.witness_data[1].bth
31
+ end
32
+
33
+ # Returns the tweak as hex string.
34
+ # @return [String] The tweak value as hex string.
35
+ def tweak_hex
36
+ tweak.bth
37
+ end
38
+
39
+ # Returns whether this output was detected using a label.
40
+ # @return [Boolean]
41
+ def labeled?
42
+ !label.nil?
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,12 +1,22 @@
1
+ require 'set'
2
+
1
3
  module Bitcoin
4
+ # BIP-352 silent payment module.
5
+ # @see https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki
2
6
  module SilentPayment
7
+ autoload :Output, 'bitcoin/silent_payment/output'
3
8
 
4
-
5
- # Derive payment
6
- # @param [Array] prevouts An array of previous output script(Bitcoin::Script).
7
- # @param [Array] private_keys An array of private key corresponding to each public key in prevouts.
8
- # @param [Array] recipients
9
- # @return [Array]
9
+ # Maximum number of silent payment addresses that can share the same scan public key
10
+ # within a single transaction. This is the maximum number of P2TR outputs that can fit
11
+ # within a 100KB transaction under current standardness rules.
12
+ K_MAX = 2323
13
+
14
+ # Derive payment point.
15
+ #
16
+ # @param [Array<Bitcoin::Script>] prevouts An array of previous output script.
17
+ # @param [Array<Bitcoin::Key>] private_keys An array of Bitcoin::Key objects corresponding to each public key in prevouts.
18
+ # @param [Array<Bech32::SilentPaymentAddr>] recipients
19
+ # @return [Array<ECDSA::Point>] An array of derived points.
10
20
  # @raise [ArgumentError]
11
21
  def derive_payment_points(prevouts, private_keys, recipients)
12
22
  raise ArgumentError, "prevouts must be Array." unless prevouts.is_a? Array
@@ -14,19 +24,19 @@ module Bitcoin
14
24
  raise ArgumentError, "prevouts and private_keys must be the same length." unless prevouts.length == private_keys.length
15
25
  raise ArgumentError, "recipients must be Array." unless recipients.is_a? Array
16
26
 
17
- outpoint_l = inputs.map{|i|i.out_point.to_hex}.sort.first
18
-
19
27
  input_pub_keys = []
20
28
  field = ECDSA::PrimeField.new(Bitcoin::Secp256k1::GROUP.order)
21
29
  sum_priv_keys = 0
22
30
  prevouts.each_with_index do |prevout, index|
23
- k = Bitcoin::Key.new(priv_key: private_keys[index].to_s(16))
31
+ key = private_keys[index]
32
+ raise ArgumentError, "private_keys element must be Bitcoin::Key." unless key.is_a? Bitcoin::Key
33
+ priv_key_int = key.priv_key.to_i(16)
24
34
  public_key = extract_public_key(prevout, inputs[index])
25
35
  next if public_key.nil?
26
- private_key = if public_key.p2tr? && k.to_point.y.odd?
27
- field.mod(-private_keys[index])
36
+ private_key = if public_key.p2tr? && key.to_point.y.odd?
37
+ field.mod(-priv_key_int)
28
38
  else
29
- private_keys[index]
39
+ priv_key_int
30
40
  end
31
41
  input_pub_keys << public_key
32
42
  sum_priv_keys = field.mod(sum_priv_keys + private_key)
@@ -34,6 +44,8 @@ module Bitcoin
34
44
  agg_pubkey = (Bitcoin::Secp256k1::GROUP.generator.to_jacobian * sum_priv_keys).to_affine
35
45
  return [] if agg_pubkey.infinity?
36
46
 
47
+ outpoint_l = inputs.map{|i|i.out_point.to_hex}.sort.first
48
+
37
49
  input_hash = Bitcoin.tagged_hash("BIP0352/Inputs", outpoint_l.htb + agg_pubkey.to_hex.htb).bth
38
50
 
39
51
  destinations = {}
@@ -42,6 +54,12 @@ module Bitcoin
42
54
  destinations[sp_addr.scan_key] = [] unless destinations.has_key?(sp_addr.scan_key)
43
55
  destinations[sp_addr.scan_key] << sp_addr.spend_key
44
56
  end
57
+
58
+ # Check K_max limit: fail if any group exceeds the limit
59
+ destinations.each_value do |spends|
60
+ raise ArgumentError, "Recipient group exceeds K_max limit (#{K_MAX})." if spends.length > K_MAX
61
+ end
62
+
45
63
  outputs = []
46
64
  destinations.each do |scan_key, spends|
47
65
  scan_key = Bitcoin::Key.new(pubkey: scan_key).to_point.to_jacobian
@@ -55,6 +73,89 @@ module Bitcoin
55
73
  outputs
56
74
  end
57
75
 
76
+
77
+ # Scan transaction outputs for silent payment outputs belonging to the receiver.
78
+ #
79
+ # @param [Array<Bitcoin::Script>] prevouts An array of previous output scripts corresponding to each input.
80
+ # @param [Bitcoin::Key] scan_private_key The receiver's scan private key (b_scan).
81
+ # @param [Bitcoin::Key] spend_pubkey The receiver's spend key. Pass a Key initialized with spend_priv_key to derive the public key.
82
+ # @param [Array<Integer>] labels An array of label integers for labeled addresses (default: []).
83
+ # @return [Array<Bitcoin::SilentPayment::Output>] An array of detected silent payment outputs.
84
+ # @raise [ArgumentError] If any of the required parameters are invalid.
85
+ def scan_sp_outputs(prevouts, scan_private_key, spend_pubkey, labels = [])
86
+ raise ArgumentError, "prevouts must be Array." unless prevouts.is_a? Array
87
+ raise ArgumentError, "scan_private_key must be Bitcoin::Key." unless scan_private_key.is_a? Bitcoin::Key
88
+ raise ArgumentError, "spend_pubkey must be Bitcoin::Key." unless spend_pubkey.is_a? Bitcoin::Key
89
+
90
+ has_taproot = !outputs.find{|o| o.script_pubkey.p2tr? }.nil?
91
+ return [] unless has_taproot
92
+ sum_pub_keys = Bitcoin::Secp256k1::GROUP.infinity.to_jacobian
93
+ maximum_witness_version = Bitcoin::Opcodes.opcode_to_small_int(Bitcoin::Opcodes::OP_1)
94
+ prevouts.each.with_index do |prevout, index|
95
+ return [] if prevout.witness_program? && prevout.witness_data.first > maximum_witness_version
96
+
97
+ public_key = extract_public_key(prevout, inputs[index])
98
+ next if public_key.nil?
99
+ sum_pub_keys += public_key.to_point.to_jacobian
100
+ end
101
+ return [] if sum_pub_keys.infinity?
102
+
103
+ field = ECDSA::PrimeField.new(Bitcoin::Secp256k1::GROUP.order)
104
+ outpoint_l = inputs.map{|i|i.out_point.to_hex}.sort.first
105
+ input_hash = Bitcoin.tagged_hash("BIP0352/Inputs", outpoint_l.htb + sum_pub_keys.to_affine.to_hex.htb).bth
106
+ ecdh_shared_secret = (sum_pub_keys * field.mod(input_hash.to_i(16) * scan_private_key.priv_key.to_i(16))).to_affine.to_hex.htb
107
+
108
+ # Pre-compute label tweak points with their label values and scalar tweaks
109
+ label_tweaks = labels.map do |m|
110
+ label_tweak = Bitcoin.tagged_hash('BIP0352/Label', scan_private_key.priv_key.htb + [m].pack('N'))
111
+ label_point = Bitcoin::Secp256k1::GROUP.generator.to_jacobian * label_tweak.bti
112
+ [m, label_tweak, label_point]
113
+ end
114
+
115
+ k = 0
116
+ results = []
117
+ found_outputs = Set.new
118
+ loop do
119
+ # Stop scanning if K_max limit is reached
120
+ break if k == K_MAX
121
+
122
+ t_k = Bitcoin.tagged_hash('BIP0352/SharedSecret', ecdh_shared_secret + [k].pack('N'))
123
+ p_k = Bitcoin::Secp256k1::GROUP.generator.to_jacobian * t_k.bti + spend_pubkey.to_point.to_jacobian
124
+ found = false
125
+ outputs.each do |output|
126
+ next unless output.script_pubkey.p2tr?
127
+ next if found_outputs.include?(output)
128
+ output_pubkey = Bitcoin::Key.from_xonly_pubkey(output.script_pubkey.witness_data[1].bth)
129
+
130
+ # Check basic match (no label)
131
+ if p_k.to_affine.x == output_pubkey.to_point.x
132
+ results << SilentPayment::Output.new(output, t_k)
133
+ found_outputs << output
134
+ k += 1
135
+ found = true
136
+ break
137
+ end
138
+
139
+ # Check labeled matches
140
+ label_tweaks.each do |label_value, label_tweak_scalar, label_point|
141
+ p_k_labeled = p_k + label_point
142
+ if p_k_labeled.to_affine.x == output_pubkey.to_point.x
143
+ # Full tweak is t_k + label_tweak (mod order)
144
+ full_tweak = field.mod(t_k.bti + label_tweak_scalar.bti).to_s(16).rjust(64, '0').htb
145
+ results << SilentPayment::Output.new(output, full_tweak, label_value)
146
+ found_outputs << output
147
+ k += 1
148
+ found = true
149
+ break
150
+ end
151
+ end
152
+ break if found
153
+ end
154
+ break unless found
155
+ end
156
+ results
157
+ end
158
+
58
159
  # Extract public keys from +prevout+ and input.
59
160
  def extract_public_key(prevout, input)
60
161
  if prevout.p2pkh?
data/lib/bitcoin/util.rb CHANGED
@@ -14,7 +14,7 @@ module Bitcoin
14
14
 
15
15
  def unpack_var_string(payload)
16
16
  size, payload = unpack_var_int(payload)
17
- size > 0 ? payload.unpack("a#{size}a*") : [nil, payload]
17
+ size && size > 0 ? payload.unpack("a#{size}a*") : ['', payload.to_s]
18
18
  end
19
19
 
20
20
  def pack_var_int(i)
@@ -102,7 +102,7 @@ module Bitcoin
102
102
  # @return [String] the hash value with binary format.
103
103
  def tagged_hash(tag, msg)
104
104
  tag_hash = Digest::SHA256.digest(tag)
105
- Digest::SHA256.digest(tag_hash + tag_hash + msg)
105
+ Digest::SHA256.digest(tag_hash + tag_hash + msg.b)
106
106
  end
107
107
 
108
108
  # encode Base58 check address.
@@ -1,3 +1,3 @@
1
1
  module Bitcoin
2
- VERSION = "1.12.0"
2
+ VERSION = "1.12.1"
3
3
  end
data/lib/bitcoin.rb CHANGED
@@ -2,13 +2,11 @@
2
2
  # https://github.com/lian/bitcoin-ruby/blob/master/COPYING
3
3
 
4
4
  require 'bitcoin/version'
5
- require 'eventmachine'
6
5
  require 'schnorr'
7
6
  require 'securerandom'
8
7
  require 'json'
9
8
  require 'bech32'
10
9
  require 'base64'
11
- require 'observer'
12
10
  require 'tmpdir'
13
11
  require 'merkle'
14
12
 
@@ -36,13 +34,10 @@ module Bitcoin
36
34
  autoload :ExtKey, 'bitcoin/ext_key'
37
35
  autoload :ExtPubkey, 'bitcoin/ext_key'
38
36
  autoload :Opcodes, 'bitcoin/opcodes'
39
- autoload :Node, 'bitcoin/node'
40
37
  autoload :Base58, 'bitcoin/base58'
41
38
  autoload :Secp256k1, 'bitcoin/secp256k1'
42
39
  autoload :Mnemonic, 'bitcoin/mnemonic'
43
40
  autoload :ValidationState, 'bitcoin/validation'
44
- autoload :Network, 'bitcoin/network'
45
- autoload :Store, 'bitcoin/store'
46
41
  autoload :RPC, 'bitcoin/rpc'
47
42
  autoload :Wallet, 'bitcoin/wallet'
48
43
  autoload :BloomFilter, 'bitcoin/bloom_filter'
@@ -64,7 +59,6 @@ module Bitcoin
64
59
  autoload :SilentPayment, 'bitcoin/silent_payment'
65
60
  autoload :BIP324, 'bitcoin/bip324'
66
61
  autoload :BIP321URI, 'bitcoin/bip321_uri'
67
- autoload :BIP353, 'bitcoin/bip353'
68
62
 
69
63
  require_relative 'bitcoin/constants'
70
64
  require_relative 'bitcoin/ext/ecdsa'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitcoinrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 1.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
@@ -23,20 +23,6 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: 0.5.1
26
- - !ruby/object:Gem::Dependency
27
- name: eventmachine
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
40
26
  - !ruby/object:Gem::Dependency
41
27
  name: murmurhash3
42
28
  requirement: !ruby/object:Gem::Requirement
@@ -65,62 +51,6 @@ dependencies:
65
51
  - - ">="
66
52
  - !ruby/object:Gem::Version
67
53
  version: 1.5.0
68
- - !ruby/object:Gem::Dependency
69
- name: daemon-spawn
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: '0'
82
- - !ruby/object:Gem::Dependency
83
- name: thor
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- version: '0'
89
- type: :runtime
90
- prerelease: false
91
- version_requirements: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: '0'
96
- - !ruby/object:Gem::Dependency
97
- name: eventmachine_httpserver
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- version: '0'
103
- type: :runtime
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- - !ruby/object:Gem::Dependency
111
- name: iniparse
112
- requirement: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- type: :runtime
118
- prerelease: false
119
- version_requirements: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
54
  - !ruby/object:Gem::Dependency
125
55
  name: siphash
126
56
  requirement: !ruby/object:Gem::Requirement
@@ -177,20 +107,6 @@ dependencies:
177
107
  - - "~>"
178
108
  - !ruby/object:Gem::Version
179
109
  version: 0.2.0
180
- - !ruby/object:Gem::Dependency
181
- name: observer
182
- requirement: !ruby/object:Gem::Requirement
183
- requirements:
184
- - - "~>"
185
- - !ruby/object:Gem::Version
186
- version: 0.1.2
187
- type: :runtime
188
- prerelease: false
189
- version_requirements: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - "~>"
192
- - !ruby/object:Gem::Version
193
- version: 0.1.2
194
110
  - !ruby/object:Gem::Dependency
195
111
  name: secp256k1rb
196
112
  requirement: !ruby/object:Gem::Requirement
@@ -233,12 +149,24 @@ dependencies:
233
149
  - - '='
234
150
  - !ruby/object:Gem::Version
235
151
  version: 0.3.0
152
+ - !ruby/object:Gem::Dependency
153
+ name: dnsruby
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '='
157
+ - !ruby/object:Gem::Version
158
+ version: 1.73.0
159
+ type: :runtime
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - '='
164
+ - !ruby/object:Gem::Version
165
+ version: 1.73.0
236
166
  description: The implementation of Bitcoin Protocol for Ruby.
237
167
  email:
238
168
  - azuchi@chaintope.com
239
- executables:
240
- - bitcoinrb-cli
241
- - bitcoinrbd
169
+ executables: []
242
170
  extensions: []
243
171
  extra_rdoc_files: []
244
172
  files:
@@ -257,8 +185,6 @@ files:
257
185
  - bin/setup
258
186
  - bitcoinrb.conf.sample
259
187
  - bitcoinrb.gemspec
260
- - exe/bitcoinrb-cli
261
- - exe/bitcoinrbd
262
188
  - lib/bitcoin.rb
263
189
  - lib/bitcoin/base58.rb
264
190
  - lib/bitcoin/bip321_uri.rb
@@ -297,6 +223,7 @@ files:
297
223
  - lib/bitcoin/descriptor/sh.rb
298
224
  - lib/bitcoin/descriptor/sorted_multi.rb
299
225
  - lib/bitcoin/descriptor/sorted_multi_a.rb
226
+ - lib/bitcoin/descriptor/sp.rb
300
227
  - lib/bitcoin/descriptor/tr.rb
301
228
  - lib/bitcoin/descriptor/wpkh.rb
302
229
  - lib/bitcoin/descriptor/wsh.rb
@@ -367,16 +294,6 @@ files:
367
294
  - lib/bitcoin/mnemonic/wordlist/italian.txt
368
295
  - lib/bitcoin/mnemonic/wordlist/japanese.txt
369
296
  - lib/bitcoin/mnemonic/wordlist/spanish.txt
370
- - lib/bitcoin/network.rb
371
- - lib/bitcoin/network/connection.rb
372
- - lib/bitcoin/network/message_handler.rb
373
- - lib/bitcoin/network/peer.rb
374
- - lib/bitcoin/network/peer_discovery.rb
375
- - lib/bitcoin/network/pool.rb
376
- - lib/bitcoin/node.rb
377
- - lib/bitcoin/node/cli.rb
378
- - lib/bitcoin/node/configuration.rb
379
- - lib/bitcoin/node/spv.rb
380
297
  - lib/bitcoin/opcodes.rb
381
298
  - lib/bitcoin/out_point.rb
382
299
  - lib/bitcoin/partial_tree.rb
@@ -390,8 +307,6 @@ files:
390
307
  - lib/bitcoin/psbt/tx.rb
391
308
  - lib/bitcoin/rpc.rb
392
309
  - lib/bitcoin/rpc/bitcoin_core_client.rb
393
- - lib/bitcoin/rpc/http_server.rb
394
- - lib/bitcoin/rpc/request_handler.rb
395
310
  - lib/bitcoin/script/multisig.rb
396
311
  - lib/bitcoin/script/script.rb
397
312
  - lib/bitcoin/script/script_error.rb
@@ -404,16 +319,11 @@ files:
404
319
  - lib/bitcoin/secp256k1/ruby.rb
405
320
  - lib/bitcoin/sighash_generator.rb
406
321
  - lib/bitcoin/silent_payment.rb
322
+ - lib/bitcoin/silent_payment/output.rb
407
323
  - lib/bitcoin/slip39.rb
408
324
  - lib/bitcoin/slip39/share.rb
409
325
  - lib/bitcoin/slip39/sss.rb
410
326
  - lib/bitcoin/slip39/wordlist/english.txt
411
- - lib/bitcoin/store.rb
412
- - lib/bitcoin/store/chain_entry.rb
413
- - lib/bitcoin/store/db.rb
414
- - lib/bitcoin/store/db/level_db.rb
415
- - lib/bitcoin/store/spv_chain.rb
416
- - lib/bitcoin/store/utxo_db.rb
417
327
  - lib/bitcoin/taproot.rb
418
328
  - lib/bitcoin/taproot/control_block.rb
419
329
  - lib/bitcoin/taproot/custom_depth_builder.rb
data/exe/bitcoinrb-cli DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'bitcoin'
4
-
5
- Bitcoin::Node::CLI.start(ARGV)
data/exe/bitcoinrbd DELETED
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'thor'
3
- require 'bitcoin'
4
- require 'daemon_spawn'
5
-
6
- class BitcoinDaemon < DaemonSpawn::Base
7
-
8
- def start(args)
9
- puts "Bitcoinrb daemon start : #{Time.now}"
10
- conf = Bitcoin::Node::Configuration.new(network: args.first[:network])
11
- node = Bitcoin::Node::SPV.new(conf)
12
- node.run
13
- end
14
-
15
- def stop
16
- puts "Stopping Bitcoinrb daemon : #{Time.now}"
17
- node.shutdown
18
- end
19
-
20
- end
21
-
22
- class Bitcoinrbd < Thor
23
-
24
- class_option :network, aliases: '-n', default: :mainnet
25
-
26
- desc 'start', 'start bitcoinrb daemon.'
27
- def start
28
- network = options['network'] ? options['network'].to_sym : :mainnet
29
- Bitcoin.chain_params = network
30
- FileUtils.mkdir_p(Bitcoin.base_dir)
31
- execute_daemon(['start', network: network])
32
- end
33
-
34
- private
35
-
36
- def execute_daemon(cmd_args)
37
- BitcoinDaemon.spawn!({working_dir: Bitcoin.base_dir,
38
- log_file: "#{Bitcoin.base_dir}/log/bitcoinrbd.log",
39
- pid_file: "#{Bitcoin.base_dir}/bitcoinrbd.pid",
40
- sync_log: true,
41
- singleton: true}, cmd_args)
42
- end
43
-
44
- end
45
-
46
- Bitcoinrbd.start(ARGV)
@@ -1,73 +0,0 @@
1
- module Bitcoin
2
-
3
- module Network
4
-
5
- # Basic Bitcoin P2P connection class
6
- class Connection < EM::Connection
7
-
8
- include MessageHandler
9
-
10
- attr_reader :peer, :logger
11
-
12
- # remote peer version.
13
- attr_accessor :version
14
-
15
- # if true, this peer send new block announcements using a headers message rather than an inv message.
16
- attr_accessor :sendheaders
17
-
18
- # minimum fee(in satoshis per kilobyte) for relay tx
19
- attr_accessor :fee_rate
20
-
21
- def initialize(peer)
22
- @peer = peer
23
- @logger = peer.logger
24
- @sendheaders = false
25
- @attr_accessor = 0
26
- @message = ''
27
- self.pending_connect_timeout = 5.0
28
- end
29
-
30
- def post_init
31
- logger.info "connected. #{addr}"
32
- peer.conn_time = Time.now.to_i
33
- begin_handshake
34
- end
35
-
36
- # handle receiving data from remote node.
37
- def receive_data(data)
38
- handle(data)
39
- end
40
-
41
- def post_handshake
42
- peer.post_handshake
43
- end
44
-
45
- def addr
46
- peer.addr
47
- end
48
-
49
- # close network connection.
50
- def close(msg = '')
51
- logger.info "close connection with #{addr}. #{msg}"
52
- close_connection_after_writing
53
- end
54
-
55
- def handle_error(e)
56
- peer.handle_error(e)
57
- end
58
-
59
- def unbind
60
- logger.info "unbind. #{addr}"
61
- peer.unbind
62
- end
63
-
64
- private
65
-
66
- # start handshake
67
- def begin_handshake
68
- logger.info "begin handshake with #{addr}"
69
- send_message(peer.local_version)
70
- end
71
- end
72
- end
73
- end