bitcoin-ruby 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -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