bitcoinrb 0.9.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +2 -3
- data/.ruby-version +1 -1
- data/README.md +1 -1
- data/lib/bitcoin/chain_params.rb +2 -1
- data/lib/bitcoin/constants.rb +31 -16
- data/lib/bitcoin/ext/object_ext.rb +29 -0
- data/lib/bitcoin/ext.rb +1 -0
- data/lib/bitcoin/network/message_handler.rb +2 -0
- data/lib/bitcoin/psbt/input.rb +35 -1
- data/lib/bitcoin/psbt/output.rb +6 -0
- data/lib/bitcoin/psbt/proprietary.rb +44 -0
- data/lib/bitcoin/psbt/tx.rb +7 -1
- data/lib/bitcoin/psbt.rb +29 -5
- data/lib/bitcoin/script/script.rb +2 -2
- data/lib/bitcoin/script/script_interpreter.rb +2 -2
- data/lib/bitcoin/sighash_generator.rb +3 -1
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin.rb +0 -26
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d105b6b0882459caee5c30db5e4ca8700a274c8fac2cd27f863e61719a1b484
|
4
|
+
data.tar.gz: fb458ded6c3c0a892bcb546f6e753b160aeff8afaa917a5510eefd090d048dbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6062ddface7588de792e84b2c6c6394ffb145dd27aaf5fe22aae0ba191491478b958bf481a55c3f8547aa0a6066e8c7439c7ef4b625b26446dd5583f54cb61c
|
7
|
+
data.tar.gz: 6768c846fb94280e5ef4f776f15ac532f1868142998d37bf551070be925a4ad7b19243322f287d1f607f1abf24816cad337735ff2eb6be3caa5afe4c187171fa
|
data/.github/workflows/ruby.yml
CHANGED
@@ -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']
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0', '3.1']
|
23
23
|
|
24
24
|
steps:
|
25
25
|
- uses: actions/checkout@v2
|
@@ -28,8 +28,7 @@ jobs:
|
|
28
28
|
- name: Set up Ruby
|
29
29
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
30
30
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
31
|
-
|
32
|
-
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
31
|
+
uses: ruby/setup-ruby@v1
|
33
32
|
with:
|
34
33
|
ruby-version: ${{ matrix.ruby-version }}
|
35
34
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-3.
|
1
|
+
ruby-3.1.2
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ Bitcoinrb supports following feature:
|
|
15
15
|
* Key generation and verification for ECDSA, including [BIP-32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) supports.
|
16
16
|
* ECDSA signature(RFC6979 -Deterministic ECDSA, LOW-S, LOW-R support)
|
17
17
|
* Segwit support (parsing segwit payload, Bech32 address, sign for segwit tx, [BIP-141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki), [BIP-143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki), [BIP-144](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki))
|
18
|
-
* [BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)
|
18
|
+
* bech32([BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)) and bech32m([BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)) address support
|
19
19
|
* [BIP-174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) PSBT(Partially Signed Bitcoin Transaction) support
|
20
20
|
* [BIP-85](https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki) Deterministic Entropy From BIP32 Keychains support by `Bitcoin::BIP85Entropy` class.
|
21
21
|
* Schnorr signature([BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki))
|
data/lib/bitcoin/chain_params.rb
CHANGED
@@ -80,7 +80,8 @@ module Bitcoin
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def self.init(name)
|
83
|
-
|
83
|
+
yaml = File.open("#{__dir__}/chainparams/#{name}.yml")
|
84
|
+
i = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(yaml) : YAML.load(yaml)
|
84
85
|
i.dust_relay_fee ||= Bitcoin::DUST_RELAY_TX_FEE
|
85
86
|
i
|
86
87
|
end
|
data/lib/bitcoin/constants.rb
CHANGED
@@ -3,6 +3,15 @@ module Bitcoin
|
|
3
3
|
COIN = 100_000_000
|
4
4
|
MAX_MONEY = 21_000_000 * COIN
|
5
5
|
|
6
|
+
# Byte size of the ripemd160 hash
|
7
|
+
RIPEMD160_SIZE = 20
|
8
|
+
# Byte size of the SHA256 hash
|
9
|
+
SHA256_SIZE = 32
|
10
|
+
# Byte size of the HASH160 hash
|
11
|
+
HASH160_SIZE = 20
|
12
|
+
# Byte size of the HASH256 hash
|
13
|
+
HASH256_SIZE = 32
|
14
|
+
|
6
15
|
# The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
|
7
16
|
MAX_BLOCK_SERIALIZED_SIZE = 4_000_000
|
8
17
|
# The maximum allowed weight for a block, see BIP 141 (network rule)
|
@@ -53,22 +62,28 @@ module Bitcoin
|
|
53
62
|
MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH
|
54
63
|
|
55
64
|
# Standard script verification flags that standard transactions will comply with.
|
56
|
-
STANDARD_SCRIPT_VERIFY_FLAGS = [
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
STANDARD_SCRIPT_VERIFY_FLAGS = [
|
66
|
+
MANDATORY_SCRIPT_VERIFY_FLAGS,
|
67
|
+
SCRIPT_VERIFY_DERSIG,
|
68
|
+
SCRIPT_VERIFY_STRICTENC,
|
69
|
+
SCRIPT_VERIFY_MINIMALDATA,
|
70
|
+
SCRIPT_VERIFY_NULLDUMMY,
|
71
|
+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS,
|
72
|
+
SCRIPT_VERIFY_CLEANSTACK,
|
73
|
+
SCRIPT_VERIFY_MINIMALIF,
|
74
|
+
SCRIPT_VERIFY_NULLFAIL,
|
75
|
+
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY,
|
76
|
+
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY,
|
77
|
+
SCRIPT_VERIFY_LOW_S,
|
78
|
+
SCRIPT_VERIFY_WITNESS,
|
79
|
+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,
|
80
|
+
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE,
|
81
|
+
SCRIPT_VERIFY_CONST_SCRIPTCODE,
|
82
|
+
SCRIPT_VERIFY_TAPROOT,
|
83
|
+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION,
|
84
|
+
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS,
|
85
|
+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE
|
86
|
+
].inject(SCRIPT_VERIFY_NONE){|flags, f| flags |= f}
|
72
87
|
|
73
88
|
# for script
|
74
89
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Ext
|
3
|
+
module ObjectExt
|
4
|
+
refine Object do
|
5
|
+
def build_json
|
6
|
+
if self.is_a?(Array)
|
7
|
+
"[#{self.map{|o|o.to_h.to_json}.join(',')}]"
|
8
|
+
else
|
9
|
+
to_h.to_json
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_h
|
14
|
+
return self if self.is_a?(String)
|
15
|
+
instance_variables.inject({}) do |result, var|
|
16
|
+
key = var.to_s
|
17
|
+
key.slice!(0) if key.start_with?('@')
|
18
|
+
value = instance_variable_get(var)
|
19
|
+
if value.is_a?(Array)
|
20
|
+
result.update(key => value.map{|v|v.to_h})
|
21
|
+
else
|
22
|
+
result.update(key => value.class.to_s.start_with?("Bitcoin::") ? value.to_h : value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/bitcoin/ext.rb
CHANGED
data/lib/bitcoin/psbt/input.rb
CHANGED
@@ -14,6 +14,11 @@ module Bitcoin
|
|
14
14
|
attr_accessor :hd_key_paths
|
15
15
|
attr_accessor :partial_sigs
|
16
16
|
attr_accessor :sighash_type
|
17
|
+
attr_accessor :ripemd160_preimages
|
18
|
+
attr_accessor :sha256_preimages
|
19
|
+
attr_accessor :hash160_preimages
|
20
|
+
attr_accessor :hash256_preimages
|
21
|
+
attr_accessor :proprietaries
|
17
22
|
attr_accessor :unknowns
|
18
23
|
|
19
24
|
def initialize(non_witness_utxo: nil, witness_utxo: nil)
|
@@ -21,6 +26,11 @@ module Bitcoin
|
|
21
26
|
@witness_utxo = witness_utxo
|
22
27
|
@partial_sigs = {}
|
23
28
|
@hd_key_paths = {}
|
29
|
+
@ripemd160_preimages = {}
|
30
|
+
@sha256_preimages = {}
|
31
|
+
@hash160_preimages = {}
|
32
|
+
@hash256_preimages = {}
|
33
|
+
@proprietaries = []
|
24
34
|
@unknowns = {}
|
25
35
|
end
|
26
36
|
|
@@ -59,7 +69,7 @@ module Bitcoin
|
|
59
69
|
input.partial_sigs[pubkey.pubkey] = value
|
60
70
|
when PSBT_IN_TYPES[:sighash]
|
61
71
|
raise ArgumentError, 'Invalid input sighash type typed key.' unless key_len == 1
|
62
|
-
raise ArgumentError 'Duplicate Key, input sighash type already provided.' if input.sighash_type
|
72
|
+
raise ArgumentError, 'Duplicate Key, input sighash type already provided.' if input.sighash_type
|
63
73
|
input.sighash_type = value.unpack1('I')
|
64
74
|
when PSBT_IN_TYPES[:redeem_script]
|
65
75
|
raise ArgumentError, 'Invalid redeemscript typed key.' unless key_len == 1
|
@@ -81,6 +91,25 @@ module Bitcoin
|
|
81
91
|
raise ArgumentError, 'Invalid final script witness typed key.' unless key_len == 1
|
82
92
|
raise ArgumentError, 'Duplicate Key, input final scriptWitness already provided.' if input.final_script_witness
|
83
93
|
input.final_script_witness = Bitcoin::ScriptWitness.parse_from_payload(value)
|
94
|
+
when PSBT_IN_TYPES[:ripemd160]
|
95
|
+
raise ArgumentError, 'Size of key was not the expected size for the type ripemd160 preimage' unless key.bytesize == RIPEMD160_SIZE
|
96
|
+
raise ArgumentError, 'Duplicate Key, input ripemd160 preimage already provided' if input.ripemd160_preimages[key.bth]
|
97
|
+
input.ripemd160_preimages[key.bth] = value.bth
|
98
|
+
when PSBT_IN_TYPES[:sha256]
|
99
|
+
raise ArgumentError, 'Size of key was not the expected size for the type sha256 preimage' unless key.bytesize == SHA256_SIZE
|
100
|
+
raise ArgumentError, 'Duplicate Key, input sha256 preimage already provided' if input.sha256_preimages[key.bth]
|
101
|
+
input.sha256_preimages[key.bth] = value.bth
|
102
|
+
when PSBT_IN_TYPES[:hash160]
|
103
|
+
raise ArgumentError, 'Size of key was not the expected size for the type hash160 preimage' unless key.bytesize == HASH160_SIZE
|
104
|
+
raise ArgumentError, 'Duplicate Key, input hash160 preimage already provided' if input.hash160_preimages[key.bth]
|
105
|
+
input.hash160_preimages[key.bth] = value.bth
|
106
|
+
when PSBT_IN_TYPES[:hash256]
|
107
|
+
raise ArgumentError, 'Size of key was not the expected size for the type hash256 preimage' unless key.bytesize == HASH256_SIZE
|
108
|
+
raise ArgumentError, 'Duplicate Key, input hash256 preimage already provided' if input.hash256_preimages[key.bth]
|
109
|
+
input.hash256_preimages[key.bth] = value.bth
|
110
|
+
when PSBT_IN_TYPES[:proprietary]
|
111
|
+
raise ArgumentError, 'Duplicate Key, key for proprietary value already provided.' if input.proprietaries.any?{|p| p.key == key}
|
112
|
+
input.proprietaries << Proprietary.new(key, value)
|
84
113
|
else
|
85
114
|
unknown_key = ([key_type].pack('C') + key).bth
|
86
115
|
raise ArgumentError, 'Duplicate Key, key for unknown value already provided.' if input.unknowns[unknown_key]
|
@@ -102,9 +131,14 @@ module Bitcoin
|
|
102
131
|
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:redeem_script], value: redeem_script.to_payload) if redeem_script
|
103
132
|
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:witness_script], value: witness_script.to_payload) if witness_script
|
104
133
|
payload << hd_key_paths.values.map(&:to_payload).join
|
134
|
+
payload << ripemd160_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:ripemd160], key: k.htb, value: v.htb)}.join
|
135
|
+
payload << sha256_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:sha256], key: k.htb, value: v.htb)}.join
|
136
|
+
payload << hash160_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:hash160], key: k.htb, value: v.htb)}.join
|
137
|
+
payload << hash256_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:hash256], key: k.htb, value: v.htb)}.join
|
105
138
|
end
|
106
139
|
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:script_sig], value: final_script_sig.to_payload) if final_script_sig
|
107
140
|
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:script_witness], value: final_script_witness.to_payload) if final_script_witness
|
141
|
+
payload << proprietaries.map(&:to_payload).join
|
108
142
|
payload << unknowns.map {|k,v|Bitcoin.pack_var_int(k.htb.bytesize) << k.htb << Bitcoin.pack_var_int(v.bytesize) << v}.join
|
109
143
|
payload << PSBT_SEPARATOR.itb
|
110
144
|
payload
|
data/lib/bitcoin/psbt/output.rb
CHANGED
@@ -7,10 +7,12 @@ module Bitcoin
|
|
7
7
|
attr_accessor :redeem_script
|
8
8
|
attr_accessor :witness_script
|
9
9
|
attr_accessor :hd_key_paths
|
10
|
+
attr_accessor :proprietaries
|
10
11
|
attr_accessor :unknowns
|
11
12
|
|
12
13
|
def initialize
|
13
14
|
@hd_key_paths = {}
|
15
|
+
@proprietaries = []
|
14
16
|
@unknowns = {}
|
15
17
|
end
|
16
18
|
|
@@ -41,6 +43,9 @@ module Bitcoin
|
|
41
43
|
when PSBT_OUT_TYPES[:bip32_derivation]
|
42
44
|
raise ArgumentError, 'Duplicate Key, pubkey derivation path already provided' if output.hd_key_paths[key.bth]
|
43
45
|
output.hd_key_paths[key.bth] = Bitcoin::PSBT::HDKeyPath.new(key, Bitcoin::PSBT::KeyOriginInfo.parse_from_payload(value))
|
46
|
+
when PSBT_OUT_TYPES[:proprietary]
|
47
|
+
raise ArgumentError, 'Duplicate Key, key for proprietary value already provided.' if output.proprietaries.any?{|p| p.key == key}
|
48
|
+
output.proprietaries << Proprietary.new(key, value)
|
44
49
|
else
|
45
50
|
unknown_key = ([key_type].pack('C') + key).bth
|
46
51
|
raise ArgumentError, 'Duplicate Key, key for unknown value already provided' if output.unknowns[unknown_key]
|
@@ -56,6 +61,7 @@ module Bitcoin
|
|
56
61
|
payload << PSBT.serialize_to_vector(PSBT_OUT_TYPES[:redeem_script], value: redeem_script) if redeem_script
|
57
62
|
payload << PSBT.serialize_to_vector(PSBT_OUT_TYPES[:witness_script], value: witness_script) if witness_script
|
58
63
|
payload << hd_key_paths.values.map{|v|v.to_payload(PSBT_OUT_TYPES[:bip32_derivation])}.join
|
64
|
+
payload << proprietaries.map(&:to_payload).join
|
59
65
|
payload << unknowns.map {|k,v|Bitcoin.pack_var_int(k.htb.bytesize) << k.htb << Bitcoin.pack_var_int(v.bytesize) << v}.join
|
60
66
|
payload << PSBT_SEPARATOR.itb
|
61
67
|
payload
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module PSBT
|
3
|
+
# Proprietary element of PSBT
|
4
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#Proprietary_Use_Type
|
5
|
+
class Proprietary
|
6
|
+
attr_accessor :identifier # binary format
|
7
|
+
attr_accessor :sub_type # integer
|
8
|
+
attr_accessor :value # binary format
|
9
|
+
|
10
|
+
# @param [String] key key with binary format without key type(0xfc).
|
11
|
+
# @param [String] value value with binary format.
|
12
|
+
def initialize(key, value)
|
13
|
+
buf = StringIO.new(key)
|
14
|
+
id_len = Bitcoin.unpack_var_int_from_io(buf)
|
15
|
+
@identifier = buf.read(id_len)
|
16
|
+
@sub_type = Bitcoin.unpack_var_int_from_io(buf)
|
17
|
+
@value = value
|
18
|
+
end
|
19
|
+
|
20
|
+
# Show contents
|
21
|
+
# @return [String]
|
22
|
+
def to_s
|
23
|
+
"identifier: #{identifier&.bth}, sub type: #{sub_type}, value: #{value&.bth}"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get key data with key type(0xfc).
|
27
|
+
# @return [String] key data with binary format.
|
28
|
+
def key
|
29
|
+
k = [PSBT_GLOBAL_TYPES[:proprietary]].pack('C')
|
30
|
+
k << Bitcoin.pack_var_int(identifier ? identifier.bytesize : 0)
|
31
|
+
k << identifier if identifier
|
32
|
+
k << Bitcoin.pack_var_int(sub_type)
|
33
|
+
k
|
34
|
+
end
|
35
|
+
|
36
|
+
# Convert to payload
|
37
|
+
# @return [String] payload with binary format.
|
38
|
+
def to_payload
|
39
|
+
k = key
|
40
|
+
Bitcoin.pack_var_int(k.bytesize) + k + Bitcoin.pack_var_int(value.bytesize) + value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/bitcoin/psbt/tx.rb
CHANGED
@@ -32,6 +32,7 @@ module Bitcoin
|
|
32
32
|
attr_accessor :xpubs
|
33
33
|
attr_reader :inputs
|
34
34
|
attr_reader :outputs
|
35
|
+
attr_accessor :proprietaries
|
35
36
|
attr_accessor :unknowns
|
36
37
|
attr_accessor :version_number
|
37
38
|
|
@@ -40,6 +41,7 @@ module Bitcoin
|
|
40
41
|
@xpubs = []
|
41
42
|
@inputs = tx ? tx.in.map{Input.new}: []
|
42
43
|
@outputs = tx ? tx.out.map{Output.new}: []
|
44
|
+
@proprietaries = []
|
43
45
|
@unknowns = {}
|
44
46
|
end
|
45
47
|
|
@@ -66,7 +68,7 @@ module Bitcoin
|
|
66
68
|
found_sep = true
|
67
69
|
break
|
68
70
|
end
|
69
|
-
key_type =
|
71
|
+
key_type = Bitcoin.unpack_var_int_from_io(buf)
|
70
72
|
key = buf.read(key_len - 1)
|
71
73
|
value = buf.read(Bitcoin.unpack_var_int_from_io(buf))
|
72
74
|
|
@@ -89,6 +91,9 @@ module Bitcoin
|
|
89
91
|
when PSBT_GLOBAL_TYPES[:ver]
|
90
92
|
partial_tx.version_number = value.unpack1('V')
|
91
93
|
raise ArgumentError, "An unsupported version was detected." if SUPPORT_VERSION < partial_tx.version_number
|
94
|
+
when PSBT_GLOBAL_TYPES[:proprietary]
|
95
|
+
raise ArgumentError, 'Duplicate Key, key for proprietary value already provided.' if partial_tx.proprietaries.any?{|p| p.key == key}
|
96
|
+
partial_tx.proprietaries << Proprietary.new(key, value)
|
92
97
|
else
|
93
98
|
raise ArgumentError, 'Duplicate Key, key for unknown value already provided.' if partial_tx.unknowns[key]
|
94
99
|
partial_tx.unknowns[([key_type].pack('C') + key).bth] = value
|
@@ -148,6 +153,7 @@ module Bitcoin
|
|
148
153
|
payload << PSBT.serialize_to_vector(PSBT_GLOBAL_TYPES[:unsigned_tx], value: tx.to_payload)
|
149
154
|
payload << xpubs.map(&:to_payload).join
|
150
155
|
payload << PSBT.serialize_to_vector(PSBT_GLOBAL_TYPES[:ver], value: [version_number].pack('V')) if version_number
|
156
|
+
payload << proprietaries.map(&:to_payload).join
|
151
157
|
payload << unknowns.map {|k,v|Bitcoin.pack_var_int(k.htb.bytesize) << k.htb << Bitcoin.pack_var_int(v.bytesize) << v}.join
|
152
158
|
|
153
159
|
payload << PSBT_SEPARATOR.itb
|
data/lib/bitcoin/psbt.rb
CHANGED
@@ -9,14 +9,38 @@ module Bitcoin
|
|
9
9
|
autoload :Output, 'bitcoin/psbt/output'
|
10
10
|
autoload :KeyOriginInfo, 'bitcoin/psbt/key_origin_info'
|
11
11
|
autoload :HDKeyPath, 'bitcoin/psbt/hd_key_path'
|
12
|
+
autoload :Proprietary, 'bitcoin/psbt/proprietary'
|
12
13
|
|
13
14
|
# constants for PSBT
|
14
15
|
PSBT_MAGIC_BYTES = 0x70736274
|
15
|
-
PSBT_GLOBAL_TYPES = {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
PSBT_GLOBAL_TYPES = {
|
17
|
+
unsigned_tx: 0x00,
|
18
|
+
xpub: 0x01,
|
19
|
+
ver: 0xfb,
|
20
|
+
proprietary: 0xfc
|
21
|
+
}
|
22
|
+
PSBT_IN_TYPES = {
|
23
|
+
non_witness_utxo: 0x00,
|
24
|
+
witness_utxo: 0x01,
|
25
|
+
partial_sig: 0x02,
|
26
|
+
sighash: 0x03,
|
27
|
+
redeem_script: 0x04,
|
28
|
+
witness_script: 0x05,
|
29
|
+
bip32_derivation: 0x06,
|
30
|
+
script_sig: 0x07,
|
31
|
+
script_witness: 0x08,
|
32
|
+
ripemd160: 0x0a,
|
33
|
+
sha256: 0x0b,
|
34
|
+
hash160: 0x0c,
|
35
|
+
hash256: 0x0d,
|
36
|
+
proprietary: 0xfc
|
37
|
+
}
|
38
|
+
PSBT_OUT_TYPES = {
|
39
|
+
redeem_script: 0x00,
|
40
|
+
witness_script: 0x01,
|
41
|
+
bip32_derivation: 0x02,
|
42
|
+
proprietary: 0xfc
|
43
|
+
}
|
20
44
|
PSBT_SEPARATOR = 0x00
|
21
45
|
|
22
46
|
SUPPORT_VERSION = 0
|
@@ -551,7 +551,7 @@ module Bitcoin
|
|
551
551
|
def p2pkh_addr
|
552
552
|
return nil unless p2pkh?
|
553
553
|
hash160 = chunks[2].pushed_data.bth
|
554
|
-
return nil unless hash160.htb.bytesize ==
|
554
|
+
return nil unless hash160.htb.bytesize == RIPEMD160_SIZE
|
555
555
|
Bitcoin.encode_base58_address(hash160, Bitcoin.chain_params.address_version)
|
556
556
|
end
|
557
557
|
|
@@ -564,7 +564,7 @@ module Bitcoin
|
|
564
564
|
def p2sh_addr
|
565
565
|
return nil unless p2sh?
|
566
566
|
hash160 = chunks[1].pushed_data.bth
|
567
|
-
return nil unless hash160.htb.bytesize ==
|
567
|
+
return nil unless hash160.htb.bytesize == RIPEMD160_SIZE
|
568
568
|
Bitcoin.encode_base58_address(hash160, Bitcoin.chain_params.p2sh_version)
|
569
569
|
end
|
570
570
|
|
@@ -163,9 +163,9 @@ module Bitcoin
|
|
163
163
|
end
|
164
164
|
return set_error(SCRIPT_ERR_STACK_SIZE) if stack.size > MAX_STACK_SIZE
|
165
165
|
need_evaluate = true
|
166
|
+
elsif flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION)
|
167
|
+
return set_error(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION)
|
166
168
|
end
|
167
|
-
|
168
|
-
return set_error(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION) if flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION)
|
169
169
|
return true unless need_evaluate
|
170
170
|
end
|
171
171
|
elsif flag?(SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)
|
@@ -71,7 +71,9 @@ module Bitcoin
|
|
71
71
|
amount = [amount].pack('Q')
|
72
72
|
nsequence = [tx.inputs[input_index].sequence].pack('V')
|
73
73
|
hash_outputs = Bitcoin.double_sha256(tx.outputs.map{|o|o.to_payload}.join)
|
74
|
-
|
74
|
+
if output_script.p2wsh?
|
75
|
+
warn('The output_script must be a witness script, not the P2WSH itself.')
|
76
|
+
end
|
75
77
|
script_code = output_script.to_script_code(skip_separator_index)
|
76
78
|
|
77
79
|
case (hash_type & 0x1f)
|
data/lib/bitcoin/version.rb
CHANGED
data/lib/bitcoin.rb
CHANGED
@@ -194,32 +194,6 @@ module Bitcoin
|
|
194
194
|
|
195
195
|
end
|
196
196
|
|
197
|
-
class ::Object
|
198
|
-
|
199
|
-
def build_json
|
200
|
-
if self.is_a?(Array)
|
201
|
-
"[#{self.map{|o|o.to_h.to_json}.join(',')}]"
|
202
|
-
else
|
203
|
-
to_h.to_json
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def to_h
|
208
|
-
return self if self.is_a?(String)
|
209
|
-
instance_variables.inject({}) do |result, var|
|
210
|
-
key = var.to_s
|
211
|
-
key.slice!(0) if key.start_with?('@')
|
212
|
-
value = instance_variable_get(var)
|
213
|
-
if value.is_a?(Array)
|
214
|
-
result.update(key => value.map{|v|v.to_h})
|
215
|
-
else
|
216
|
-
result.update(key => value.class.to_s.start_with?("Bitcoin::") ? value.to_h : value)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
197
|
class ::Integer
|
224
198
|
def to_even_length_hex
|
225
199
|
hex = to_s(16)
|
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:
|
4
|
+
version: 1.1.1
|
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: 2022-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -364,6 +364,7 @@ files:
|
|
364
364
|
- lib/bitcoin/ext/array_ext.rb
|
365
365
|
- lib/bitcoin/ext/ecdsa.rb
|
366
366
|
- lib/bitcoin/ext/json_parser.rb
|
367
|
+
- lib/bitcoin/ext/object_ext.rb
|
367
368
|
- lib/bitcoin/ext_key.rb
|
368
369
|
- lib/bitcoin/gcs_filter.rb
|
369
370
|
- lib/bitcoin/key.rb
|
@@ -450,6 +451,7 @@ files:
|
|
450
451
|
- lib/bitcoin/psbt/input.rb
|
451
452
|
- lib/bitcoin/psbt/key_origin_info.rb
|
452
453
|
- lib/bitcoin/psbt/output.rb
|
454
|
+
- lib/bitcoin/psbt/proprietary.rb
|
453
455
|
- lib/bitcoin/psbt/tx.rb
|
454
456
|
- lib/bitcoin/rpc.rb
|
455
457
|
- lib/bitcoin/rpc/bitcoin_core_client.rb
|
@@ -514,7 +516,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
514
516
|
- !ruby/object:Gem::Version
|
515
517
|
version: '0'
|
516
518
|
requirements: []
|
517
|
-
rubygems_version: 3.
|
519
|
+
rubygems_version: 3.3.7
|
518
520
|
signing_key:
|
519
521
|
specification_version: 4
|
520
522
|
summary: The implementation of Bitcoin Protocol for Ruby.
|