bitcoin-ruby 0.0.14 → 0.0.15

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.
@@ -237,7 +237,7 @@ module Bitcoin
237
237
  @tx.in[i].sig_address = Script.new(@prev_script).get_address if @prev_script
238
238
  end
239
239
 
240
- def get_script_sig(inc)
240
+ def get_script_sig(inc, hash_type)
241
241
  if inc.has_multiple_keys?
242
242
  # multiple keys given, generate signature for each one
243
243
  sigs = inc.sign(@sig_hash)
@@ -251,7 +251,7 @@ module Bitcoin
251
251
  else
252
252
  # only one key given, generate signature and script_sig
253
253
  sig = inc.sign(@sig_hash)
254
- script_sig = Script.to_signature_pubkey_script(sig, [inc.key.pub].pack("H*"))
254
+ script_sig = Script.to_signature_pubkey_script(sig, [inc.key.pub].pack("H*"), hash_type)
255
255
  end
256
256
  return script_sig
257
257
  end
@@ -268,13 +268,28 @@ module Bitcoin
268
268
  sig_script = inc.instance_eval { @redeem_script }
269
269
  sig_script ||= @prev_script
270
270
 
271
+ hash_type = if inc.prev_out_forkid
272
+ Script::SIGHASH_TYPE[:all] | Script::SIGHASH_TYPE[:forkid]
273
+ else
274
+ Script::SIGHASH_TYPE[:all]
275
+ end
276
+
271
277
  # when a sig_script was found, generate the sig_hash to be signed
272
278
  if sig_script
273
279
  script = Script.new(sig_script)
274
280
  if script.is_witness_v0_keyhash?
275
281
  @sig_hash = @tx.signature_hash_for_witness_input(i, sig_script, inc.value)
276
282
  else
277
- @sig_hash = @tx.signature_hash_for_input(i, sig_script)
283
+ @sig_hash = if inc.prev_out_forkid
284
+ @tx.signature_hash_for_input(
285
+ i,
286
+ sig_script,
287
+ hash_type,
288
+ inc.value,
289
+ inc.prev_out_forkid)
290
+ else
291
+ @tx.signature_hash_for_input(i, sig_script)
292
+ end
278
293
  end
279
294
  end
280
295
 
@@ -285,10 +300,12 @@ module Bitcoin
285
300
  @tx.in[i].script_witness.stack << inc.sign(@sig_hash) + [Script::SIGHASH_TYPE[:all]].pack("C")
286
301
  @tx.in[i].script_witness.stack << inc.key.pub.htb
287
302
  else
288
- @tx.in[i].script_sig = get_script_sig(inc)
303
+ @tx.in[i].script_sig = get_script_sig(inc, hash_type)
289
304
  end
290
305
  # double-check that the script_sig is valid to spend the given prev_script
291
- raise "Signature error" if @prev_script && !@tx.verify_input_signature(i, @prev_script)
306
+ if @prev_script && !inc.prev_out_forkid && !@tx.verify_input_signature(i, @prev_script)
307
+ raise "Signature error"
308
+ end
292
309
  elsif inc.has_multiple_keys?
293
310
  raise "Keys missing for multisig signing"
294
311
  else
@@ -329,7 +346,7 @@ module Bitcoin
329
346
  #
330
347
  # If you want to spend a multisig output, just provide an array of keys to #signature_key.
331
348
  class TxInBuilder
332
- attr_reader :prev_tx, :prev_script, :redeem_script, :key, :coinbase_data, :prev_out_value
349
+ attr_reader :prev_tx, :prev_script, :redeem_script, :key, :coinbase_data, :prev_out_value, :prev_out_forkid
333
350
 
334
351
  def initialize
335
352
  @txin = P::TxIn.new
@@ -341,7 +358,8 @@ module Bitcoin
341
358
  # You can either pass the transaction, or just the tx hash.
342
359
  # If you pass only the hash, you need to pass the previous outputs
343
360
  # +script+ separately if you want the txin to be signed.
344
- def prev_out tx, idx = nil, script = nil, prev_value = nil
361
+ def prev_out tx, idx = nil, script = nil, prev_value = nil, prev_forkid = nil
362
+ @prev_out_forkid = prev_forkid
345
363
  if tx.is_a?(Bitcoin::P::Tx)
346
364
  @prev_tx = tx
