bitcoinrb 0.6.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +37 -0
- data/.rspec_parallel +2 -0
- data/.ruby-version +1 -1
- data/README.md +1 -1
- data/bitcoinrb.gemspec +4 -3
- data/lib/bitcoin/constants.rb +24 -17
- data/lib/bitcoin/ext/array_ext.rb +22 -0
- data/lib/bitcoin/ext/ecdsa.rb +5 -0
- data/lib/bitcoin/ext.rb +1 -0
- data/lib/bitcoin/ext_key.rb +1 -1
- data/lib/bitcoin/key.rb +42 -2
- data/lib/bitcoin/message/addr_v2.rb +34 -0
- data/lib/bitcoin/message/base.rb +16 -0
- data/lib/bitcoin/message/network_addr.rb +141 -18
- data/lib/bitcoin/message/send_addr_v2.rb +13 -0
- data/lib/bitcoin/message/tx.rb +1 -1
- data/lib/bitcoin/message.rb +72 -0
- data/lib/bitcoin/message_sign.rb +47 -0
- data/lib/bitcoin/payments/payment.pb.rb +1 -1
- data/lib/bitcoin/psbt/input.rb +1 -1
- data/lib/bitcoin/psbt/tx.rb +10 -1
- data/lib/bitcoin/psbt.rb +8 -0
- data/lib/bitcoin/rpc/request_handler.rb +3 -3
- data/lib/bitcoin/script/script.rb +29 -12
- data/lib/bitcoin/script/script_interpreter.rb +6 -3
- data/lib/bitcoin/script/tx_checker.rb +2 -4
- data/lib/bitcoin/secp256k1/native.rb +68 -14
- data/lib/bitcoin/secp256k1/ruby.rb +31 -3
- data/lib/bitcoin/sighash_generator.rb +1 -0
- data/lib/bitcoin/taproot/leaf_node.rb +23 -0
- data/lib/bitcoin/taproot/simple_builder.rb +155 -0
- data/lib/bitcoin/taproot.rb +45 -0
- data/lib/bitcoin/tx.rb +17 -16
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin.rb +3 -8
- metadata +44 -8
- data/.travis.yml +0 -13
@@ -0,0 +1,155 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Taproot
|
3
|
+
|
4
|
+
# Utility class to construct Taproot outputs from internal key and script tree.keyPathSpending
|
5
|
+
# SimpleBuilder builds a script tree that places all lock scripts, in the order they are added, as leaf nodes.
|
6
|
+
# It is not possible to specify the depth of the locking script or to insert any intermediate nodes.
|
7
|
+
class SimpleBuilder
|
8
|
+
include Bitcoin::Opcodes
|
9
|
+
|
10
|
+
attr_reader :internal_key # String with hex format
|
11
|
+
attr_reader :branches # List of branch that has two child leaves
|
12
|
+
|
13
|
+
# Initialize builder.
|
14
|
+
# @param [String] internal_key Internal public key with hex format.
|
15
|
+
# @param [Array[Bitcoin::Taproot::LeafNode]] leaves (Optional) Array of leaf nodes for each lock condition.
|
16
|
+
# @raise [Bitcoin::Taproot::Builder] +internal_pubkey+ dose not xonly public key or leaf in +leaves+ does not instance of Bitcoin::Taproot::LeafNode.
|
17
|
+
# @return [Bitcoin::Taproot::SimpleBuilder]
|
18
|
+
def initialize(internal_key, leaves = [])
|
19
|
+
raise Error, 'Internal public key must be 32 bytes' unless internal_key.htb.bytesize == 32
|
20
|
+
raise Error, 'leaf must be Bitcoin::Taproot::LeafNode object' if leaves.find{ |leaf| !leaf.is_a?(Bitcoin::Taproot::LeafNode)}
|
21
|
+
|
22
|
+
@leaves = leaves
|
23
|
+
@branches = leaves.each_slice(2).map.to_a
|
24
|
+
@internal_key = internal_key
|
25
|
+
end
|
26
|
+
|
27
|
+
# Add a leaf node to the end of the current branch.
|
28
|
+
# @param [Bitcoin::Taproot::LeafNode] leaf Leaf node to be added.
|
29
|
+
def add_leaf(leaf)
|
30
|
+
raise Error, 'leaf must be Bitcoin::Taproot::LeafNode object' unless leaf.is_a?(Bitcoin::Taproot::LeafNode)
|
31
|
+
|
32
|
+
if branches.last&.size == 1
|
33
|
+
branches.last << leaf
|
34
|
+
else
|
35
|
+
branches << [leaf]
|
36
|
+
end
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add a pair of leaf nodes as a branch. If there is only one, add a branch with only one child.
|
41
|
+
# @param [Bitcoin::Taproot::LeafNode] leaf1 Leaf node to be added.
|
42
|
+
# @param [Bitcoin::Taproot::LeafNode] leaf2 Leaf node to be added.
|
43
|
+
def add_branch(leaf1, leaf2 = nil)
|
44
|
+
raise Error, 'leaf1 must be Bitcoin::Taproot::LeafNode object' unless leaf1.is_a?(Bitcoin::Taproot::LeafNode)
|
45
|
+
raise Error, 'leaf2 must be Bitcoin::Taproot::LeafNode object' if leaf2 && !leaf2.is_a?(Bitcoin::Taproot::LeafNode)
|
46
|
+
|
47
|
+
branches << (leaf2.nil? ? [leaf1] : [leaf1, leaf2])
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# Build P2TR script.
|
52
|
+
# @return [Bitcoin::Script] P2TR script.
|
53
|
+
def build
|
54
|
+
q = tweak_public_key
|
55
|
+
Bitcoin::Script.new << OP_1 << q.xonly_pubkey
|
56
|
+
end
|
57
|
+
|
58
|
+
# Compute the tweaked public key.
|
59
|
+
# @return [Bitcoin::Key] the tweaked public key
|
60
|
+
def tweak_public_key
|
61
|
+
Taproot.tweak_public_key(Bitcoin::Key.from_xonly_pubkey(internal_key), merkle_root)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Compute the secret key for a tweaked public key.
|
65
|
+
# @param [Bitcoin::Key] key key object contains private key.
|
66
|
+
# @return [Bitcoin::Key] secret key for a tweaked public key
|
67
|
+
def tweak_private_key(key)
|
68
|
+
raise Error, 'Requires private key' unless key.priv_key
|
69
|
+
|
70
|
+
Taproot.tweak_private_key(key, merkle_root)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Generate control block needed to unlock with script-path.
|
74
|
+
# @param [Bitcoin::Taproot::LeafNode] leaf Leaf to use for unlocking.
|
75
|
+
# @return [String] control block with binary format.
|
76
|
+
def control_block(leaf)
|
77
|
+
path = inclusion_proof(leaf)
|
78
|
+
parity = tweak_public_key.to_point.has_even_y? ? 0 : 1
|
79
|
+
[parity + leaf.leaf_ver].pack("C") + internal_key.htb + path.join
|
80
|
+
end
|
81
|
+
|
82
|
+
# Generate inclusion proof for +leaf+.
|
83
|
+
# @param [Bitcoin::Taproot::LeafNode] leaf The leaf node in script tree.
|
84
|
+
# @return [Array[String]] Inclusion proof.
|
85
|
+
# @raise [Bitcoin::Taproot::Error] If the specified +leaf+ does not exist
|
86
|
+
def inclusion_proof(leaf)
|
87
|
+
proofs = []
|
88
|
+
target_branch = branches.find{|b| b.include?(leaf)}
|
89
|
+
raise Error 'Specified leaf does not exist' unless target_branch
|
90
|
+
|
91
|
+
# flatten each branch
|
92
|
+
proofs << hash_value(target_branch.find{|b| b != leaf}) if target_branch.size == 2
|
93
|
+
parent_hash = combine_hash(target_branch)
|
94
|
+
parents = branches.map {|pair| combine_hash(pair)}
|
95
|
+
|
96
|
+
until parents.size == 1
|
97
|
+
parents = parents.each_slice(2).map do |pair|
|
98
|
+
combined = combine_hash(pair)
|
99
|
+
unless pair.size == 1
|
100
|
+
if hash_value(pair[0]) == parent_hash
|
101
|
+
proofs << hash_value(pair[1])
|
102
|
+
parent_hash = combined
|
103
|
+
elsif hash_value(pair[1]) == parent_hash
|
104
|
+
proofs << hash_value(pair[0])
|
105
|
+
parent_hash = combined
|
106
|
+
end
|
107
|
+
end
|
108
|
+
combined
|
109
|
+
end
|
110
|
+
end
|
111
|
+
proofs
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# Compute tweak from script tree.
|
117
|
+
# @return [String] tweak with binary format.
|
118
|
+
def tweak
|
119
|
+
Taproot.tweak(Bitcoin::Key.from_xonly_pubkey(internal_key), merkle_root)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Calculate merkle root from branches.
|
123
|
+
# @return [String] merkle root with hex format.
|
124
|
+
def merkle_root
|
125
|
+
parents = branches.map {|pair| combine_hash(pair)}
|
126
|
+
if parents.empty?
|
127
|
+
parents = ['']
|
128
|
+
elsif parents.size == 1
|
129
|
+
parents = [combine_hash(parents)]
|
130
|
+
else
|
131
|
+
parents = parents.each_slice(2).map { |pair| combine_hash(pair) } until parents.size == 1
|
132
|
+
end
|
133
|
+
parents.first.bth
|
134
|
+
end
|
135
|
+
|
136
|
+
def combine_hash(pair)
|
137
|
+
if pair.size == 1
|
138
|
+
hash_value(pair[0])
|
139
|
+
else
|
140
|
+
hash1 = hash_value(pair[0])
|
141
|
+
hash2 = hash_value(pair[1])
|
142
|
+
|
143
|
+
# Lexicographically sort a and b's hash, and compute parent hash.
|
144
|
+
payload = hash1.bth < hash2.bth ? hash1 + hash2 : hash2 + hash1
|
145
|
+
Bitcoin.tagged_hash('TapBranch', payload)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def hash_value(leaf_or_branch)
|
150
|
+
leaf_or_branch.is_a?(LeafNode) ? leaf_or_branch.leaf_hash : leaf_or_branch
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Taproot
|
3
|
+
|
4
|
+
class Error < StandardError; end
|
5
|
+
|
6
|
+
autoload :LeafNode, 'bitcoin/taproot/leaf_node'
|
7
|
+
autoload :SimpleBuilder, 'bitcoin/taproot/simple_builder'
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
# Calculate tweak value from +internal_pubkey+ and +merkle_root+.
|
12
|
+
# @param [Bitcoin::Key] internal_key Internal key with hex format(x-only public key).
|
13
|
+
# @param [String] merkle_root Merkle root value of script tree with hex format.
|
14
|
+
# @return [String] teak value with binary format.
|
15
|
+
def tweak(internal_key, merkle_root)
|
16
|
+
raise Error, 'internal_key must be Bitcoin::Key object.' unless internal_key.is_a?(Bitcoin::Key)
|
17
|
+
|
18
|
+
merkle_root ||= ''
|
19
|
+
t = Bitcoin.tagged_hash('TapTweak', internal_key.xonly_pubkey.htb + merkle_root.htb)
|
20
|
+
raise Error, 'tweak value exceeds the curve order' if t.bti >= ECDSA::Group::Secp256k1.order
|
21
|
+
|
22
|
+
t
|
23
|
+
end
|
24
|
+
|
25
|
+
# Generate tweak public key form +internal_pubkey+ and +merkle_root+.
|
26
|
+
# @param [Bitcoin::Key] internal_key Internal key with hex format(x-only public key).
|
27
|
+
# @param [String] merkle_root Merkle root value of script tree with hex format.
|
28
|
+
# @return [Bitcoin::Key] Tweaked public key.
|
29
|
+
def tweak_public_key(internal_key, merkle_root)
|
30
|
+
t = tweak(internal_key, merkle_root)
|
31
|
+
key = Bitcoin::Key.new(priv_key: t.bth, key_type: Key::TYPES[:compressed])
|
32
|
+
Bitcoin::Key.from_point(key.to_point + internal_key.to_point)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate tweak private key
|
36
|
+
#
|
37
|
+
def tweak_private_key(internal_private_key, merkle_root)
|
38
|
+
p = internal_private_key.to_point
|
39
|
+
private_key = p.has_even_y? ? internal_private_key.priv_key.to_i(16) :
|
40
|
+
ECDSA::Group::Secp256k1.order - internal_private_key.priv_key.to_i(16)
|
41
|
+
t = tweak(internal_private_key, merkle_root)
|
42
|
+
Bitcoin::Key.new(priv_key: ((t.bti + private_key) % ECDSA::Group::Secp256k1.order).to_even_length_hex)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bitcoin/tx.rb
CHANGED
@@ -33,13 +33,13 @@ module Bitcoin
|
|
33
33
|
alias_method :in, :inputs
|
34
34
|
alias_method :out, :outputs
|
35
35
|
|
36
|
-
def self.parse_from_payload(payload, non_witness: false)
|
36
|
+
def self.parse_from_payload(payload, non_witness: false, strict: false)
|
37
37
|
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
38
38
|
tx = new
|
39
39
|
tx.version = buf.read(4).unpack1('V')
|
40
40
|
|
41
41
|
in_count = Bitcoin.unpack_var_int_from_io(buf)
|
42
|
-
|
42
|
+
has_witness = false
|
43
43
|
if in_count.zero? && !non_witness
|
44
44
|
tx.marker = 0
|
45
45
|
tx.flag = buf.read(1).unpack1('c')
|
@@ -47,7 +47,7 @@ module Bitcoin
|
|
47
47
|
buf.pos -= 1
|
48
48
|
else
|
49
49
|
in_count = Bitcoin.unpack_var_int_from_io(buf)
|
50
|
-
|
50
|
+
has_witness = true
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -60,14 +60,14 @@ module Bitcoin
|
|
60
60
|
tx.outputs << TxOut.parse_from_payload(buf)
|
61
61
|
end
|
62
62
|
|
63
|
-
if
|
63
|
+
if has_witness
|
64
64
|
in_count.times do |i|
|
65
65
|
tx.inputs[i].script_witness = Bitcoin::ScriptWitness.parse_from_payload(buf)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
raise ArgumentError, 'Transaction has unexpected data.' if strict && (buf.pos + 4) != buf.length
|
69
70
|
tx.lock_time = buf.read(4).unpack1('V')
|
70
|
-
|
71
71
|
tx
|
72
72
|
end
|
73
73
|
|
@@ -192,8 +192,10 @@ module Bitcoin
|
|
192
192
|
# @param [Integer] amount bitcoin amount locked in input. required for witness input only.
|
193
193
|
# @param [Integer] skip_separator_index If output_script is P2WSH and output_script contains any OP_CODESEPARATOR,
|
194
194
|
# the script code needs is the witnessScript but removing everything up to and including the last executed OP_CODESEPARATOR before the signature checking opcode being executed.
|
195
|
+
# @param [Array[Bitcoin::TxOut] prevouts Previous outputs referenced by all Tx inputs, required for taproot.
|
196
|
+
# @return [String] signature hash with binary format.
|
195
197
|
def sighash_for_input(input_index, output_script = nil, opts: {}, hash_type: SIGHASH_TYPE[:all],
|
196
|
-
sig_version: :base, amount: nil, skip_separator_index: 0)
|
198
|
+
sig_version: :base, amount: nil, skip_separator_index: 0, prevouts: [])
|
197
199
|
raise ArgumentError, 'input_index must be specified.' unless input_index
|
198
200
|
raise ArgumentError, 'does not exist input corresponding to input_index.' if input_index >= inputs.size
|
199
201
|
raise ArgumentError, 'script_pubkey must be specified.' if [:base, :witness_v0].include?(sig_version) && output_script.nil?
|
@@ -202,6 +204,8 @@ module Bitcoin
|
|
202
204
|
opts[:skip_separator_index] = skip_separator_index
|
203
205
|
opts[:sig_version] = sig_version
|
204
206
|
opts[:script_code] = output_script
|
207
|
+
opts[:prevouts] = prevouts
|
208
|
+
opts[:last_code_separator_pos] ||= 0xffffffff
|
205
209
|
sig_hash_gen = SigHashGenerator.load(sig_version)
|
206
210
|
sig_hash_gen.generate(self, input_index, hash_type, opts)
|
207
211
|
end
|
@@ -211,7 +215,9 @@ module Bitcoin
|
|
211
215
|
# @param [Bitcoin::Script] script_pubkey the script pubkey for target input.
|
212
216
|
# @param [Integer] amount the amount of bitcoin, require for witness program only.
|
213
217
|
# @param [Array] flags the flags used when execute script interpreter.
|
214
|
-
|
218
|
+
# @param [Array[Bitcoin::TxOut]] prevouts Previous outputs referenced by all Tx inputs, required for taproot.
|
219
|
+
# @return [Boolean] result
|
220
|
+
def verify_input_sig(input_index, script_pubkey, amount: nil, flags: STANDARD_SCRIPT_VERIFY_FLAGS, prevouts: [])
|
215
221
|
script_sig = inputs[input_index].script_sig
|
216
222
|
has_witness = inputs[input_index].has_witness?
|
217
223
|
|
@@ -222,7 +228,7 @@ module Bitcoin
|
|
222
228
|
end
|
223
229
|
|
224
230
|
if has_witness
|
225
|
-
verify_input_sig_for_witness(input_index, script_pubkey, amount, flags)
|
231
|
+
verify_input_sig_for_witness(input_index, script_pubkey, amount, flags, prevouts)
|
226
232
|
else
|
227
233
|
verify_input_sig_for_legacy(input_index, script_pubkey, flags)
|
228
234
|
end
|
@@ -255,16 +261,11 @@ module Bitcoin
|
|
255
261
|
end
|
256
262
|
|
257
263
|
# verify input signature for witness tx.
|
258
|
-
def verify_input_sig_for_witness(input_index, script_pubkey, amount, flags)
|
259
|
-
|
260
|
-
flags |= SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
|
261
|
-
checker = Bitcoin::TxChecker.new(tx: self, input_index: input_index, amount: amount)
|
264
|
+
def verify_input_sig_for_witness(input_index, script_pubkey, amount, flags, prevouts)
|
265
|
+
checker = Bitcoin::TxChecker.new(tx: self, input_index: input_index, amount: amount, prevouts: prevouts)
|
262
266
|
interpreter = Bitcoin::ScriptInterpreter.new(checker: checker, flags: flags)
|
263
267
|
i = inputs[input_index]
|
264
|
-
|
265
|
-
script_sig = i.script_sig
|
266
|
-
witness = i.script_witness
|
267
|
-
interpreter.verify_script(script_sig, script_pubkey, witness)
|
268
|
+
interpreter.verify_script(i.script_sig, script_pubkey, i.script_witness)
|
268
269
|
end
|
269
270
|
|
270
271
|
end
|
data/lib/bitcoin/version.rb
CHANGED
data/lib/bitcoin.rb
CHANGED
@@ -60,6 +60,8 @@ module Bitcoin
|
|
60
60
|
autoload :BIP85Entropy, 'bitcoin/bip85_entropy'
|
61
61
|
autoload :Errors, 'bitcoin/errors'
|
62
62
|
autoload :SigHashGenerator, 'bitcoin/sighash_generator'
|
63
|
+
autoload :MessageSign, 'bitcoin/message_sign'
|
64
|
+
autoload :Taproot, 'bitcoin/taproot'
|
63
65
|
|
64
66
|
require_relative 'bitcoin/constants'
|
65
67
|
require_relative 'bitcoin/ext/ecdsa'
|
@@ -133,14 +135,7 @@ module Bitcoin
|
|
133
135
|
|
134
136
|
# get opcode
|
135
137
|
def opcode
|
136
|
-
|
137
|
-
when Encoding::ASCII_8BIT
|
138
|
-
each_byte.next
|
139
|
-
when Encoding::US_ASCII
|
140
|
-
ord
|
141
|
-
else
|
142
|
-
to_i
|
143
|
-
end
|
138
|
+
force_encoding(Encoding::ASCII_8BIT).ord
|
144
139
|
end
|
145
140
|
|
146
141
|
def opcode?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoinrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0
|
61
|
+
version: 1.1.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0
|
68
|
+
version: 1.1.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: daemon-spawn
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,14 +198,28 @@ dependencies:
|
|
198
198
|
requirements:
|
199
199
|
- - ">="
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version: 0.
|
201
|
+
version: 0.4.0
|
202
202
|
type: :runtime
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - ">="
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version: 0.
|
208
|
+
version: 0.4.0
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: base32
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 0.3.4
|
216
|
+
type: :runtime
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 0.3.4
|
209
223
|
- !ruby/object:Gem::Dependency
|
210
224
|
name: leveldb-native
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -290,6 +304,20 @@ dependencies:
|
|
290
304
|
- - ">="
|
291
305
|
- !ruby/object:Gem::Version
|
292
306
|
version: 3.11.1
|
307
|
+
- !ruby/object:Gem::Dependency
|
308
|
+
name: parallel
|
309
|
+
requirement: !ruby/object:Gem::Requirement
|
310
|
+
requirements:
|
311
|
+
- - ">="
|
312
|
+
- !ruby/object:Gem::Version
|
313
|
+
version: 1.20.1
|
314
|
+
type: :development
|
315
|
+
prerelease: false
|
316
|
+
version_requirements: !ruby/object:Gem::Requirement
|
317
|
+
requirements:
|
318
|
+
- - ">="
|
319
|
+
- !ruby/object:Gem::Version
|
320
|
+
version: 1.20.1
|
293
321
|
description: The implementation of Bitcoin Protocol for Ruby.
|
294
322
|
email:
|
295
323
|
- azuchi@chaintope.com
|
@@ -299,11 +327,12 @@ executables:
|
|
299
327
|
extensions: []
|
300
328
|
extra_rdoc_files: []
|
301
329
|
files:
|
330
|
+
- ".github/workflows/ruby.yml"
|
302
331
|
- ".gitignore"
|
303
332
|
- ".rspec"
|
333
|
+
- ".rspec_parallel"
|
304
334
|
- ".ruby-gemset"
|
305
335
|
- ".ruby-version"
|
306
|
-
- ".travis.yml"
|
307
336
|
- CODE_OF_CONDUCT.md
|
308
337
|
- Gemfile
|
309
338
|
- LICENSE.txt
|
@@ -332,6 +361,7 @@ files:
|
|
332
361
|
- lib/bitcoin/descriptor.rb
|
333
362
|
- lib/bitcoin/errors.rb
|
334
363
|
- lib/bitcoin/ext.rb
|
364
|
+
- lib/bitcoin/ext/array_ext.rb
|
335
365
|
- lib/bitcoin/ext/ecdsa.rb
|
336
366
|
- lib/bitcoin/ext/json_parser.rb
|
337
367
|
- lib/bitcoin/ext_key.rb
|
@@ -342,6 +372,7 @@ files:
|
|
342
372
|
- lib/bitcoin/merkle_tree.rb
|
343
373
|
- lib/bitcoin/message.rb
|
344
374
|
- lib/bitcoin/message/addr.rb
|
375
|
+
- lib/bitcoin/message/addr_v2.rb
|
345
376
|
- lib/bitcoin/message/base.rb
|
346
377
|
- lib/bitcoin/message/block.rb
|
347
378
|
- lib/bitcoin/message/block_transaction_request.rb
|
@@ -379,11 +410,13 @@ files:
|
|
379
410
|
- lib/bitcoin/message/pong.rb
|
380
411
|
- lib/bitcoin/message/prefilled_tx.rb
|
381
412
|
- lib/bitcoin/message/reject.rb
|
413
|
+
- lib/bitcoin/message/send_addr_v2.rb
|
382
414
|
- lib/bitcoin/message/send_cmpct.rb
|
383
415
|
- lib/bitcoin/message/send_headers.rb
|
384
416
|
- lib/bitcoin/message/tx.rb
|
385
417
|
- lib/bitcoin/message/ver_ack.rb
|
386
418
|
- lib/bitcoin/message/version.rb
|
419
|
+
- lib/bitcoin/message_sign.rb
|
387
420
|
- lib/bitcoin/mnemonic.rb
|
388
421
|
- lib/bitcoin/mnemonic/wordlist/chinese_simplified.txt
|
389
422
|
- lib/bitcoin/mnemonic/wordlist/chinese_traditional.txt
|
@@ -443,6 +476,9 @@ files:
|
|
443
476
|
- lib/bitcoin/store/db/level_db.rb
|
444
477
|
- lib/bitcoin/store/spv_chain.rb
|
445
478
|
- lib/bitcoin/store/utxo_db.rb
|
479
|
+
- lib/bitcoin/taproot.rb
|
480
|
+
- lib/bitcoin/taproot/leaf_node.rb
|
481
|
+
- lib/bitcoin/taproot/simple_builder.rb
|
446
482
|
- lib/bitcoin/tx.rb
|
447
483
|
- lib/bitcoin/tx_in.rb
|
448
484
|
- lib/bitcoin/tx_out.rb
|
@@ -478,7 +514,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
478
514
|
- !ruby/object:Gem::Version
|
479
515
|
version: '0'
|
480
516
|
requirements: []
|
481
|
-
rubygems_version: 3.2.
|
517
|
+
rubygems_version: 3.2.22
|
482
518
|
signing_key:
|
483
519
|
specification_version: 4
|
484
520
|
summary: The implementation of Bitcoin Protocol for Ruby.
|