bitcoinrb 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbc1459b87de8addec350661eb84c3a8bd87503eff03d6bad50c329660fc2749
4
- data.tar.gz: ccb70c6d406a1b4f7134c7c8b8f13f536ba8197d3479b4fca635c073cccd6f11
3
+ metadata.gz: 23f677d00426b94e0bdcee887901bb1e89a98c65ae61b0a025c7d95467dcb484
4
+ data.tar.gz: 7426638ec33999d466026a09a91517fe698adc0a55f32db6d416dc3f4ad6a386
5
5
  SHA512:
6
- metadata.gz: 5ed8400e197cb53d7232265b87f201174e60dae37952e075dae4e4f961b41e9967a24fa2998845100212747493a0dc2bd0b03a79ca208a2beb824cfd48f4a9bf
7
- data.tar.gz: 7585bf0a8179d1144a6f6310a63817538075a111ca92a248c2469df962c2fb913f091abffacdf57096cfb183ebe40406080ce807deca3c052c1a63b1934d895c
6
+ metadata.gz: 960aada8b3db4c610a2b206254f878af9c149f81ce42a53a2ebe8441e0a5179964a9a505807ae2b7519349c4a48125397acb20b412cfb84ea59d58957acd84e4
7
+ data.tar.gz: 493c6e06d7fb686dda65fd4bc4075e3716004427beab0cce9e040060711ad4a7197d0fdece2838d130ed6b1b64cdc94a37957a8354d7629bf9bd68fc02d326e4
@@ -19,7 +19,7 @@ jobs:
19
19
  runs-on: ubuntu-latest
20
20
  strategy:
21
21
  matrix:
22
- ruby-version: ['2.6', '2.7', '3.0', '3.1']
22
+ ruby-version: ['3.0', '3.1', '3.2']
23
23
 
24
24
  steps:
25
25
  - uses: actions/checkout@v2
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.1.2
1
+ ruby-3.2.0
data/README.md CHANGED
@@ -67,6 +67,8 @@ And then add to your .rb file:
67
67
 
68
68
  ## Usage
69
69
 
70
+ Examples can be found on the [wiki](https://github.com/chaintope/bitcoinrb/wiki).
71
+
70
72
  ### Chain selection
71
73
 
72
74
  The parameters of the blockchain are managed by `Bitcoin::ChainParams`. Switch chain parameters as follows:
data/bitcoinrb.gemspec CHANGED
@@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_runtime_dependency 'ecdsa'
23
+ spec.add_runtime_dependency 'ecdsa_ext', '~> 0.5.0'
24
24
  spec.add_runtime_dependency 'eventmachine'
25
25
  spec.add_runtime_dependency 'murmurhash3'
26
- spec.add_runtime_dependency 'bech32', '~> 1.1.0'
26
+ spec.add_runtime_dependency 'bech32', '>= 1.3.0'
27
27
  spec.add_runtime_dependency 'daemon-spawn'
28
28
  spec.add_runtime_dependency 'thor'
29
29
  spec.add_runtime_dependency 'ffi'
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_runtime_dependency 'siphash'
34
34
  spec.add_runtime_dependency 'protobuf', '3.8.5'
35
35
  spec.add_runtime_dependency 'json_pure', '>= 2.3.1'
36
- spec.add_runtime_dependency 'bip-schnorr', '>= 0.4.0'
36
+ spec.add_runtime_dependency 'bip-schnorr', '>= 0.5.0'
37
37
  spec.add_runtime_dependency 'base32', '>= 0.3.4'
38
38
 
39
39
  # for options
@@ -57,9 +57,8 @@ module Bitcoin
57
57
  SCRIPT_VERIFY_CONST_SCRIPTCODE = (1 << 16) # Making OP_CODESEPARATOR and FindAndDelete fail any non-segwit scripts
58
58
  SCRIPT_VERIFY_TAPROOT = (1 << 17) # Taproot/Tapscript validation (BIPs 341 & 342)
59
59
  SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION = (1 << 18) # Making unknown Taproot leaf versions non-standard
60
- SCRIPT_VERIFY_DISCOURAGE_UNKNOWN_ANNEX = (1 << 19) # Making the use of (unknown) annexes non-standard (currently no annexes are known)
61
- SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1 << 20) # Making unknown OP_SUCCESS non-standard
62
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1 << 21) # Making unknown public key versions (in BIP 342 scripts) non-standard
60
+ SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS = (1 << 19) # Making unknown OP_SUCCESS non-standard
61
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1 << 20) # Making unknown public key versions (in BIP 342 scripts) non-standard
63
62
 