347
365
  @prev_out_hash = tx.binary_hash
@@ -134,7 +134,7 @@ module Bitcoin
134
134
 
135
135
  internal_pubkey = FFI::MemoryPointer.new(:uchar, 64)
136
136
  result = secp256k1_ec_pubkey_create(context, internal_pubkey, seckey)
137
- raise "error creating pubkey" unless result
137
+ raise "error creating pubkey" unless result == 1
138
138
 
139
139
  pubkey, pubkey_len = FFI::MemoryPointer.new(:uchar, 65), FFI::MemoryPointer.new(:uint64)
140
140
  result = if compressed
@@ -144,7 +144,7 @@ module Bitcoin
144
144
  pubkey_len.put_uint64(0, 65)
145
145
  secp256k1_ec_pubkey_serialize(context, pubkey, pubkey_len, internal_pubkey, SECP256K1_EC_UNCOMPRESSED)
146
146
  end
147
- raise "error serialize pubkey" unless result || pubkey_len.read_uint64 > 0
147
+ raise "error serialize pubkey" unless (result == 1) || pubkey_len.read_uint64 > 0
148
148
 
149
149
  [ seckey.read_string(32), pubkey.read_string(pubkey_len.read_uint64) ]
150
150
  end
@@ -158,7 +158,7 @@ module Bitcoin
158
158
  def self.sign(data, priv_key)
159
159
  with_context do |context|
160
160
  seckey = FFI::MemoryPointer.new(:uchar, priv_key.bytesize).put_bytes(0, priv_key)
161
- raise "priv_key invalid" unless secp256k1_ec_seckey_verify(context, seckey)
161
+ raise "priv_key invalid" unless secp256k1_ec_seckey_verify(context, seckey) == 1
162
162
 
163
163
  internal_signature = FFI::MemoryPointer.new(:uchar, 64)
164
164
  msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, data)
@@ -173,7 +173,7 @@ module Bitcoin
173
173
 
174
174
  signature, signature_len = FFI::MemoryPointer.new(:uchar, 72), FFI::MemoryPointer.new(:uint64).put_uint64(0, 72)
175
175
  result = secp256k1_ecdsa_signature_serialize_der(context, signature, signature_len, internal_signature)
176
- raise "secp256k1_ecdsa_signature_serialize_der failed" unless result
176
+ raise "secp256k1_ecdsa_signature_serialize_der failed" unless result == 1
177
177
 
178
178
  signature.read_string(signature_len.read_uint64)
179
179
  end
@@ -186,13 +186,13 @@ module Bitcoin
186
186
  pubkey = FFI::MemoryPointer.new(:uchar, pub_key.bytesize).put_bytes(0, pub_key)
187
187
  internal_pubkey = FFI::MemoryPointer.new(:uchar, 64)
188
188
  result = secp256k1_ec_pubkey_parse(context, internal_pubkey, pubkey, pubkey.size)
189
- return false unless result
189
+ return false unless result == 1
190
190
 
191
191
  signature = FFI::MemoryPointer.new(:uchar, sig.bytesize).put_bytes(0, sig)
192
192
  internal_signature = FFI::MemoryPointer.new(:uchar, 64)
193
193
  result = secp256k1_ecdsa_signature_parse_der(context, internal_signature, signature, signature.size)
194
194
  #result = ecdsa_signature_parse_der_lax(context, internal_signature, signature, signature.size)
195
- return false unless result
195
+ return false unless result == 1
196
196
 
197
197
  # libsecp256k1's ECDSA verification requires lower-S signatures, which have not historically been enforced in Bitcoin, so normalize them first.
198
198
  secp256k1_ecdsa_signature_normalize(context, internal_signature, internal_signature)
@@ -200,14 +200,14 @@ module Bitcoin
200
200
  msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, data)
201
201
  result = secp256k1_ecdsa_verify(context, internal_signature, msg32, internal_pubkey)
202
202
 
203
- return result ? true : false
203
+ return result == 1
204
204
  end
205
205
  end
206
206
 
207
207
  def self.sign_compact(message, priv_key, compressed=true)
208
208
  with_context do |context|
209
209
  seckey = FFI::MemoryPointer.new(:uchar, priv_key.bytesize).put_bytes(0, priv_key)
210
- raise "priv_key invalid" unless secp256k1_ec_seckey_verify(context, seckey)
210
+ raise "priv_key invalid" unless secp256k1_ec_seckey_verify(context, seckey) == 1
211
211
 
