bitcoinrb 0.3.2 → 0.8.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 +17 -6
- data/bitcoinrb.gemspec +9 -8
- data/exe/bitcoinrbd +5 -0
- data/lib/bitcoin.rb +37 -19
- data/lib/bitcoin/bip85_entropy.rb +111 -0
- data/lib/bitcoin/block_filter.rb +14 -0
- data/lib/bitcoin/block_header.rb +2 -0
- data/lib/bitcoin/chain_params.rb +9 -8
- data/lib/bitcoin/chainparams/regtest.yml +1 -1
- data/lib/bitcoin/chainparams/signet.yml +39 -0
- data/lib/bitcoin/chainparams/testnet.yml +1 -1
- data/lib/bitcoin/constants.rb +44 -10
- data/lib/bitcoin/descriptor.rb +1 -1
- data/lib/bitcoin/errors.rb +19 -0
- data/lib/bitcoin/ext.rb +6 -0
- data/lib/bitcoin/ext/array_ext.rb +22 -0
- data/lib/bitcoin/ext/ecdsa.rb +36 -0
- data/lib/bitcoin/ext/json_parser.rb +46 -0
- data/lib/bitcoin/ext_key.rb +51 -20
- data/lib/bitcoin/key.rb +89 -30
- data/lib/bitcoin/key_path.rb +12 -5
- data/lib/bitcoin/message.rb +79 -0
- data/lib/bitcoin/message/addr_v2.rb +34 -0
- data/lib/bitcoin/message/base.rb +17 -0
- data/lib/bitcoin/message/cf_parser.rb +16 -0
- data/lib/bitcoin/message/cfcheckpt.rb +36 -0
- data/lib/bitcoin/message/cfheaders.rb +40 -0
- data/lib/bitcoin/message/cfilter.rb +35 -0
- data/lib/bitcoin/message/fee_filter.rb +1 -1
- data/lib/bitcoin/message/filter_load.rb +3 -3
- data/lib/bitcoin/message/get_cfcheckpt.rb +29 -0
- data/lib/bitcoin/message/get_cfheaders.rb +24 -0
- data/lib/bitcoin/message/get_cfilters.rb +25 -0
- data/lib/bitcoin/message/header_and_short_ids.rb +1 -1
- data/lib/bitcoin/message/inventory.rb +1 -1
- data/lib/bitcoin/message/merkle_block.rb +1 -1
- data/lib/bitcoin/message/network_addr.rb +141 -18
- data/lib/bitcoin/message/ping.rb +1 -1
- data/lib/bitcoin/message/pong.rb +1 -1
- data/lib/bitcoin/message/send_addr_v2.rb +13 -0
- data/lib/bitcoin/message/send_cmpct.rb +2 -2
- data/lib/bitcoin/message/tx.rb +1 -1
- data/lib/bitcoin/message/version.rb +7 -0
- data/lib/bitcoin/message_sign.rb +47 -0
- data/lib/bitcoin/mnemonic.rb +7 -7
- data/lib/bitcoin/network/peer.rb +9 -4
- data/lib/bitcoin/network/peer_discovery.rb +1 -1
- data/lib/bitcoin/node/cli.rb +14 -10
- data/lib/bitcoin/node/configuration.rb +3 -1
- data/lib/bitcoin/node/spv.rb +9 -1
- data/lib/bitcoin/opcodes.rb +14 -1
- data/lib/bitcoin/out_point.rb +2 -0
- data/lib/bitcoin/payment_code.rb +92 -0
- data/lib/bitcoin/payments/payment.pb.rb +1 -1
- data/lib/bitcoin/psbt/hd_key_path.rb +1 -1
- data/lib/bitcoin/psbt/input.rb +9 -18
- data/lib/bitcoin/psbt/output.rb +1 -1
- data/lib/bitcoin/psbt/tx.rb +12 -17
- data/lib/bitcoin/rpc/bitcoin_core_client.rb +22 -12
- data/lib/bitcoin/rpc/request_handler.rb +5 -5
- data/lib/bitcoin/script/script.rb +96 -39
- data/lib/bitcoin/script/script_error.rb +27 -1
- data/lib/bitcoin/script/script_interpreter.rb +166 -66
- data/lib/bitcoin/script/tx_checker.rb +62 -14
- data/lib/bitcoin/secp256k1.rb +1 -0
- data/lib/bitcoin/secp256k1/native.rb +184 -17
- data/lib/bitcoin/secp256k1/rfc6979.rb +43 -0
- data/lib/bitcoin/secp256k1/ruby.rb +112 -56
- data/lib/bitcoin/sighash_generator.rb +156 -0
- data/lib/bitcoin/store.rb +1 -0
- data/lib/bitcoin/store/chain_entry.rb +1 -0
- data/lib/bitcoin/store/utxo_db.rb +226 -0
- data/lib/bitcoin/taproot.rb +9 -0
- data/lib/bitcoin/taproot/leaf_node.rb +23 -0
- data/lib/bitcoin/taproot/simple_builder.rb +139 -0
- data/lib/bitcoin/tx.rb +34 -104
- data/lib/bitcoin/tx_in.rb +4 -5
- data/lib/bitcoin/tx_out.rb +2 -3
- data/lib/bitcoin/util.rb +22 -6
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet.rb +1 -0
- data/lib/bitcoin/wallet/account.rb +2 -1
- data/lib/bitcoin/wallet/base.rb +2 -2
- data/lib/bitcoin/wallet/master_key.rb +1 -0
- data/lib/bitcoin/wallet/utxo.rb +37 -0
- metadata +86 -32
- data/.travis.yml +0 -11
data/lib/bitcoin/tx.rb
CHANGED
@@ -6,6 +6,8 @@ module Bitcoin
|
|
6
6
|
# Transaction class
|
7
7
|
class Tx
|
8
8
|
|
9
|
+
include Bitcoin::HexConverter
|
10
|
+
|
9
11
|
MAX_STANDARD_VERSION = 2
|
10
12
|
|
11
13
|
# The maximum weight for transactions we're willing to relay/mine
|
@@ -31,21 +33,21 @@ module Bitcoin
|
|
31
33
|
alias_method :in, :inputs
|
32
34
|
alias_method :out, :outputs
|
33
35
|
|
34
|
-
def self.parse_from_payload(payload, non_witness: false)
|
36
|
+
def self.parse_from_payload(payload, non_witness: false, strict: false)
|
35
37
|
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
36
38
|
tx = new
|
37
|
-
tx.version = buf.read(4).
|
39
|
+
tx.version = buf.read(4).unpack1('V')
|
38
40
|
|
39
41
|
in_count = Bitcoin.unpack_var_int_from_io(buf)
|
40
|
-
|
42
|
+
has_witness = false
|
41
43
|
if in_count.zero? && !non_witness
|
42
44
|
tx.marker = 0
|
43
|
-
tx.flag = buf.read(1).
|
45
|
+
tx.flag = buf.read(1).unpack1('c')
|
44
46
|
if tx.flag.zero?
|
45
47
|
buf.pos -= 1
|
46
48
|
else
|
47
49
|
in_count = Bitcoin.unpack_var_int_from_io(buf)
|
48
|
-
|
50
|
+
has_witness = true
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -58,19 +60,19 @@ module Bitcoin
|
|
58
60
|
tx.outputs << TxOut.parse_from_payload(buf)
|
59
61
|
end
|
60
62
|
|
61
|
-
if
|
63
|
+
if has_witness
|
62
64
|
in_count.times do |i|
|
63
65
|
tx.inputs[i].script_witness = Bitcoin::ScriptWitness.parse_from_payload(buf)
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
+
raise ArgumentError, 'Transaction has unexpected data.' if strict && (buf.pos + 4) != buf.length
|
70
|
+
tx.lock_time = buf.read(4).unpack1('V')
|
69
71
|
tx
|
70
72
|
end
|
71
73
|
|
72
74
|
def hash
|
73
|
-
|
75
|
+
to_hex.to_i(16)
|
74
76
|
end
|
75
77
|
|
76
78
|
def tx_hash
|
@@ -104,12 +106,6 @@ module Bitcoin
|
|
104
106
|
witness? ? serialize_witness_format : serialize_old_format
|
105
107
|
end
|
106
108
|
|
107
|
-
# convert tx to hex format.
|
108
|
-
# @return [String] tx with hex format.
|
109
|
-
def to_hex
|
110
|
-
to_payload.bth
|
111
|
-
end
|
112
|
-
|
113
109
|
def coinbase_tx?
|
114
110
|
inputs.length == 1 && inputs.first.coinbase?
|
115
111
|
end
|
@@ -192,22 +188,26 @@ module Bitcoin
|
|
192
188
|
# @param [Integer] input_index input index.
|
193
189
|
# @param [Integer] hash_type signature hash type
|
194
190
|
# @param [Bitcoin::Script] output_script script pubkey or script code. if script pubkey is P2WSH, set witness script to this.
|
191
|
+
# @param [Hash] opts Data required for each sig version (amount and skip_separator_index params can also be set to this parameter)
|
195
192
|
# @param [Integer] amount bitcoin amount locked in input. required for witness input only.
|
196
193
|
# @param [Integer] skip_separator_index If output_script is P2WSH and output_script contains any OP_CODESEPARATOR,
|
197
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.
|
198
|
-
|
199
|
-
|
195
|
+
# @param [Array[Bitcoin::TxOut] prevouts Previous outputs referenced by all Tx inputs, required for taproot.
|
196
|
+
# @return [String] signature hash with binary format.
|
197
|
+
def sighash_for_input(input_index, output_script = nil, opts: {}, hash_type: SIGHASH_TYPE[:all],
|
198
|
+
sig_version: :base, amount: nil, skip_separator_index: 0, prevouts: [])
|
200
199
|
raise ArgumentError, 'input_index must be specified.' unless input_index
|
201
200
|
raise ArgumentError, 'does not exist input corresponding to input_index.' if input_index >= inputs.size
|
202
|
-
raise ArgumentError, 'script_pubkey must be specified.'
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
201
|
+
raise ArgumentError, 'script_pubkey must be specified.' if [:base, :witness_v0].include?(sig_version) && output_script.nil?
|
202
|
+
|
203
|
+
opts[:amount] = amount if amount
|
204
|
+
opts[:skip_separator_index] = skip_separator_index
|
205
|
+
opts[:sig_version] = sig_version
|
206
|
+
opts[:script_code] = output_script
|
207
|
+
opts[:prevouts] = prevouts
|
208
|
+
opts[:last_code_separator_pos] ||= 0xffffffff
|
209
|
+
sig_hash_gen = SigHashGenerator.load(sig_version)
|
210
|
+
sig_hash_gen.generate(self, input_index, hash_type, opts)
|
211
211
|
end
|
212
212
|
|
213
213
|
# verify input signature.
|
@@ -215,7 +215,9 @@ module Bitcoin
|
|
215
215
|
# @param [Bitcoin::Script] script_pubkey the script pubkey for target input.
|
216
216
|
# @param [Integer] amount the amount of bitcoin, require for witness program only.
|
217
217
|
# @param [Array] flags the flags used when execute script interpreter.
|
218
|
-
|
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: [])
|
219
221
|
script_sig = inputs[input_index].script_sig
|
220
222
|
has_witness = inputs[input_index].has_witness?
|
221
223
|
|
@@ -225,8 +227,8 @@ module Bitcoin
|
|
225
227
|
script_pubkey = redeem_script if redeem_script.p2wpkh?
|
226
228
|
end
|
227
229
|
|
228
|
-
if has_witness
|
229
|
-
verify_input_sig_for_witness(input_index, script_pubkey, amount, flags)
|
230
|
+
if has_witness
|
231
|
+
verify_input_sig_for_witness(input_index, script_pubkey, amount, flags, prevouts)
|
230
232
|
else
|
231
233
|
verify_input_sig_for_legacy(input_index, script_pubkey, flags)
|
232
234
|
end
|
@@ -249,73 +251,6 @@ module Bitcoin
|
|
249
251
|
|
250
252
|
private
|
251
253
|
|
252
|
-
# generate sighash with legacy format
|
253
|
-
def sighash_for_legacy(index, script_code, hash_type)
|
254
|
-
ins = inputs.map.with_index do |i, idx|
|
255
|
-
if idx == index
|
256
|
-
i.to_payload(script_code.delete_opcode(Bitcoin::Opcodes::OP_CODESEPARATOR))
|
257
|
-
else
|
258
|
-
case hash_type & 0x1f
|
259
|
-
when SIGHASH_TYPE[:none], SIGHASH_TYPE[:single]
|
260
|
-
i.to_payload(Bitcoin::Script.new, 0)
|
261
|
-
else
|
262
|
-
i.to_payload(Bitcoin::Script.new)
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
outs = outputs.map(&:to_payload)
|
268
|
-
out_size = Bitcoin.pack_var_int(outputs.size)
|
269
|
-
|
270
|
-
case hash_type & 0x1f
|
271
|
-
when SIGHASH_TYPE[:none]
|
272
|
-
outs = ''
|
273
|
-
out_size = Bitcoin.pack_var_int(0)
|
274
|
-
when SIGHASH_TYPE[:single]
|
275
|
-
return "\x01".ljust(32, "\x00") if index >= outputs.size
|
276
|
-
outs = outputs[0...(index + 1)].map.with_index { |o, idx| (idx == index) ? o.to_payload : o.to_empty_payload }.join
|
277
|
-
out_size = Bitcoin.pack_var_int(index + 1)
|
278
|
-
end
|
279
|
-
|
280
|
-
if hash_type & SIGHASH_TYPE[:anyonecanpay] != 0
|
281
|
-
ins = [ins[index]]
|
282
|
-
end
|
283
|
-
|
284
|
-
buf = [[version].pack('V'), Bitcoin.pack_var_int(ins.size),
|
285
|
-
ins, out_size, outs, [lock_time, hash_type].pack('VV')].join
|
286
|
-
|
287
|
-
Bitcoin.double_sha256(buf)
|
288
|
-
end
|
289
|
-
|
290
|
-
# generate sighash with BIP-143 format
|
291
|
-
# https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
292
|
-
def sighash_for_witness(index, script_pubkey_or_script_code, hash_type, amount, skip_separator_index)
|
293
|
-
hash_prevouts = Bitcoin.double_sha256(inputs.map{|i|i.out_point.to_payload}.join)
|
294
|
-
hash_sequence = Bitcoin.double_sha256(inputs.map{|i|[i.sequence].pack('V')}.join)
|
295
|
-
outpoint = inputs[index].out_point.to_payload
|
296
|
-
amount = [amount].pack('Q')
|
297
|
-
nsequence = [inputs[index].sequence].pack('V')
|
298
|
-
hash_outputs = Bitcoin.double_sha256(outputs.map{|o|o.to_payload}.join)
|
299
|
-
|
300
|
-
script_code = script_pubkey_or_script_code.to_script_code(skip_separator_index)
|
301
|
-
|
302
|
-
case (hash_type & 0x1f)
|
303
|
-
when SIGHASH_TYPE[:single]
|
304
|
-
hash_outputs = index >= outputs.size ? "\x00".ljust(32, "\x00") : Bitcoin.double_sha256(outputs[index].to_payload)
|
305
|
-
hash_sequence = "\x00".ljust(32, "\x00")
|
306
|
-
when SIGHASH_TYPE[:none]
|
307
|
-
hash_sequence = hash_outputs = "\x00".ljust(32, "\x00")
|
308
|
-
end
|
309
|
-
|
310
|
-
if (hash_type & SIGHASH_TYPE[:anyonecanpay]) != 0
|
311
|
-
hash_prevouts = hash_sequence ="\x00".ljust(32, "\x00")
|
312
|
-
end
|
313
|
-
hash_type |= (Bitcoin.chain_params.fork_id << 8) if Bitcoin.chain_params.fork_chain?
|
314
|
-
buf = [ [version].pack('V'), hash_prevouts, hash_sequence, outpoint,
|
315
|
-
script_code ,amount, nsequence, hash_outputs, [@lock_time, hash_type].pack('VV')].join
|
316
|
-
Bitcoin.double_sha256(buf)
|
317
|
-
end
|
318
|
-
|
319
254
|
# verify input signature for legacy tx.
|
320
255
|
def verify_input_sig_for_legacy(input_index, script_pubkey, flags)
|
321
256
|
script_sig = inputs[input_index].script_sig
|
@@ -326,16 +261,11 @@ module Bitcoin
|
|
326
261
|
end
|
327
262
|
|
328
263
|
# verify input signature for witness tx.
|
329
|
-
def verify_input_sig_for_witness(input_index, script_pubkey, amount, flags)
|
330
|
-
|
331
|
-
flags |= SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
|
332
|
-
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)
|
333
266
|
interpreter = Bitcoin::ScriptInterpreter.new(checker: checker, flags: flags)
|
334
267
|
i = inputs[input_index]
|
335
|
-
|
336
|
-
script_sig = i.script_sig
|
337
|
-
witness = i.script_witness
|
338
|
-
interpreter.verify_script(script_sig, script_pubkey, witness)
|
268
|
+
interpreter.verify_script(i.script_sig, script_pubkey, i.script_witness)
|
339
269
|
end
|
340
270
|
|
341
271
|
end
|
data/lib/bitcoin/tx_in.rb
CHANGED
@@ -37,13 +37,12 @@ module Bitcoin
|
|
37
37
|
hash, index = buf.read(36).unpack('a32V')
|
38
38
|
i.out_point = OutPoint.new(hash.bth, index)
|
39
39
|
sig_length = Bitcoin.unpack_var_int_from_io(buf)
|
40
|
-
|
41
|
-
|
42
|
-
i.script_sig.chunks[0] = sig
|
40
|
+
if sig_length == 0
|
41
|
+
i.script_sig = Bitcoin::Script.new
|
43
42
|
else
|
44
|
-
i.script_sig = Script.parse_from_payload(
|
43
|
+
i.script_sig = Script.parse_from_payload(buf.read(sig_length))
|
45
44
|
end
|
46
|
-
i.sequence = buf.read(4).
|
45
|
+
i.sequence = buf.read(4).unpack1('V')
|
47
46
|
i
|
48
47
|
end
|
49
48
|
|
data/lib/bitcoin/tx_out.rb
CHANGED
@@ -18,14 +18,13 @@ module Bitcoin
|
|
18
18
|
|
19
19
|
def self.parse_from_payload(payload)
|
20
20
|
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
21
|
-
value = buf.read(8).
|
21
|
+
value = buf.read(8).unpack1('q')
|
22
22
|
script_size = Bitcoin.unpack_var_int_from_io(buf)
|
23
23
|
new(value: value, script_pubkey: Script.parse_from_payload(buf.read(script_size)))
|
24
24
|
end
|
25
25
|
|
26
26
|
def to_payload
|
27
|
-
|
28
|
-
[value].pack('Q') << Bitcoin.pack_var_int(s.length) << s
|
27
|
+
[value].pack('Q') << script_pubkey.to_payload(true)
|
29
28
|
end
|
30
29
|
|
31
30
|
def to_empty_payload
|
data/lib/bitcoin/util.rb
CHANGED
@@ -33,7 +33,7 @@ module Bitcoin
|
|
33
33
|
|
34
34
|
# @return an integer for a valid payload, otherwise nil
|
35
35
|
def unpack_var_int(payload)
|
36
|
-
case payload.
|
36
|
+
case payload.unpack1('C')
|
37
37
|
when 0xfd
|
38
38
|
payload.unpack('xva*')
|
39
39
|
when 0xfe
|
@@ -47,14 +47,14 @@ module Bitcoin
|
|
47
47
|
|
48
48
|
# @return an integer for a valid payload, otherwise nil
|
49
49
|
def unpack_var_int_from_io(buf)
|
50
|
-
uchar = buf.read(1)&.
|
50
|
+
uchar = buf.read(1)&.unpack1('C')
|
51
51
|
case uchar
|
52
52
|
when 0xfd
|
53
|
-
buf.read(2)&.
|
53
|
+
buf.read(2)&.unpack1('v')
|
54
54
|
when 0xfe
|
55
|
-
buf.read(4)&.
|
55
|
+
buf.read(4)&.unpack1('V')
|
56
56
|
when 0xff
|
57
|
-
buf.read(8)&.
|
57
|
+
buf.read(8)&.unpack1('Q')
|
58
58
|
else
|
59
59
|
uchar
|
60
60
|
end
|
@@ -79,7 +79,7 @@ module Bitcoin
|
|
79
79
|
|
80
80
|
# byte convert to the sequence of bits packed eight in a byte with the least significant bit first.
|
81
81
|
def byte_to_bit(byte)
|
82
|
-
byte.
|
82
|
+
byte.unpack1('b*')
|
83
83
|
end
|
84
84
|
|
85
85
|
# padding zero to the left of binary string until bytesize.
|
@@ -96,6 +96,15 @@ module Bitcoin
|
|
96
96
|
Digest::RMD160.hexdigest(Digest::SHA256.digest(hex.htb))
|
97
97
|
end
|
98
98
|
|
99
|
+
# Generate tagged hash value.
|
100
|
+
# @param [String] tag tag value.
|
101
|
+
# @param [String] msg the message to be hashed.
|
102
|
+
# @return [String] the hash value with binary format.
|
103
|
+
def tagged_hash(tag, msg)
|
104
|
+
tag_hash = Digest::SHA256.digest(tag)
|
105
|
+
Digest::SHA256.digest(tag_hash + tag_hash + msg)
|
106
|
+
end
|
107
|
+
|
99
108
|
# encode Base58 check address.
|
100
109
|
# @param [String] hex the address payload.
|
101
110
|
# @param [String] addr_version the address version for P2PKH and P2SH.
|
@@ -142,4 +151,11 @@ module Bitcoin
|
|
142
151
|
|
143
152
|
end
|
144
153
|
|
154
|
+
module HexConverter
|
155
|
+
|
156
|
+
def to_hex
|
157
|
+
to_payload.bth
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
145
161
|
end
|
data/lib/bitcoin/version.rb
CHANGED
data/lib/bitcoin/wallet.rb
CHANGED
@@ -3,6 +3,7 @@ module Bitcoin
|
|
3
3
|
|
4
4
|
# the account in BIP-44
|
5
5
|
class Account
|
6
|
+
include Bitcoin::HexConverter
|
6
7
|
|
7
8
|
PURPOSE_TYPE = {legacy: 44, nested_witness: 49, native_segwit: 84}
|
8
9
|
|
@@ -42,7 +43,7 @@ module Bitcoin
|
|
42
43
|
|
43
44
|
def to_payload
|
44
45
|
payload = account_key.to_payload
|
45
|
-
payload << Bitcoin.pack_var_string(name.
|
46
|
+
payload << Bitcoin.pack_var_string(name.unpack1('H*').htb)
|
46
47
|
payload << [purpose, index, receive_depth, change_depth, lookahead].pack('I*')
|
47
48
|
payload
|
48
49
|
end
|
data/lib/bitcoin/wallet/base.rb
CHANGED
@@ -20,14 +20,14 @@ module Bitcoin
|
|
20
20
|
# @param [String] wallet_id new wallet id.
|
21
21
|
# @param [String] path_prefix wallet file path prefix.
|
22
22
|
# @return [Bitcoin::Wallet::Base] the wallet
|
23
|
-
def self.create(wallet_id = 1, path_prefix = default_path_prefix)
|
23
|
+
def self.create(wallet_id = 1, path_prefix = default_path_prefix, purpose = Account::PURPOSE_TYPE[:native_segwit])
|
24
24
|
raise ArgumentError, "wallet_id : #{wallet_id} already exist." if self.exist?(wallet_id, path_prefix)
|
25
25
|
w = self.new(wallet_id, path_prefix)
|
26
26
|
# generate seed
|
27
27
|
raise RuntimeError, 'the seed already exist.' if w.db.registered_master?
|
28
28
|
master = Bitcoin::Wallet::MasterKey.generate
|
29
29
|
w.db.register_master_key(master)
|
30
|
-
w.create_account('Default')
|
30
|
+
w.create_account(purpose, 'Default')
|
31
31
|
w
|
32
32
|
end
|
33
33
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Wallet
|
3
|
+
class Utxo
|
4
|
+
attr_reader :tx_hash
|
5
|
+
attr_reader :index
|
6
|
+
attr_reader :block_height
|
7
|
+
attr_reader :value
|
8
|
+
attr_reader :script_pubkey
|
9
|
+
|
10
|
+
def initialize(tx_hash, index, value, script_pubkey, block_height = nil)
|
11
|
+
@tx_hash = tx_hash
|
12
|
+
@index = index
|
13
|
+
@block_height = block_height
|
14
|
+
@value = value
|
15
|
+
@script_pubkey = script_pubkey
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parse_from_payload(payload)
|
19
|
+
return nil if payload.nil?
|
20
|
+
|
21
|
+
tx_hash, index, block_height, value, payload = payload.unpack('H64VVQa*')
|
22
|
+
|
23
|
+
buf = StringIO.new(payload)
|
24
|
+
script_size = Bitcoin.unpack_var_int_from_io(buf)
|
25
|
+
script_pubkey = Bitcoin::Script.parse_from_payload(buf.read(script_size));
|
26
|
+
new(tx_hash, index, value, script_pubkey, block_height == 0 ? nil : block_height )
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_payload
|
30
|
+
payload = [tx_hash, index, block_height.nil? ? 0 : block_height, value].pack('H64VVQ')
|
31
|
+
s = script_pubkey.to_payload
|
32
|
+
payload << Bitcoin.pack_var_int(s.length) << s
|
33
|
+
payload
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
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: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-29 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
|
@@ -137,7 +137,7 @@ dependencies:
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
140
|
+
name: iniparse
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
@@ -151,7 +151,7 @@ dependencies:
|
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
154
|
+
name: siphash
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
@@ -165,61 +165,61 @@ dependencies:
|
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
168
|
+
name: protobuf
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- -
|
171
|
+
- - '='
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
173
|
+
version: 3.8.5
|
174
174
|
type: :runtime
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- -
|
178
|
+
- - '='
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
180
|
+
version: 3.8.5
|
181
181
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
182
|
+
name: json_pure
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
185
|
+
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: 3.
|
187
|
+
version: 2.3.1
|
188
188
|
type: :runtime
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- -
|
192
|
+
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version: 3.
|
194
|
+
version: 2.3.1
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
196
|
+
name: bip-schnorr
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
198
198
|
requirements:
|
199
199
|
- - ">="
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
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:
|
208
|
+
version: 0.4.0
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
210
|
+
name: base32
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
212
212
|
requirements:
|
213
|
-
- - "
|
213
|
+
- - ">="
|
214
214
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
215
|
+
version: 0.3.4
|
216
216
|
type: :runtime
|
217
217
|
prerelease: false
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
|
-
- - "
|
220
|
+
- - ">="
|
221
221
|
- !ruby/object:Gem::Version
|
222
|
-
version:
|
222
|
+
version: 0.3.4
|
223
223
|
- !ruby/object:Gem::Dependency
|
224
224
|
name: leveldb-native
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -252,16 +252,16 @@ dependencies:
|
|
252
252
|
name: rake
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
254
254
|
requirements:
|
255
|
-
- - "
|
255
|
+
- - ">="
|
256
256
|
- !ruby/object:Gem::Version
|
257
|
-
version:
|
257
|
+
version: 12.3.3
|
258
258
|
type: :development
|
259
259
|
prerelease: false
|
260
260
|
version_requirements: !ruby/object:Gem::Requirement
|
261
261
|
requirements:
|
262
|
-
- - "
|
262
|
+
- - ">="
|
263
263
|
- !ruby/object:Gem::Version
|
264
|
-
version:
|
264
|
+
version: 12.3.3
|
265
265
|
- !ruby/object:Gem::Dependency
|
266
266
|
name: rspec
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
@@ -290,7 +290,35 @@ dependencies:
|
|
290
290
|
- - ">="
|
291
291
|
- !ruby/object:Gem::Version
|
292
292
|
version: '0'
|
293
|
-
|
293
|
+
- !ruby/object:Gem::Dependency
|
294
|
+
name: webmock
|
295
|
+
requirement: !ruby/object:Gem::Requirement
|
296
|
+
requirements:
|
297
|
+
- - ">="
|
298
|
+
- !ruby/object:Gem::Version
|
299
|
+
version: 3.11.1
|
300
|
+
type: :development
|
301
|
+
prerelease: false
|
302
|
+
version_requirements: !ruby/object:Gem::Requirement
|
303
|
+
requirements:
|
304
|
+
- - ">="
|
305
|
+
- !ruby/object:Gem::Version
|
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
|
321
|
+
description: The implementation of Bitcoin Protocol for Ruby.
|
294
322
|
email:
|
295
323
|
- azuchi@chaintope.com
|
296
324
|
executables:
|
@@ -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
|
@@ -317,6 +346,7 @@ files:
|
|
317
346
|
- exe/bitcoinrbd
|
318
347
|
- lib/bitcoin.rb
|
319
348
|
- lib/bitcoin/base58.rb
|
349
|
+
- lib/bitcoin/bip85_entropy.rb
|
320
350
|
- lib/bitcoin/bit_stream.rb
|
321
351
|
- lib/bitcoin/block.rb
|
322
352
|
- lib/bitcoin/block_filter.rb
|
@@ -325,9 +355,15 @@ files:
|
|
325
355
|
- lib/bitcoin/chain_params.rb
|
326
356
|
- lib/bitcoin/chainparams/mainnet.yml
|
327
357
|
- lib/bitcoin/chainparams/regtest.yml
|
358
|
+
- lib/bitcoin/chainparams/signet.yml
|
328
359
|
- lib/bitcoin/chainparams/testnet.yml
|
329
360
|
- lib/bitcoin/constants.rb
|
330
361
|
- lib/bitcoin/descriptor.rb
|
362
|
+
- lib/bitcoin/errors.rb
|
363
|
+
- lib/bitcoin/ext.rb
|
364
|
+
- lib/bitcoin/ext/array_ext.rb
|
365
|
+
- lib/bitcoin/ext/ecdsa.rb
|
366
|
+
- lib/bitcoin/ext/json_parser.rb
|
331
367
|
- lib/bitcoin/ext_key.rb
|
332
368
|
- lib/bitcoin/gcs_filter.rb
|
333
369
|
- lib/bitcoin/key.rb
|
@@ -336,11 +372,16 @@ files:
|
|
336
372
|
- lib/bitcoin/merkle_tree.rb
|
337
373
|
- lib/bitcoin/message.rb
|
338
374
|
- lib/bitcoin/message/addr.rb
|
375
|
+
- lib/bitcoin/message/addr_v2.rb
|
339
376
|
- lib/bitcoin/message/base.rb
|
340
377
|
- lib/bitcoin/message/block.rb
|
341
378
|
- lib/bitcoin/message/block_transaction_request.rb
|
342
379
|
- lib/bitcoin/message/block_transactions.rb
|
343
380
|
- lib/bitcoin/message/block_txn.rb
|
381
|
+
- lib/bitcoin/message/cf_parser.rb
|
382
|
+
- lib/bitcoin/message/cfcheckpt.rb
|
383
|
+
- lib/bitcoin/message/cfheaders.rb
|
384
|
+
- lib/bitcoin/message/cfilter.rb
|
344
385
|
- lib/bitcoin/message/cmpct_block.rb
|
345
386
|
- lib/bitcoin/message/error.rb
|
346
387
|
- lib/bitcoin/message/fee_filter.rb
|
@@ -350,6 +391,9 @@ files:
|
|
350
391
|
- lib/bitcoin/message/get_addr.rb
|
351
392
|
- lib/bitcoin/message/get_block_txn.rb
|
352
393
|
- lib/bitcoin/message/get_blocks.rb
|
394
|
+
- lib/bitcoin/message/get_cfcheckpt.rb
|
395
|
+
- lib/bitcoin/message/get_cfheaders.rb
|
396
|
+
- lib/bitcoin/message/get_cfilters.rb
|
353
397
|
- lib/bitcoin/message/get_data.rb
|
354
398
|
- lib/bitcoin/message/get_headers.rb
|
355
399
|
- lib/bitcoin/message/header_and_short_ids.rb
|
@@ -366,11 +410,13 @@ files:
|
|
366
410
|
- lib/bitcoin/message/pong.rb
|
367
411
|
- lib/bitcoin/message/prefilled_tx.rb
|
368
412
|
- lib/bitcoin/message/reject.rb
|
413
|
+
- lib/bitcoin/message/send_addr_v2.rb
|
369
414
|
- lib/bitcoin/message/send_cmpct.rb
|
370
415
|
- lib/bitcoin/message/send_headers.rb
|
371
416
|
- lib/bitcoin/message/tx.rb
|
372
417
|
- lib/bitcoin/message/ver_ack.rb
|
373
418
|
- lib/bitcoin/message/version.rb
|
419
|
+
- lib/bitcoin/message_sign.rb
|
374
420
|
- lib/bitcoin/mnemonic.rb
|
375
421
|
- lib/bitcoin/mnemonic/wordlist/chinese_simplified.txt
|
376
422
|
- lib/bitcoin/mnemonic/wordlist/chinese_traditional.txt
|
@@ -391,6 +437,7 @@ files:
|
|
391
437
|
- lib/bitcoin/node/spv.rb
|
392
438
|
- lib/bitcoin/opcodes.rb
|
393
439
|
- lib/bitcoin/out_point.rb
|
440
|
+
- lib/bitcoin/payment_code.rb
|
394
441
|
- lib/bitcoin/payments.rb
|
395
442
|
- lib/bitcoin/payments/output.pb.rb
|
396
443
|
- lib/bitcoin/payments/payment.pb.rb
|
@@ -416,7 +463,9 @@ files:
|
|
416
463
|
- lib/bitcoin/script_witness.rb
|
417
464
|
- lib/bitcoin/secp256k1.rb
|
418
465
|
- lib/bitcoin/secp256k1/native.rb
|
466
|
+
- lib/bitcoin/secp256k1/rfc6979.rb
|
419
467
|
- lib/bitcoin/secp256k1/ruby.rb
|
468
|
+
- lib/bitcoin/sighash_generator.rb
|
420
469
|
- lib/bitcoin/slip39.rb
|
421
470
|
- lib/bitcoin/slip39/share.rb
|
422
471
|
- lib/bitcoin/slip39/sss.rb
|
@@ -426,6 +475,10 @@ files:
|
|
426
475
|
- lib/bitcoin/store/db.rb
|
427
476
|
- lib/bitcoin/store/db/level_db.rb
|
428
477
|
- lib/bitcoin/store/spv_chain.rb
|
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
|
429
482
|
- lib/bitcoin/tx.rb
|
430
483
|
- lib/bitcoin/tx_in.rb
|
431
484
|
- lib/bitcoin/tx_out.rb
|
@@ -437,6 +490,7 @@ files:
|
|
437
490
|
- lib/bitcoin/wallet/base.rb
|
438
491
|
- lib/bitcoin/wallet/db.rb
|
439
492
|
- lib/bitcoin/wallet/master_key.rb
|
493
|
+
- lib/bitcoin/wallet/utxo.rb
|
440
494
|
- lib/openassets.rb
|
441
495
|
- lib/openassets/marker_output.rb
|
442
496
|
- lib/openassets/payload.rb
|
@@ -460,8 +514,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
460
514
|
- !ruby/object:Gem::Version
|
461
515
|
version: '0'
|
462
516
|
requirements: []
|
463
|
-
rubygems_version: 3.
|
517
|
+
rubygems_version: 3.2.3
|
464
518
|
signing_key:
|
465
519
|
specification_version: 4
|
466
|
-
summary:
|
520
|
+
summary: The implementation of Bitcoin Protocol for Ruby.
|
467
521
|
test_files: []
|