64
63
  MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH
65
64
 
@@ -27,7 +27,8 @@ module Bitcoin
27
27
  l = Bitcoin.hmac_sha512('Bitcoin seed', seed.htb)
28
28
  left = l[0..31].bth.to_i(16)
29
29
  raise 'invalid key' if left >= CURVE_ORDER || left == 0
30
- ext_key.key = Bitcoin::Key.new(priv_key: l[0..31].bth, key_type: Bitcoin::Key::TYPES[:compressed])
30
+ l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
31
+ ext_key.key = Bitcoin::Key.new(priv_key: l_priv.bth, key_type: Bitcoin::Key::TYPES[:compressed])
31
32
  ext_key.chain_code = l[32..-1]
32
33
  ext_key
33
34
  end
@@ -110,8 +111,8 @@ module Bitcoin
110
111
  raise 'invalid key' if left >= CURVE_ORDER
111
112
  child_priv = (left + key.priv_key.to_i(16)) % CURVE_ORDER
112
113
  raise 'invalid key ' if child_priv >= CURVE_ORDER
113
- new_key.key = Bitcoin::Key.new(
114
- priv_key: child_priv.to_even_length_hex.rjust(64, '0'), key_type: key_type)
114
+ child_priv = ECDSA::Format::IntegerOctetString.encode(child_priv, 32)
115
+ new_key.key = Bitcoin::Key.new(priv_key: child_priv.bth, key_type: key_type)
115
116
  new_key.chain_code = l[32..-1]
116
117
  new_key.ver = version
117
118
  new_key
@@ -280,7 +281,8 @@ module Bitcoin
280
281
  l = Bitcoin.hmac_sha512(chain_code, data)
281
282
  left = l[0..31].bth.to_i(16)
282
283
  raise 'invalid key' if left >= CURVE_ORDER
283
- p1 = Bitcoin::Key.new(priv_key: left.to_s(16), key_type: Bitcoin::Key::TYPES[:uncompressed]).to_point
284
+ l_priv = ECDSA::Format::IntegerOctetString.encode(left, 32)
285
+ p1 = Bitcoin::Key.new(priv_key: l_priv.bth, key_type: Bitcoin::Key::TYPES[:uncompressed]).to_point
284
286
  p2 = Bitcoin::Key.new(pubkey: pubkey, key_type: key_type).to_point
285
287
  new_key.pubkey = (p1 + p2).to_hex
286
288
  new_key.chain_code = l[32..-1]
data/lib/bitcoin/key.rb CHANGED
@@ -39,6 +39,7 @@ module Bitcoin
39
39
  @secp256k1_module = Bitcoin.secp_impl
40
40
  @priv_key = priv_key
41
41
  if @priv_key
42
+ raise ArgumentError, 'Private key must be 32 bytes.' unless priv_key.htb.bytesize == 32
42
43
  raise ArgumentError, Errors::Messages::INVALID_PRIV_KEY unless validate_private_key_range(@priv_key)
43
44
  end
44
45
  if pubkey
@@ -6,14 +6,42 @@ module Bitcoin
6
6
 
7
7
  module_function
8
8
 
9
+ FORMAT_LEGACY = :legacy
10
+ FORMAT_SIMPLE = :simple
11
+ FORMAT_FULL = :full
12
+
9
13
  # Sign a message.
10
- # @param [Bitcoin::Key] key Private key to sign with.
11
- # @param [String] message The message to sign.
14
+ # @param [Bitcoin::Key] key Private key to sign.
15
+ # @param [String] message The message to be signed.
16
+ # @param [String] address An address of the key used for signing (required for full or simple format).
17
+ # @param [String] format Format of signature data. Default is +FORMAT_LEGACY+.
18
+ # @param [String] prefix (Optional) Prefix used in legacy format.
12
19
  # @return [String] Signature, base64 encoded.
