bitcoinrb 0.4.0 → 0.5.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 +1 -0
- data/README.md +3 -2
- data/bitcoinrb.gemspec +2 -2
- data/exe/bitcoinrbd +5 -0
- data/lib/bitcoin.rb +10 -1
- data/lib/bitcoin/bip85_entropy.rb +111 -0
- data/lib/bitcoin/block_header.rb +2 -0
- data/lib/bitcoin/ext.rb +5 -0
- data/lib/bitcoin/ext/json_parser.rb +46 -0
- data/lib/bitcoin/ext_key.rb +7 -3
- data/lib/bitcoin/key_path.rb +12 -5
- data/lib/bitcoin/message.rb +7 -0
- data/lib/bitcoin/message/base.rb +1 -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/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/version.rb +7 -0
- data/lib/bitcoin/mnemonic.rb +5 -5
- data/lib/bitcoin/network/peer.rb +9 -4
- data/lib/bitcoin/network/peer_discovery.rb +3 -1
- data/lib/bitcoin/node/cli.rb +14 -10
- data/lib/bitcoin/node/spv.rb +1 -1
- data/lib/bitcoin/out_point.rb +2 -0
- data/lib/bitcoin/payment_code.rb +92 -0
- data/lib/bitcoin/psbt/input.rb +5 -14
- data/lib/bitcoin/psbt/tx.rb +7 -12
- data/lib/bitcoin/rpc/bitcoin_core_client.rb +22 -12
- data/lib/bitcoin/rpc/request_handler.rb +1 -1
- data/lib/bitcoin/script/script.rb +5 -9
- data/lib/bitcoin/script/script_interpreter.rb +2 -3
- data/lib/bitcoin/secp256k1.rb +1 -0
- data/lib/bitcoin/secp256k1/rfc6979.rb +43 -0
- data/lib/bitcoin/secp256k1/ruby.rb +4 -35
- 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/tx.rb +3 -7
- data/lib/bitcoin/tx_in.rb +3 -4
- data/lib/bitcoin/util.rb +7 -0
- data/lib/bitcoin/version.rb +1 -1
- data/lib/bitcoin/wallet.rb +1 -0
- data/lib/bitcoin/wallet/account.rb +1 -0
- 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 +34 -20
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# cfilter message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#cfilter
|
6
|
+
class CFilter < Base
|
7
|
+
|
8
|
+
COMMAND = 'cfilter'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :block_hash # little endian
|
12
|
+
attr_accessor :filter # little endian
|
13
|
+
|
14
|
+
def initialize(filter_type, block_hash, filter)
|
15
|
+
@filter_type = filter_type
|
16
|
+
@block_hash = block_hash
|
17
|
+
@filter = filter
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parse_from_payload(payload)
|
21
|
+
buf = StringIO.new(payload)
|
22
|
+
type = buf.read(1).unpack("C").first
|
23
|
+
hash = buf.read(32).bth
|
24
|
+
len = Bitcoin.unpack_var_int_from_io(buf)
|
25
|
+
filter = buf.read(len).bth
|
26
|
+
self.new(type, hash, filter)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_payload
|
30
|
+
[filter_type, block_hash].pack('CH*') + Bitcoin.pack_var_string(filter.htb)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfcheckpt message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfcheckpt
|
6
|
+
class GetCFCheckpt < Base
|
7
|
+
|
8
|
+
COMMAND = 'getcfcheckpt'
|
9
|
+
|
10
|
+
attr_accessor :filter_type
|
11
|
+
attr_accessor :stop_hash # little endian
|
12
|
+
|
13
|
+
def initialize(filter_type, stop_hash)
|
14
|
+
@filter_type = filter_type
|
15
|
+
@stop_hash = stop_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parse_from_payload(payload)
|
19
|
+
type, hash = payload.unpack('CH*')
|
20
|
+
self.new(type, hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_payload
|
24
|
+
[filter_type, stop_hash].pack('CH*')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfheaders message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfheaders
|
6
|
+
class GetCFHeaders < Base
|
7
|
+
include CFParser
|
8
|
+
extend CFParser
|
9
|
+
|
10
|
+
COMMAND = 'getcfheaders'
|
11
|
+
|
12
|
+
attr_accessor :filter_type
|
13
|
+
attr_accessor :start_height
|
14
|
+
attr_accessor :stop_hash # little endian
|
15
|
+
|
16
|
+
def initialize(filter_type, start_height, stop_hash)
|
17
|
+
@filter_type = filter_type
|
18
|
+
@start_height = start_height
|
19
|
+
@stop_hash = stop_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
module Message
|
3
|
+
|
4
|
+
# getcfilters message for BIP-157
|
5
|
+
# https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki#getcfilters
|
6
|
+
class GetCFilters < Base
|
7
|
+
include CFParser
|
8
|
+
extend CFParser
|
9
|
+
|
10
|
+
COMMAND = 'getcfilters'
|
11
|
+
|
12
|
+
attr_accessor :filter_type
|
13
|
+
attr_accessor :start_height
|
14
|
+
attr_accessor :stop_hash # little endian
|
15
|
+
|
16
|
+
def initialize(filter_type, start_height, stop_hash)
|
17
|
+
@filter_type = filter_type
|
18
|
+
@start_height = start_height
|
19
|
+
@stop_hash = stop_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -64,6 +64,13 @@ module Bitcoin
|
|
64
64
|
( version >= 70001 && payload ) ? unpack_boolean(payload) : [ true, nil ]
|
65
65
|
end
|
66
66
|
|
67
|
+
# Check whether +service_flag+ support this version.
|
68
|
+
# @param [Integer] service_flag the service flags.
|
69
|
+
# @return [Boolean] whether support +service_flag+
|
70
|
+
def support?(service_flag)
|
71
|
+
(services & service_flag) != 0
|
72
|
+
end
|
73
|
+
|
67
74
|
end
|
68
75
|
end
|
69
76
|
end
|
data/lib/bitcoin/mnemonic.rb
CHANGED
@@ -6,11 +6,11 @@ module Bitcoin
|
|
6
6
|
|
7
7
|
WORD_DIR = "#{__dir__}/mnemonic/wordlist"
|
8
8
|
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :language
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
raise ArgumentError, 'specified language is not supported.' unless Mnemonic.word_lists.include?(
|
13
|
-
@
|
11
|
+
def initialize(language)
|
12
|
+
raise ArgumentError, 'specified language is not supported.' unless Mnemonic.word_lists.include?(language)
|
13
|
+
@language = language
|
14
14
|
end
|
15
15
|
|
16
16
|
# get support language list
|
@@ -69,7 +69,7 @@ module Bitcoin
|
|
69
69
|
|
70
70
|
# load word list contents
|
71
71
|
def load_words
|
72
|
-
File.readlines("#{WORD_DIR}/#{
|
72
|
+
File.readlines("#{WORD_DIR}/#{language}.txt").map(&:strip)
|
73
73
|
end
|
74
74
|
|
75
75
|
end
|
data/lib/bitcoin/network/peer.rb
CHANGED
@@ -83,10 +83,15 @@ module Bitcoin
|
|
83
83
|
|
84
84
|
def post_handshake
|
85
85
|
@connected = true
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
if remote_version.support?(Bitcoin::Message::SERVICE_FLAGS[:bloom])
|
87
|
+
pool.handle_new_peer(self)
|
88
|
+
# require remote peer to use headers message instead fo inv message.
|
89
|
+
conn.send_message(Bitcoin::Message::SendHeaders.new)
|
90
|
+
EM.add_periodic_timer(PING_INTERVAL) {send_ping}
|
91
|
+
else
|
92
|
+
close("peer does not support NODE_BLOOM.")
|
93
|
+
pool.pending_peers.delete(self)
|
94
|
+
end
|
90
95
|
end
|
91
96
|
|
92
97
|
# start block header download
|
@@ -30,7 +30,9 @@ module Bitcoin
|
|
30
30
|
logger.debug 'discover peer address from DNS seeds.'
|
31
31
|
dns_seeds.map { |seed|
|
32
32
|
begin
|
33
|
-
|
33
|
+
# x5 is a prefix for finding nodes that support NODE_BLOOM.
|
34
|
+
# https://github.com/bitcoin/bitcoin/pull/8083#issuecomment-221552835
|
35
|
+
Socket.getaddrinfo("x5.#{seed}", Bitcoin.chain_params.default_port).map{|a|a[2]}.uniq
|
34
36
|
rescue SocketError => e
|
35
37
|
logger.error "SocketError occurred when load DNS seed: #{seed}, error: #{e.message}"
|
36
38
|
nil
|
data/lib/bitcoin/node/cli.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'net/http'
|
2
2
|
require 'thor'
|
3
3
|
require 'json'
|
4
4
|
|
@@ -92,15 +92,19 @@ module Bitcoin
|
|
92
92
|
:id => 'jsonrpc'
|
93
93
|
}
|
94
94
|
begin
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
95
|
+
uri = URI.parse(config.server_url)
|
96
|
+
http = Net::HTTP.new(uri.hostname, uri.port)
|
97
|
+
http.use_ssl = uri.scheme === "https"
|
98
|
+
request = Net::HTTP::Post.new('/')
|
99
|
+
request.content_type = 'application/json'
|
100
|
+
request.body = data.to_json
|
101
|
+
response = http.request(request)
|
102
|
+
body = response.body
|
103
|
+
begin
|
104
|
+
json = JSON.parse(body.to_str)
|
105
|
+
puts JSON.pretty_generate(json)
|
106
|
+
rescue Exception
|
107
|
+
puts body.to_str
|
104
108
|
end
|
105
109
|
rescue Exception => e
|
106
110
|
puts e.message
|
data/lib/bitcoin/node/spv.rb
CHANGED
data/lib/bitcoin/out_point.rb
CHANGED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Bitcoin
|
2
|
+
|
3
|
+
# BIP47 payment code
|
4
|
+
class PaymentCode < ExtKey
|
5
|
+
|
6
|
+
include Bitcoin::HexConverter
|
7
|
+
|
8
|
+
attr_accessor :x_value
|
9
|
+
attr_accessor :sign
|
10
|
+
|
11
|
+
VERSION_BYTE = '47'
|
12
|
+
SUPPORT_VERSIONS = ['01']
|
13
|
+
SUPPORT_SIGNS = ['02', '03']
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@version = '01'
|
17
|
+
@features_bits = '00'
|
18
|
+
@reserve_field = '0' * 26
|
19
|
+
end
|
20
|
+
|
21
|
+
# generate master key from seed.
|
22
|
+
# @params [String] seed a seed data with hex format.
|
23
|
+
def self.generate_master(seed)
|
24
|
+
master_ext_key = super.derive(47, harden=true).derive(0, harden=true).derive(0, harden=true)
|
25
|
+
compressed_pubkey = master_ext_key.pub
|
26
|
+
|
27
|
+
payment_code = PaymentCode.new
|
28
|
+
payment_code.depth = master_ext_key.depth
|
29
|
+
payment_code.key = master_ext_key.key
|
30
|
+
payment_code.sign = compressed_pubkey[0..1]
|
31
|
+
payment_code.x_value = compressed_pubkey[2..-1]
|
32
|
+
payment_code.chain_code = master_ext_key.chain_code
|
33
|
+
payment_code
|
34
|
+
end
|
35
|
+
|
36
|
+
# Base58 encoded payment code
|
37
|
+
def to_base58
|
38
|
+
payment_code_with_version_byte = VERSION_BYTE + to_hex
|
39
|
+
Bitcoin::Base58.encode(payment_code_with_version_byte + Bitcoin.calc_checksum(payment_code_with_version_byte))
|
40
|
+
end
|
41
|
+
|
42
|
+
# serialize payment code
|
43
|
+
def to_payload
|
44
|
+
@version.htb << @features_bits.htb << @sign.htb << @x_value.htb << @chain_code << @reserve_field.htb
|
45
|
+
end
|
46
|
+
|
47
|
+
# get notification address
|
48
|
+
def notification_address
|
49
|
+
ext_pubkey.derive(0).addr
|
50
|
+
end
|
51
|
+
|
52
|
+
# decode base58 encoded payment code
|
53
|
+
# @params [String] base58_payment_code base58 encoded payment code
|
54
|
+
def self.from_base58(base58_payment_code)
|
55
|
+
hex = Bitcoin::Base58.decode(base58_payment_code)
|
56
|
+
version = hex[2..3]
|
57
|
+
sign = hex[6..7]
|
58
|
+
public_key = hex[8..71]
|
59
|
+
payment_code = hex[0...-8]
|
60
|
+
|
61
|
+
raise ArgumentError, 'invalid version byte' unless hex[0..1] == VERSION_BYTE
|
62
|
+
raise ArgumentError, 'invalid version' unless PaymentCode.support_version?(version)
|
63
|
+
raise ArgumentError, 'invalid sign' unless PaymentCode.support_sign?(sign)
|
64
|
+
raise ArgumentError, 'invalid public key' unless Bitcoin::Key.new(priv_key: nil, pubkey: sign + public_key).fully_valid_pubkey?
|
65
|
+
raise ArgumentError, 'invalid checksum' unless Bitcoin.calc_checksum(payment_code) == hex[-8..-1]
|
66
|
+
|
67
|
+
x_value = payment_code[8..71]
|
68
|
+
chain_code_hex = payment_code[72..135]
|
69
|
+
|
70
|
+
payment_code_pubkey = PaymentCode.new
|
71
|
+
payment_code_pubkey.depth = 3
|
72
|
+
payment_code_pubkey.sign = sign
|
73
|
+
payment_code_pubkey.x_value = x_value
|
74
|
+
payment_code_pubkey.chain_code = [chain_code_hex].pack('H*')
|
75
|
+
|
76
|
+
payment_code_pubkey.to_payload
|
77
|
+
end
|
78
|
+
|
79
|
+
# check whether +version+ is supported version bytes.
|
80
|
+
def self.support_version?(version)
|
81
|
+
SUPPORT_VERSIONS.include?(version)
|
82
|
+
end
|
83
|
+
|
84
|
+
# check whether +sign+ is supported version bytes.
|
85
|
+
def self.support_sign?(sign)
|
86
|
+
SUPPORT_SIGNS.include?(sign)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
data/lib/bitcoin/psbt/input.rb
CHANGED
@@ -93,7 +93,8 @@ module Bitcoin
|
|
93
93
|
|
94
94
|
def to_payload
|
95
95
|
payload = ''
|
96
|
-
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:non_witness_utxo], value:
|
96
|
+
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:non_witness_utxo], value:
|
97
|
+
(witness_utxo && valid_witness_input?) ? non_witness_utxo.serialize_old_format : non_witness_utxo.to_payload) if non_witness_utxo
|
97
98
|
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:witness_utxo], value: witness_utxo.to_payload) if witness_utxo
|
98
99
|
if final_script_sig.nil? && final_script_witness.nil?
|
99
100
|
payload << partial_sigs.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:partial_sig], key: k.htb, value: v)}.join
|
@@ -109,15 +110,6 @@ module Bitcoin
|
|
109
110
|
payload
|
110
111
|
end
|
111
112
|
|
112
|
-
# Sanity check
|
113
|
-
# @return [Boolean]
|
114
|
-
def sane?
|
115
|
-
return false if non_witness_utxo && witness_utxo
|
116
|
-
return false if witness_script && witness_utxo.nil?
|
117
|
-
return false if final_script_witness && witness_utxo.nil?
|
118
|
-
true
|
119
|
-
end
|
120
|
-
|
121
113
|
# Check whether input's scriptPubkey is correct witness.
|
122
114
|
# @return [Boolean]
|
123
115
|
def valid_witness_input?
|
@@ -141,7 +133,6 @@ module Bitcoin
|
|
141
133
|
# @param [Bitcoin::TxOut] utxo utxo object which input refers.
|
142
134
|
# @return [Boolean]
|
143
135
|
def ready_to_sign?(utxo)
|
144
|
-
return false unless sane?
|
145
136
|
return valid_witness_input? if witness_utxo
|
146
137
|
valid_non_witness_input?(utxo) # non_witness_utxo
|
147
138
|
end
|
@@ -177,8 +168,8 @@ module Bitcoin
|
|
177
168
|
combined.witness_script = witness_script
|
178
169
|
combined.sighash_type = sighash_type
|
179
170
|
sigs = Hash[partial_sigs.merge(psbi.partial_sigs)]
|
180
|
-
redeem_script.get_multisig_pubkeys.each{|pubkey|combined.partial_sigs[pubkey.bth] = sigs[pubkey.bth]} if redeem_script
|
181
|
-
witness_script.get_multisig_pubkeys.each{|pubkey|combined.partial_sigs[pubkey.bth] = sigs[pubkey.bth]} if witness_script
|
171
|
+
redeem_script.get_multisig_pubkeys.each{|pubkey|combined.partial_sigs[pubkey.bth] = sigs[pubkey.bth]} if redeem_script&.multisig?
|
172
|
+
witness_script.get_multisig_pubkeys.each{|pubkey|combined.partial_sigs[pubkey.bth] = sigs[pubkey.bth]} if witness_script&.multisig?
|
182
173
|
combined.hd_key_paths = hd_key_paths.merge(psbi.hd_key_paths)
|
183
174
|
combined
|
184
175
|
end
|
@@ -190,7 +181,7 @@ module Bitcoin
|
|
190
181
|
if non_witness_utxo
|
191
182
|
self.final_script_sig = Bitcoin::Script.new << Bitcoin::Opcodes::OP_0 if redeem_script.multisig?
|
192
183
|
partial_sigs.values.each {|sig|final_script_sig << sig}
|
193
|
-
final_script_sig << redeem_script.
|
184
|
+
final_script_sig << redeem_script.to_hex
|
194
185
|
self.partial_sigs = {}
|
195
186
|
self.hd_key_paths = {}
|
196
187
|
self.redeem_script = nil
|
data/lib/bitcoin/psbt/tx.rb
CHANGED
@@ -2,6 +2,7 @@ module Bitcoin
|
|
2
2
|
module PSBT
|
3
3
|
|
4
4
|
class GlobalXpub
|
5
|
+
include Bitcoin::HexConverter
|
5
6
|
|
6
7
|
attr_reader :xpub # Bitcoin::ExtPubkey
|
7
8
|
attr_reader :info # Bitcoin::PSBT::KeyOriginInfo
|
@@ -16,7 +17,7 @@ module Bitcoin
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def to_h
|
19
|
-
{xpub: xpub.
|
20
|
+
{xpub: xpub.to_hex}.merge(info.to_h)
|
20
21
|
end
|
21
22
|
|
22
23
|
def to_s
|
@@ -25,6 +26,8 @@ module Bitcoin
|
|
25
26
|
end
|
26
27
|
|
27
28
|
class Tx
|
29
|
+
include Bitcoin::HexConverter
|
30
|
+
|
28
31
|
attr_accessor :tx
|
29
32
|
attr_accessor :xpubs
|
30
33
|
attr_reader :inputs
|
@@ -117,10 +120,6 @@ module Bitcoin
|
|
117
120
|
|
118
121
|
raise ArgumentError, 'Outputs provided does not match the number of outputs in transaction.' unless partial_tx.outputs.size == partial_tx.tx.out.size
|
119
122
|
|
120
|
-
partial_tx.inputs.each do |input|
|
121
|
-
raise ArgumentError, 'PSBT is not sane.' unless input.sane?
|
122
|
-
end
|
123
|
-
|
124
123
|
partial_tx
|
125
124
|
end
|
126
125
|
|
@@ -149,11 +148,9 @@ module Bitcoin
|
|
149
148
|
payload << PSBT.serialize_to_vector(PSBT_GLOBAL_TYPES[:unsigned_tx], value: tx.to_payload)
|
150
149
|
payload << xpubs.map(&:to_payload).join
|
151
150
|
payload << PSBT.serialize_to_vector(PSBT_GLOBAL_TYPES[:ver], value: [version_number].pack('V')) if version_number
|
152
|
-
|
153
151
|
payload << unknowns.map {|k,v|Bitcoin.pack_var_int(k.htb.bytesize) << k.htb << Bitcoin.pack_var_int(v.bytesize) << v}.join
|
154
152
|
|
155
153
|
payload << PSBT_SEPARATOR.itb
|
156
|
-
|
157
154
|
payload << inputs.map(&:to_payload).join
|
158
155
|
payload << outputs.map(&:to_payload).join
|
159
156
|
payload
|
@@ -177,14 +174,12 @@ module Bitcoin
|
|
177
174
|
utxo = prev_tx.out[tx_in.out_point.index]
|
178
175
|
raise ArgumentError, 'redeem script does not match utxo.' if redeem_script && !utxo.script_pubkey.include?(redeem_script.to_hash160)
|
179
176
|
raise ArgumentError, 'witness script does not match redeem script.' if redeem_script && witness_script && !redeem_script.include?(witness_script.to_sha256)
|
180
|
-
if utxo.script_pubkey.witness_program? ||
|
181
|
-
|
182
|
-
else
|
183
|
-
inputs[i].non_witness_utxo = prev_tx
|
184
|
-
end
|
177
|
+
inputs[i].witness_utxo = utxo if utxo.script_pubkey.witness_program? || redeem_script&.witness_program?
|
178
|
+
inputs[i].non_witness_utxo = prev_tx
|
185
179
|
inputs[i].redeem_script = redeem_script if redeem_script
|
186
180
|
inputs[i].witness_script = witness_script if witness_script
|
187
181
|
inputs[i].hd_key_paths = hd_key_paths.map(&:pubkey).zip(hd_key_paths).to_h
|
182
|
+
break
|
188
183
|
end
|
189
184
|
end
|
190
185
|
end
|