212
212
  msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, message)
213
213
  internal_recoverable_signature = FFI::MemoryPointer.new(:uchar, 65)
@@ -223,7 +223,7 @@ module Bitcoin
223
223
 
224
224
  recoverable_signature = FFI::MemoryPointer.new(:uchar, 64)
225
225
  result = secp256k1_ecdsa_recoverable_signature_serialize_compact(context, recoverable_signature, rec_id, internal_recoverable_signature)
226
- raise "secp256k1_ecdsa_recoverable_signature_serialize_compact failed" unless result
226
+ raise "secp256k1_ecdsa_recoverable_signature_serialize_compact failed" unless result == 1
227
227
  raise "secp256k1_ecdsa_recoverable_signature_serialize_compact failed" unless rec_id.read_int != -1
228
228
 
229
229
  header = [27 + rec_id.read_int + (compressed ? 4 : 0)].pack("C")
@@ -248,15 +248,15 @@ module Bitcoin
248
248
 
249
249
  internal_recoverable_signature = FFI::MemoryPointer.new(:uchar, 65)
250
250
  result = secp256k1_ecdsa_recoverable_signature_parse_compact(context, internal_recoverable_signature, recoverable_signature, recid)
251
- return nil unless result
251
+ return nil unless result == 1
252
252
 
253
253
  internal_pubkey = FFI::MemoryPointer.new(:uchar, 64)
254
254
  result = secp256k1_ecdsa_recover(context, internal_pubkey, internal_recoverable_signature, msg32)
255
- return nil unless result
255
+ return nil unless result == 1
256
256
 
257
257
  pubkey, pubkey_len = FFI::MemoryPointer.new(:uchar, 65), FFI::MemoryPointer.new(:uint64).put_uint64(0, 65)
258
258
  result = secp256k1_ec_pubkey_serialize(context, pubkey, pubkey_len, internal_pubkey, flag)
259
- raise "error serialize pubkey" unless result || pubkey_len.read_uint64 > 0
259
+ raise "error serialize pubkey" unless (result == 1) || pubkey_len.read_uint64 > 0
260
260
 
261
261
  pubkey.read_string(pubkey_len.read_uint64)
262
262
  end
@@ -9,7 +9,7 @@ module Bitcoin
9
9
  attr_accessor :value
10
10
 
11
11
  # pk_script output Script
12
- attr_accessor :pk_script, :pk_script_length
12
+ attr_reader :pk_script, :pk_script_length
13
13
 
14
14
  # p2sh redeem script (optional, not included in the serialized binary format)
15
15
  attr_accessor :redeem_script
@@ -39,6 +39,7 @@ module Bitcoin
39
39
 
40
40
  # parse raw binary data for transaction output
41
41
  def parse_data_from_io(buf)
42
+ clear_parsed_script_cache
42
43
  @value = buf.read(8).unpack("Q")[0]
43
44
  @pk_script_length = Protocol.unpack_var_int_from_io(buf)
44
45
  @pk_script = buf.read(@pk_script_length)
@@ -50,6 +51,10 @@ module Bitcoin
50
51
  @parsed_script ||= Bitcoin::Script.new(pk_script)
51
52
  end
52
53
 
54
+ def clear_parsed_script_cache
55
+ remove_instance_variable(:@parsed_script) if defined?(@parsed_script)
56
+ end
57
+
53
58
  def to_payload
54
59
  [@value].pack("Q") << Protocol.pack_var_int(@pk_script_length) << @pk_script
55
60
  end
@@ -73,6 +78,7 @@ module Bitcoin
73
78
 
74
79
  # set pk_script and pk_script_length
75
80
  def pk_script=(pk_script)
81
+ clear_parsed_script_cache
76
82
  @pk_script_length, @pk_script = pk_script.bytesize, pk_script
77
83
  end
78
84
 
@@ -599,19 +599,19 @@ class Bitcoin::Script
599
599
  @chunks[0] == OP_RETURN && @chunks.size <= 2
600
600
  end
601
601
 
602
- # is this a witness script(witness_v0_keyhash or witness_v0_scripthash)
602
+ # is this a witness script
603
603
  def is_witness?