13
- def sign_message(key, message, prefix: Bitcoin.chain_params.message_magic)
14
- digest = message_hash(message, prefix: prefix)
15
- compact_sig = key.sign_compact(digest)
16
- Base64.strict_encode64(compact_sig)
20
+ def sign_message(key, message, prefix: Bitcoin.chain_params.message_magic, format: FORMAT_LEGACY, address: nil)
21
+ validate_format!(format)
22
+ digest = message_hash(message, prefix: prefix, legacy: format == FORMAT_LEGACY)
23
+ sig = case format
24
+ when FORMAT_LEGACY
25
+ key.sign_compact(digest)
26
+ else
27
+ validate_address!(address)
28
+ addr = Bitcoin::Script.parse_from_addr(address)
29
+ sig_ver, algo = if addr.p2wpkh?
30
+ [:witness_v0, :ecdsa]
31
+ elsif addr.p2tr?
32
+ [:taproot, :schnorr]
33
+ else
34
+ raise ArgumentError "#{address} dose not supported."
35
+ end
36
+ tx = to_sign_tx(digest, address)
37
+ prev_out = Bitcoin::TxOut.new(script_pubkey: addr)
38
+ sighash = tx.sighash_for_input(0, addr, sig_version: sig_ver, amount: 0, prevouts: [prev_out])
39
+ sig = key.sign(sighash, algo: algo) + [Bitcoin::SIGHASH_TYPE[:all]].pack('C')
40
+ tx.in[0].script_witness.stack << sig
41
+ tx.in[0].script_witness.stack << key.pubkey.htb
42
+ format == FORMAT_SIMPLE ? tx.in[0].script_witness.to_payload : tx.to_payload
43
+ end
44
+ Base64.strict_encode64(sig)
17
45
  end
18
46
 
19
47
  # Verify a signed message.
@@ -23,25 +51,72 @@ module Bitcoin
23
51
  # @return [Boolean] Verification result.
24
52
  def verify_message(address, signature, message, prefix: Bitcoin.chain_params.message_magic)
25
53
  validate_address!(address)
26
- sig = Base64.decode64(signature)
27
- raise ArgumentError, 'Invalid signature length' unless sig.bytesize == Bitcoin::Key::COMPACT_SIGNATURE_SIZE
28
- digest = message_hash(message, prefix: prefix)
29
- pubkey = Bitcoin::Key.recover_compact(digest, sig)
30
- return false unless pubkey
31
- pubkey.to_p2pkh == address
54
+ begin
55
+ sig = Base64.strict_decode64(signature)
56
+ rescue ArgumentError
57
+ raise ArgumentError, 'Invalid signature'
58
+ end
59
+ begin
60
+ # Legacy verification
61
+ pubkey = Bitcoin::Key.recover_compact(message_hash(message, prefix: prefix, legacy: true), sig)
62
+ return false unless pubkey
63
+ pubkey.to_p2pkh == address
64
+ rescue ArgumentError
65
+ # BIP322 verification
66
+ tx = to_sign_tx(message_hash(message, prefix: prefix, legacy: false), address)
67
+ tx.in[0].script_witness = Bitcoin::ScriptWitness.parse_from_payload(sig)
68
+ script_pubkey = Bitcoin::Script.parse_from_addr(address)
69
+ tx_out = Bitcoin::TxOut.new(script_pubkey: script_pubkey)
70
+ interpreter = Bitcoin::ScriptInterpreter.new(checker: Bitcoin::TxChecker.new(tx: tx, input_index: 0, prevouts: [tx_out]))
71
+ interpreter.verify_script(Bitcoin::Script.new, script_pubkey, tx.in[0].script_witness)
72
+ end
32
73
  end
33
74
 
34
75
  # Hashes a message for signing and verification.
35
- def message_hash(message, prefix: Bitcoin.chain_params.message_magic)
36
- Bitcoin.double_sha256(Bitcoin.pack_var_string(prefix) << Bitcoin.pack_var_string(message))
76
+ def message_hash(message, prefix: Bitcoin.chain_params.message_magic, legacy: true)
77
+ if legacy
78
+ Bitcoin.double_sha256(Bitcoin.pack_var_string(prefix) << Bitcoin.pack_var_string(message))
79
+ else
80
+ Bitcoin.tagged_hash('BIP0322-signed-message', message)
81
+ end
37
82
  end
