bitcoinrb 0.5.0 → 0.6.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/.ruby-version +1 -1
- data/.travis.yml +5 -4
- data/README.md +10 -0
- data/bitcoinrb.gemspec +4 -4
- data/lib/bitcoin.rb +29 -16
- data/lib/bitcoin/block_filter.rb +14 -0
- data/lib/bitcoin/chain_params.rb +9 -0
- data/lib/bitcoin/chainparams/signet.yml +39 -0
- data/lib/bitcoin/constants.rb +43 -3
- data/lib/bitcoin/descriptor.rb +1 -1
- data/lib/bitcoin/errors.rb +19 -0
- data/lib/bitcoin/ext/ecdsa.rb +31 -0
- data/lib/bitcoin/ext_key.rb +35 -19
- data/lib/bitcoin/key.rb +43 -26
- data/lib/bitcoin/message/cfcheckpt.rb +2 -2
- data/lib/bitcoin/message/cfheaders.rb +1 -1
- data/lib/bitcoin/message/cfilter.rb +1 -1
- data/lib/bitcoin/message/fee_filter.rb +1 -1
- data/lib/bitcoin/message/filter_load.rb +3 -3
- 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 +3 -3
- data/lib/bitcoin/message/ping.rb +1 -1
- data/lib/bitcoin/message/pong.rb +1 -1
- data/lib/bitcoin/message/send_cmpct.rb +2 -2
- data/lib/bitcoin/mnemonic.rb +2 -2
- data/lib/bitcoin/network/peer_discovery.rb +1 -3
- data/lib/bitcoin/node/configuration.rb +3 -1
- data/lib/bitcoin/node/spv.rb +8 -0
- data/lib/bitcoin/opcodes.rb +14 -1
- data/lib/bitcoin/payment_code.rb +2 -2
- data/lib/bitcoin/psbt/hd_key_path.rb +1 -1
- data/lib/bitcoin/psbt/input.rb +3 -3
- data/lib/bitcoin/psbt/output.rb +1 -1
- data/lib/bitcoin/psbt/tx.rb +4 -4
- data/lib/bitcoin/rpc/bitcoin_core_client.rb +1 -1
- data/lib/bitcoin/script/script.rb +52 -19
- data/lib/bitcoin/script/script_error.rb +27 -1
- data/lib/bitcoin/script/script_interpreter.rb +161 -62
- data/lib/bitcoin/script/tx_checker.rb +64 -14
- data/lib/bitcoin/secp256k1/native.rb +138 -25
- data/lib/bitcoin/secp256k1/ruby.rb +78 -19
- data/lib/bitcoin/sighash_generator.rb +156 -0
- data/lib/bitcoin/tx.rb +13 -80
- data/lib/bitcoin/tx_in.rb +1 -1
- data/lib/bitcoin/tx_out.rb +2 -3
- data/lib/bitcoin/util.rb +15 -6
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet/account.rb +1 -1
- metadata +19 -15
data/lib/bitcoin/tx.rb
CHANGED
@@ -36,13 +36,13 @@ module Bitcoin
|
|
36
36
|
def self.parse_from_payload(payload, non_witness: false)
|
37
37
|
buf = payload.is_a?(String) ? StringIO.new(payload) : payload
|
38
38
|
tx = new
|
39
|
-
tx.version = buf.read(4).
|
39
|
+
tx.version = buf.read(4).unpack1('V')
|
40
40
|
|
41
41
|
in_count = Bitcoin.unpack_var_int_from_io(buf)
|
42
42
|
witness = false
|
43
43
|
if in_count.zero? && !non_witness
|
44
44
|
tx.marker = 0
|
45
|
-
tx.flag = buf.read(1).
|
45
|
+
tx.flag = buf.read(1).unpack1('c')
|
46
46
|
if tx.flag.zero?
|
47
47
|
buf.pos -= 1
|
48
48
|
else
|
@@ -66,7 +66,7 @@ module Bitcoin
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
tx.lock_time = buf.read(4).
|
69
|
+
tx.lock_time = buf.read(4).unpack1('V')
|
70
70
|
|
71
71
|
tx
|
72
72
|
end
|
@@ -188,22 +188,22 @@ module Bitcoin
|
|
188
188
|
# @param [Integer] input_index input index.
|
189
189
|
# @param [Integer] hash_type signature hash type
|
190
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)
|
191
192
|
# @param [Integer] amount bitcoin amount locked in input. required for witness input only.
|
192
193
|
# @param [Integer] skip_separator_index If output_script is P2WSH and output_script contains any OP_CODESEPARATOR,
|
193
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.
|
194
|
-
def sighash_for_input(input_index, output_script, hash_type: SIGHASH_TYPE[:all],
|
195
|
+
def sighash_for_input(input_index, output_script = nil, opts: {}, hash_type: SIGHASH_TYPE[:all],
|
195
196
|
sig_version: :base, amount: nil, skip_separator_index: 0)
|
196
197
|
raise ArgumentError, 'input_index must be specified.' unless input_index
|
197
198
|
raise ArgumentError, 'does not exist input corresponding to input_index.' if input_index >= inputs.size
|
198
|
-
raise ArgumentError, 'script_pubkey must be specified.'
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
end
|
199
|
+
raise ArgumentError, 'script_pubkey must be specified.' if [:base, :witness_v0].include?(sig_version) && output_script.nil?
|
200
|
+
|
201
|
+
opts[:amount] = amount if amount
|
202
|
+
opts[:skip_separator_index] = skip_separator_index
|
203
|
+
opts[:sig_version] = sig_version
|
204
|
+
opts[:script_code] = output_script
|
205
|
+
sig_hash_gen = SigHashGenerator.load(sig_version)
|
206
|
+
sig_hash_gen.generate(self, input_index, hash_type, opts)
|
207
207
|
end
|
208
208
|
|
209
209
|
# verify input signature.
|
@@ -245,73 +245,6 @@ module Bitcoin
|
|
245
245
|
|
246
246
|
private
|
247
247
|
|
248
|
-
# generate sighash with legacy format
|
249
|
-
def sighash_for_legacy(index, script_code, hash_type)
|
250
|
-
ins = inputs.map.with_index do |i, idx|
|
251
|
-
if idx == index
|
252
|
-
i.to_payload(script_code.delete_opcode(Bitcoin::Opcodes::OP_CODESEPARATOR))
|
253
|
-
else
|
254
|
-
case hash_type & 0x1f
|
255
|
-
when SIGHASH_TYPE[:none], SIGHASH_TYPE[:single]
|
256
|
-
i.to_payload(Bitcoin::Script.new, 0)
|
257
|
-
else
|
258
|
-
i.to_payload(Bitcoin::Script.new)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
outs = outputs.map(&:to_payload)
|
264
|
-
out_size = Bitcoin.pack_var_int(outputs.size)
|
265
|
-
|
266
|
-
case hash_type & 0x1f
|
267
|
-
when SIGHASH_TYPE[:none]
|
268
|
-
outs = ''
|
269
|
-
out_size = Bitcoin.pack_var_int(0)
|
270
|
-
when SIGHASH_TYPE[:single]
|
271
|
-
return "\x01".ljust(32, "\x00") if index >= outputs.size
|
272
|
-
outs = outputs[0...(index + 1)].map.with_index { |o, idx| (idx == index) ? o.to_payload : o.to_empty_payload }.join
|
273
|
-
out_size = Bitcoin.pack_var_int(index + 1)
|
274
|
-
end
|
275
|
-
|
276
|
-
if hash_type & SIGHASH_TYPE[:anyonecanpay] != 0
|
277
|
-
ins = [ins[index]]
|
278
|
-
end
|
279
|
-
|
280
|
-
buf = [[version].pack('V'), Bitcoin.pack_var_int(ins.size),
|
281
|
-
ins, out_size, outs, [lock_time, hash_type].pack('VV')].join
|
282
|
-
|
283
|
-
Bitcoin.double_sha256(buf)
|
284
|
-
end
|
285
|
-
|
286
|
-
# generate sighash with BIP-143 format
|
287
|
-
# https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
|
288
|
-
def sighash_for_witness(index, script_pubkey_or_script_code, hash_type, amount, skip_separator_index)
|
289
|
-
hash_prevouts = Bitcoin.double_sha256(inputs.map{|i|i.out_point.to_payload}.join)
|
290
|
-
hash_sequence = Bitcoin.double_sha256(inputs.map{|i|[i.sequence].pack('V')}.join)
|
291
|
-
outpoint = inputs[index].out_point.to_payload
|
292
|
-
amount = [amount].pack('Q')
|
293
|
-
nsequence = [inputs[index].sequence].pack('V')
|
294
|
-
hash_outputs = Bitcoin.double_sha256(outputs.map{|o|o.to_payload}.join)
|
295
|
-
|
296
|
-
script_code = script_pubkey_or_script_code.to_script_code(skip_separator_index)
|
297
|
-
|
298
|
-
case (hash_type & 0x1f)
|
299
|
-
when SIGHASH_TYPE[:single]
|
300
|
-
hash_outputs = index >= outputs.size ? "\x00".ljust(32, "\x00") : Bitcoin.double_sha256(outputs[index].to_payload)
|
301
|
-
hash_sequence = "\x00".ljust(32, "\x00")
|
302
|
-
when SIGHASH_TYPE[:none]
|
303
|
-
hash_sequence = hash_outputs = "\x00".ljust(32, "\x00")
|
304
|
-
end
|
305
|
-
|
306
|
-
if (hash_type & SIGHASH_TYPE[:anyonecanpay]) != 0
|
307
|
-
hash_prevouts = hash_sequence ="\x00".ljust(32, "\x00")
|
308
|
-
end
|
309
|
-
|
310
|
-
buf = [ [version].pack('V'), hash_prevouts, hash_sequence, outpoint,
|
311
|
-
script_code ,amount, nsequence, hash_outputs, [@lock_time, hash_type].pack('VV')].join
|
312
|
-
Bitcoin.double_sha256(buf)
|
313
|
-
end
|
314
|
-
|
315
248
|
# verify input signature for legacy tx.
|
316
249
|
def verify_input_sig_for_legacy(input_index, script_pubkey, flags)
|
317
250
|
script_sig = inputs[input_index].script_sig
|
data/lib/bitcoin/tx_in.rb
CHANGED
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.
|
data/lib/bitcoin/version.rb
CHANGED
@@ -43,7 +43,7 @@ module Bitcoin
|
|
43
43
|
|
44
44
|
def to_payload
|
45
45
|
payload = account_key.to_payload
|
46
|
-
payload << Bitcoin.pack_var_string(name.
|
46
|
+
payload << Bitcoin.pack_var_string(name.unpack1('H*').htb)
|
47
47
|
payload << [purpose, index, receive_depth, change_depth, lookahead].pack('I*')
|
48
48
|
payload
|
49
49
|
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.6.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-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -179,33 +179,33 @@ dependencies:
|
|
179
179
|
- !ruby/object:Gem::Version
|
180
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:
|
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:
|
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.3.2
|
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.3.2
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: leveldb-native
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -280,17 +280,17 @@ dependencies:
|
|
280
280
|
name: webmock
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
282
282
|
requirements:
|
283
|
-
- - "
|
283
|
+
- - ">="
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version:
|
285
|
+
version: 3.11.1
|
286
286
|
type: :development
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
|
-
- - "
|
290
|
+
- - ">="
|
291
291
|
- !ruby/object:Gem::Version
|
292
|
-
version:
|
293
|
-
description:
|
292
|
+
version: 3.11.1
|
293
|
+
description: The implementation of Bitcoin Protocol for Ruby.
|
294
294
|
email:
|
295
295
|
- azuchi@chaintope.com
|
296
296
|
executables:
|
@@ -326,10 +326,13 @@ files:
|
|
326
326
|
- lib/bitcoin/chain_params.rb
|
327
327
|
- lib/bitcoin/chainparams/mainnet.yml
|
328
328
|
- lib/bitcoin/chainparams/regtest.yml
|
329
|
+
- lib/bitcoin/chainparams/signet.yml
|
329
330
|
- lib/bitcoin/chainparams/testnet.yml
|
330
331
|
- lib/bitcoin/constants.rb
|
331
332
|
- lib/bitcoin/descriptor.rb
|
333
|
+
- lib/bitcoin/errors.rb
|
332
334
|
- lib/bitcoin/ext.rb
|
335
|
+
- lib/bitcoin/ext/ecdsa.rb
|
333
336
|
- lib/bitcoin/ext/json_parser.rb
|
334
337
|
- lib/bitcoin/ext_key.rb
|
335
338
|
- lib/bitcoin/gcs_filter.rb
|
@@ -429,6 +432,7 @@ files:
|
|
429
432
|
- lib/bitcoin/secp256k1/native.rb
|
430
433
|
- lib/bitcoin/secp256k1/rfc6979.rb
|
431
434
|
- lib/bitcoin/secp256k1/ruby.rb
|
435
|
+
- lib/bitcoin/sighash_generator.rb
|
432
436
|
- lib/bitcoin/slip39.rb
|
433
437
|
- lib/bitcoin/slip39/share.rb
|
434
438
|
- lib/bitcoin/slip39/sss.rb
|
@@ -474,8 +478,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
474
478
|
- !ruby/object:Gem::Version
|
475
479
|
version: '0'
|
476
480
|
requirements: []
|
477
|
-
rubygems_version: 3.
|
481
|
+
rubygems_version: 3.2.3
|
478
482
|
signing_key:
|
479
483
|
specification_version: 4
|
480
|
-
summary:
|
484
|
+
summary: The implementation of Bitcoin Protocol for Ruby.
|
481
485
|
test_files: []
|