604
- is_witness_v0_keyhash? || is_witness_v0_scripthash?
604
+ @chunks.length == 2 && (0..16).include?(@chunks[0]) && @chunks[1].is_a?(String)
605
605
  end
606
606
 
607
607
  # is this a witness pubkey script
608
608
  def is_witness_v0_keyhash?
609
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 20
609
+ is_witness? && @chunks[0] == 0 && @chunks[1].bytesize == 20
610
610
  end
611
611
 
612
612
  # is this a witness script hash
613
613
  def is_witness_v0_scripthash?
614
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 32
614
+ is_witness? && @chunks[0] == 0 && @chunks[1].bytesize == 32
615
615
  end
616
616
 
617
617
  # Verify the script is only pushing data onto the stack
@@ -731,6 +731,12 @@ class Bitcoin::Script
731
731
  return [get_hash160_address] if is_hash160?
732
732
  return get_multisig_addresses if is_multisig?
733
733
  return [get_p2sh_address] if is_p2sh?
734
+
735
+ if is_witness_v0_keyhash? || is_witness_v0_scripthash?
736
+ program_hex = chunks[1].unpack("H*").first
737
+ return Bitcoin.encode_segwit_address(0, program_hex)
738
+ end
739
+
734
740
  []
735
741
  end
736
742
 
@@ -762,20 +768,28 @@ class Bitcoin::Script
762
768
  [ ["a9", "14", p2sh, "87"].join ].pack("H*")
763
769
  end
764
770
 
771
+ # generate pay-to-witness output script for given +witness_version+ and
772
+ # +witness_program+. returns a raw binary script of the form:
773
+ # <witness_version> <witness_program>
774
+ def self.to_witness_script(witness_version, witness_program_hex)
775
+ return nil unless (0..16).include?(witness_version)
776
+ return nil unless witness_program_hex
777
+ version = witness_version != 0 ? 0x50 + witness_version : 0 # 0x50 for OP_1.. codes
778
+ [version].pack('C') + pack_pushdata(witness_program_hex.htb)
779
+ end
780
+
765
781
  # generate p2wpkh tx for given +address+. returns a raw binary script of the form:
766
782
  # 0 <hash160>
767
783
  def self.to_witness_hash160_script(hash160)
768
784
  return nil unless hash160
769
- # witness ver length hash160
770
- [ ["00", "14", hash160].join ].pack("H*")
785
+ to_witness_script(0, hash160)
771
786
  end
772
787
 
773
788
  # generate p2wsh output script for given +p2sh+ sha256. returns a raw binary script of the form:
774
789
  # 0 <p2sh>
775
790
  def self.to_witness_p2sh_script(p2sh)
776
791
  return nil unless p2sh
777
- # witness ver length sha256
778
- [ [ "00", "20", p2sh].join].pack("H*")
792
+ to_witness_script(0, p2sh)
779
793
  end
780
794
 
781
795
  # generate hash160 or p2sh output script, depending on the type of the given +address+.
@@ -785,6 +799,9 @@ class Bitcoin::Script
785
799
  case Bitcoin.address_type(address)
786
800
  when :hash160; to_hash160_script(hash160)
787
801
  when :p2sh; to_p2sh_script(hash160)
802
+ when :witness_v0_keyhash, :witness_v0_scripthash
803
+ witness_version, witness_program_hex = Bitcoin.decode_segwit_address(address)
804
+ to_witness_script(witness_version, witness_program_hex)
788
805
  end
789
806
  end
790
807
 
@@ -1,3 +1,3 @@
1
1
  module Bitcoin
2
- VERSION = "0.0.14"
2
+ VERSION = "0.0.15"
3
3
  end