38
83
 
39
84
  def validate_address!(address)
40
85
  raise ArgumentError, 'Invalid address' unless Bitcoin.valid_address?(address)
41
86
  script = Bitcoin::Script.parse_from_addr(address)
42
- raise ArgumentError, 'Address has no key' unless script.p2pkh?
87
+ raise ArgumentError, 'This address unsupported' if script.p2sh? || script.p2wsh?
88
+ end
89
+
90
+ def validate_format!(format)
91
+ unless [FORMAT_LEGACY, FORMAT_FULL, FORMAT_SIMPLE].include?(format)
92
+ raise ArgumentError "Invalid format specified."
93
+ end
94
+ end
95
+
96
+ def to_spend_tx(digest, addr)
97
+ validate_address!(addr)
98
+ message_challenge = Bitcoin::Script.parse_from_addr(addr)
99
+ tx = Bitcoin::Tx.new
100
+ tx.version = 0
101
+ tx.lock_time = 0
102
+ prev_out = Bitcoin::OutPoint.create_coinbase_outpoint
103
+ script_sig = Bitcoin::Script.new << Bitcoin::Opcodes::OP_0 << digest
104
+ tx.in << Bitcoin::TxIn.new(out_point: prev_out, sequence: 0, script_sig: script_sig)
105
+ tx.out << Bitcoin::TxOut.new(script_pubkey: message_challenge)
106
+ tx
107
+ end
108
+
109
+ def to_sign_tx(digest, addr)
110
+ tx = Bitcoin::Tx.new
111
+ tx.version = 0
112
+ tx.lock_time = 0
113
+ prev_out = Bitcoin::OutPoint.from_txid(to_spend_tx(digest, addr).txid, 0)
114
+ tx.in << Bitcoin::TxIn.new(out_point: prev_out, sequence: 0)
115
+ tx.out << Bitcoin::TxOut.new(script_pubkey: Bitcoin::Script.new << Bitcoin::Opcodes::OP_RETURN)
116
+ tx
43
117
  end
44
118
 
45
119
  private_class_method :validate_address!
120
+ private_class_method :validate_format!
46
121
  end
47
122
  end
@@ -9,6 +9,12 @@ module Bitcoin
9
9
 
10
10
  class_option :network, aliases: '-n', default: :mainnet
11
11
 
12
+ desc 'decodepsbt <base64 psbt string>', "Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction."
13
+ def decodepsbt(base64)
14
+ psbt = Bitcoin::PSBT::Tx.parse_from_base64(base64)
15
+ puts JSON.pretty_generate(psbt.to_h)
16
+ end
17
+
12
18
  desc 'getblockchaininfo', 'Returns an object containing various state info regarding blockchain processing.'
13
19
  def getblockchaininfo
14
20
  request('getblockchaininfo')
@@ -61,7 +61,7 @@ module Bitcoin
61
61
  raise ArgumentError, 'invalid version byte' unless hex[0..1] == VERSION_BYTE
62
62
  raise ArgumentError, 'invalid version' unless PaymentCode.support_version?(version)
63
63
  raise ArgumentError, 'invalid sign' unless PaymentCode.support_sign?(sign)
64
- raise ArgumentError, Errors::Messages::INVALID_PUBLIC_KEY unless Bitcoin::Key.new(priv_key: nil, pubkey: sign + public_key).fully_valid_pubkey?
64
+ raise ArgumentError, Errors::Messages::INVALID_PUBLIC_KEY unless Bitcoin::Key.new(pubkey: sign + public_key).fully_valid_pubkey?
65
65
  raise ArgumentError, Errors::Messages::INVALID_CHECKSUM unless Bitcoin.calc_checksum(payment_code) == hex[-8..-1]
66
66
 
67
67
  x_value = payment_code[8..71]
@@ -283,6 +283,32 @@ module Bitcoin
283
283
  self
284
284
  end
285
285
 
286
+ def to_h
287
+ h = {}
288
+ h[:non_witness_utxo] = non_witness_utxo.to_h if non_witness_utxo
289
+ h[:witness_utxo] = witness_utxo.to_h if witness_utxo
290
+ h[:redeem_script] = redeem_script.to_h if redeem_script
291
+ h[:witness_script] = witness_script.to_h if redeem_script
292
+ h[:final_script_sig] = final_script_sig.to_h if final_script_sig
293
+ h[:final_script_witness] = final_script_witness.to_h if final_script_witness
294
+ h[:bip32_derivs] = hd_key_paths.values.map(&:to_h) unless hd_key_paths.empty?
295
+ h[:partial_signatures] = partial_sigs.map {|k, v| {"#{k}": v.bth}} unless partial_sigs.empty?
296
+ h[:sighash_type] = sighash_type if sighash_type
297
+ h[:ripemd160_preimages] = ripemd160_preimages.map {|k, v| {"#{k}": v}} unless ripemd160_preimages.empty?
298
+ h[:sha256_preimages] = sha256_preimages.map {|k, v| {"#{k}": v}} unless sha256_preimages.empty?
299
+ h[:hash160_preimages] = hash160_preimages.map {|k, v| {"#{k}": v}} unless hash160_preimages.empty?
300
+ h[:hash256_preimages] = hash256_preimages.map {|k, v| {"#{k}": v}} unless hash256_preimages.empty?
301
+ h[:proprietary] = proprietaries.map(&:to_h) unless proprietaries.empty?
302
+ h[:tap_key_sig] = tap_key_sig if tap_key_sig
303
+ h[:tap_script_sig] = tap_script_sigs.map {|k, v| {"#{k}": v}} unless tap_script_sigs.empty?
304
+ h[:tap_leaf_script] = tap_leaf_scripts.map {|k, v| {"#{k}": v}} unless tap_leaf_scripts.empty?
305
+ h[:tap_bip32_derivs] = tap_bip32_derivations.map{|k, v| {"#{k}": v}} unless tap_bip32_derivations.empty?
306
+ h[:tap_internal_key] = tap_internal_key if tap_internal_key
307
+ h[:tap_merkle_root] = tap_merkle_root if tap_merkle_root
308
+ h[:unknown] = unknowns.map {|k, v| {"#{k}": v.bth}} unless unknowns.empty?
309
+ h
310
+ end
311
+
286
312
  end
287
313
 
288
314
  end
@@ -100,7 +100,18 @@ module Bitcoin
100
100
  combined
101
101
  end
102
102
 
103
+ def to_h
104
+ h = {}
105
+ h[:redeem_script] = redeem_script.bth if redeem_script
106
+ h[:witness_script] = witness_script.bth if witness_script
107
+ h[:bip32_derivs] = hd_key_paths.values.map(&:to_h) unless hd_key_paths.empty?
108
+ h[:proprietary] = proprietaries.map(&:to_h) unless proprietaries.empty?
109
+ h[:tap_internal_key] = tap_internal_key if tap_internal_key
110
+ h[:tap_tree] = tap_tree if tap_tree
111
+ h[:tap_bip32_derivs] = tap_bip32_derivations.map{|k, v| {"#{k}": v}} unless tap_bip32_derivations.empty?
112
+ h[:unknown] = unknowns.map {|k, v| {"#{k}": v.bth}} unless unknowns.empty?
113
+ h
114
+ end
103
115
  end
104
-
105
116
  end
106
117
  end
@@ -39,6 +39,10 @@ module Bitcoin
39
39
  k = key
40
40
  Bitcoin.pack_var_int(k.bytesize) + k + Bitcoin.pack_var_int(value.bytesize) + value
41
41
  end
42
+
43
+ def to_h
44
+ {identifier: identifier.bth, sub_type: sub_type, value: value.bth}
45
+ end
42
46
  end
43
47
  end
44
48
  end
@@ -177,6 +177,18 @@ module Bitcoin
177
177
  end
178
178
  end
179
179
 
180
+ def to_h
181
+ {
182
+ tx: tx.to_h,
183
+ global_xpubs: xpubs.map(&:to_h),
184
+ psbt_version: version,
185
+ proprietary: proprietaries.map(&:to_h),
186
+ unknown: unknowns.map {|k, v| {"#{k}": v}},
187
+ inputs: inputs.map(&:to_h),
188
+ outputs: outputs.map(&:to_h)
189
+ }
190
+ end
191
+
180
192
  # update input key-value maps.
181
193
  # @param [Bitcoin::Tx] prev_tx previous tx reference by input.