@@ -0,0 +1,160 @@
1
+ # encoding: ascii-8bit
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ describe Bitcoin::Bech32 do
6
+ before do
7
+ Bitcoin.network = :bitcoin
8
+
9
+ @invalid_address_enc = [
10
+ ["BC", 0, 20],
11
+ ["bc", 0, 21],
12
+ ["bc", 17, 32],
13
+ ["bc", 1, 1],
14
+ ["bc", 16, 41],
15
+ ]
16
+
17
+ @valid_address = [
18
+ [
19
+ "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
20
+ 22, [
21
+ 0x00, 0x14, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
22
+ 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
23
+ ]
24
+ ],
25
+ [
26
+ "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
27
+ 34, [
28
+ 0x00, 0x20, 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 0x04,
29
+ 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 0x6c, 0x98, 0x56, 0x78,
30
+ 0xcd, 0x4d, 0x27, 0xa1, 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32,
31
+ 0x62
32
+ ]
33
+ ],
34
+ [
35
+ "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
36
+ 42, [
37
+ 0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
38
+ 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6,
39
+ 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c,
40
+ 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
41
+ ]
42
+ ],
43
+ [
44
+ "BC1SW50QA3JX3S",
45
+ 4, [
46
+ 0x60, 0x02, 0x75, 0x1e
47
+ ]
48
+ ],
49
+ [
50
+ "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
51
+ 18, [
52
+ 0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
53
+ 0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23
54
+ ]
55
+ ],
56
+ [
57
+ "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
58
+ 34, [
59
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21,
60
+ 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5,
61
+ 0xe9, 0x1c, 0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64,
62
+ 0x33
63
+ ]
64
+ ]
65
+ ]
66
+
67
+ @valid_checksum = [
68
+ "A12UEL5L",
69
+ "an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
70
+ "abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
71
+ "11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
72
+ "split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
73
+ ]
74
+
75
+ @invalid_checksum = [
76
+ " 1nwldj5",
77
+ "\x7f""1axkwrx",
78
+ "an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
79
+ "pzry9x0s0muk",
80
+ "1pzry9x0s0muk",
81
+ "x1b4n0q5v",
82
+ "li1dgmt3",
83
+ "de1lg7wt\xff",
84
+ ]
85
+
86
+ @invalid_address = [
87
+ "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
88
+ "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
89
+ "BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
90
+ "bc1rw5uspcuh",
91
+ "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
92
+ "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
93
+ "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
94
+ "bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du",
95
+ "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
96
+ "bc1gmk9yu",
97
+ ]
98
+ end
99
+
100
+ describe '#decode and #encode' do
101
+ it "test vectors" do
102
+ @valid_checksum.each do |testdata|
103
+ hrp, data = Bitcoin::Bech32.decode(testdata)
104
+ newdata = Bitcoin::Bech32.encode(hrp, data)
105
+ newdata.should == testdata.downcase
106
+ end
107
+
108
+ @invalid_checksum.each do |testdata|
109
+ hrp, data = Bitcoin::Bech32.decode(testdata)
110
+ hrp.should == nil
111
+ end
112
+
113
+ @valid_address.each do |testdata, _, _|
114
+ hrp, data = Bitcoin::Bech32.decode(testdata)
115
+ newdata = Bitcoin::Bech32.encode(hrp, data)
116
+ newdata.should == testdata.downcase
117
+ end
118
+ end
119
+ end
120
+
121
+ describe '#decode_segwit_address and #encode_segwit_address' do
122
+ it "test vectors" do
123
+ @valid_address.each do |testaddress, _, testscript|
124
+ Bitcoin.network = :bitcoin
125
+ version, program = Bitcoin.decode_segwit_address(testaddress)
126
+ if version.nil?
127
+ Bitcoin.network = :testnet3
128
+ version, program = Bitcoin.decode_segwit_address(testaddress)
129
+ end
130
+ version.should != nil
131
+
132
+ script = Bitcoin::Script.to_witness_script(version, program)
133
+ script.should == testscript.pack("C*")
134
+
135
+ newaddress = Bitcoin.encode_segwit_address(version, program)
136
+ newaddress.should != nil
137
+ newaddress.should == testaddress.downcase
138
+ end
139
+
140
+ @invalid_address.each do |testaddress|
141
+ Bitcoin.network = :bitcoin
142
+ version, program = Bitcoin.decode_segwit_address(testaddress)
143
+ if version.nil?
144
+ Bitcoin.network = :testnet3
145
+ version, program = Bitcoin.decode_segwit_address(testaddress)
146
+ end
147
+ version.should == nil
148
+ end
149
+
150
+ Bitcoin.network = :bitcoin
151
+ @invalid_address_enc.each do |testhrp, testversion, testlength|
152
+ Bitcoin.network[:bech32_hrp] = testhrp
153
+ program_hex = Array.new(testlength){ 0 }.pack("C*").unpack("H*").first
154
+ newaddress = Bitcoin.encode_segwit_address(testversion, program_hex)
155
+ newaddress.should == nil
156
+ end
157
+ end
158
+ end
159
+
160
+ end