182
194
  # @param [Bitcoin::Script] redeem_script redeem script to set input.
@@ -543,11 +543,8 @@ module Bitcoin
543
543
 
544
544
  def to_h
545
545
  h = {asm: to_s, hex: to_hex, type: type}
546
- addrs = addresses
547
- unless addrs.empty?
548
- h[:req_sigs] = multisig? ? Bitcoin::Opcodes.opcode_to_small_int(chunks[0].bth.to_i(16)) :addrs.size
549
- h[:addresses] = addrs
550
- end
546
+ addr = to_addr
547
+ h[:address] = addr if addr
551
548
  h
552
549
  end
553
550
 
@@ -1,3 +1,6 @@
1
+ require 'ecdsa_ext'
2
+ require 'ecdsa/ext/sign_verify'
3
+
1
4
  module Bitcoin
2
5
  module Secp256k1
3
6
 
@@ -10,9 +13,9 @@ module Bitcoin
10
13
  # generate ec private key and public key
11
14
  def generate_key_pair(compressed: true)
12
15
  private_key = 1 + SecureRandom.random_number(GROUP.order - 1)
13
- public_key = GROUP.generator.multiply_by_scalar(private_key)
16
+ public_key = GROUP.generator.to_jacobian * private_key
14
17
  privkey = ECDSA::Format::IntegerOctetString.encode(private_key, 32)
15
- pubkey = public_key.to_hex(compressed)
18
+ pubkey = public_key.to_affine.to_hex(compressed)
16
19
  [privkey.bth, pubkey]
17
20
  end
18
21
 
@@ -23,8 +26,8 @@ module Bitcoin
23
26
  end
24
27
 
25
28
  def generate_pubkey(privkey, compressed: true)
26
- public_key = ECDSA::Group::Secp256k1.generator.multiply_by_scalar(privkey.to_i(16))
27
- public_key.to_hex(compressed)
29
+ public_key = GROUP.generator.to_jacobian * privkey.to_i(16)
30
+ public_key.to_affine.to_hex(compressed)
28
31
  end
29
32
 
30
33
  # Check whether valid x-only public key or not.
@@ -132,7 +135,7 @@ module Bitcoin
132
135
  nonce = RFC6979.generate_rfc6979_nonce(privkey + data, extra_entropy)
133
136
 
134
137
  # port form ecdsa gem.
135
- r_point = GROUP.new_point(nonce)
138
+ r_point = (GROUP.generator.to_jacobian * nonce).to_affine
136
139
 
137
140
  point_field = ECDSA::PrimeField.new(GROUP.order)
138
141
  r = point_field.mod(r_point.x)
@@ -40,7 +40,9 @@ module Bitcoin
40
40
  private_key = p.has_even_y? ? internal_private_key.priv_key.to_i(16) :
41
41
  ECDSA::Group::Secp256k1.order - internal_private_key.priv_key.to_i(16)
42
42
  t = tweak(internal_private_key, merkle_root)
43
- Bitcoin::Key.new(priv_key: ((t.bti + private_key) % ECDSA::Group::Secp256k1.order).to_even_length_hex)
43
+ private_key = ECDSA::Format::IntegerOctetString.encode(
44
+ (t.bti + private_key) % ECDSA::Group::Secp256k1.order, 32)
45
+ Bitcoin::Key.new(priv_key: private_key.bth)
44
46
  end
45
47
  end
46
48
  end
@@ -1,3 +1,3 @@
1
1
  module Bitcoin
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitcoinrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2023-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ecdsa
14
+ name: ecdsa_ext
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: eventmachine
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: bech32
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.1.0
61
+ version: 1.3.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.1.0
68
+ version: 1.3.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: daemon-spawn
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - ">="
200
200
  - !ruby/object:Gem::Version
201
- version: 0.4.0
201
+ version: 0.5.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.4.0
208
+ version: 0.5.0
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: base32
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -517,7 +517,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
517
517
  - !ruby/object:Gem::Version
518
518
  version: '0'
519
519
  requirements: []
520
- rubygems_version: 3.3.23
520
+ rubygems_version: 3.4.1
521
521
  signing_key:
522
522
  specification_version: 4
523
523
  summary: The implementation of Bitcoin Protocol for Ruby.