openassets-ruby 0.6.1 → 0.6.2

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
  SHA1:
3
- metadata.gz: 6b5679dc5dd4ae230e09b81012fe13e7db057548
4
- data.tar.gz: c1796a40aa77821f6ae961202a0d4bcb9ebff79c
3
+ metadata.gz: b3cd49e63faf8301ee4caf26be682202e5e5a051
4
+ data.tar.gz: a3b67aa95ec1f0b25065eb05723a0b497fdecb7e
5
5
  SHA512:
6
- metadata.gz: 7b6a6bd8a6c3f078d097d7f7c78a2f292ee55bc021f9576dc89c1a91981daf043a4b91302dd03fa10cf6885c63f64c95622018837c13122aba9c0362100317f1
7
- data.tar.gz: 3037ef079b58c44834699f196fbd117374f8a4ff5b01dbbe09e28f3409b371886ff930767d6d8829d854519824cee83b90d4eb89c1a1fcd4cb7239036b6dfe51
6
+ metadata.gz: ebbb8bb25821768cfeeed8a95057dbba49652c81bc357f243ba67e6cc0ad0fb843d5d02b0c6b865b32b569dee95712641983c7332bdc97d9063404ff0b903700
7
+ data.tar.gz: c6fb0224a52a92f34466a677423769566158e912b52bc1ce677ff87999396c81d27764ffb252b172c25a9826be8276892ec3cd373741ad9dfc93ab51a270b66d
@@ -1,3 +1,3 @@
1
1
  module OpenAssets
2
- VERSION = '0.6.1'
2
+ VERSION = '0.6.2'
3
3
  end
data/lib/segwit/script.rb CHANGED
@@ -1,36 +1,78 @@
1
- module SegwitScript
1
+ # encoding: ascii-8bit
2
2
 
3
- # override Bitcoin::Script#is_standard?
4
- # Add P2WPKH and P2WSH to the standard
3
+ require 'bitcoin'
4
+
5
+ class Bitcoin::Script
6
+ # Returns a script that deleted the script before the index specified by separator_index.
7
+ def subscript_codeseparator(separator_index)
8
+ buf = []
9
+ process_separator_index = 0
10
+ (chunks || @chunks).each{|chunk|
11
+ buf << chunk if process_separator_index == separator_index
12
+ process_separator_index += 1 if chunk == OP_CODESEPARATOR and process_separator_index < separator_index
13
+ }
14
+ to_binary(buf)
15
+ end
16
+
17
+ # check if script is in one of the recognized standard formats
5
18
  def is_standard?
6
- super || is_witness_v0_keyhash? || is_witness_v0_scripthash?
19
+ is_pubkey? || is_hash160? || is_multisig? || is_p2sh? || is_op_return? || is_witness_v0_keyhash? || is_witness_v0_scripthash?
7
20
  end
8
21
 
9
- # see https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Witness_program
22
+ # is this a witness script(witness_v0_keyhash or witness_v0_scripthash)
23
+ def is_witness?
24
+ is_witness_v0_keyhash? || is_witness_v0_scripthash?
25
+ end
26
+
27
+ # is this a witness pubkey script
10
28
  def is_witness_v0_keyhash?
11
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].bytesize == 20
29
+ @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 20
12
30
  end
13
31
 
14
- # see https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#Witness_program
32
+ # is this a witness script hash
15
33
  def is_witness_v0_scripthash?
16
- @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].bytesize == 32
34
+ @chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 32
17
35
  end
18
36
 
19
- # override Bitcoin::Script#type
20
- # Add type witness_v0_keyhash and witness_v0_scripthash
37
+ # get type of this tx
21
38
  def type
22
- base = super
23
- if base == :unknown
24
- return :witness_v0_keyhash if is_witness_v0_keyhash?
25
- return :witness_v0_scripthash if is_witness_v0_scripthash?
26
- :unknown
27
- else
28
- base
39
+ if is_hash160?; :hash160
40
+ elsif is_pubkey?; :pubkey
41
+ elsif is_multisig?; :multisig
42
+ elsif is_p2sh?; :p2sh
43
+ elsif is_op_return?; :op_return
44
+ elsif is_witness_v0_keyhash?; :witness_v0_keyhash
45
+ elsif is_witness_v0_scripthash?;:witness_v0_scripthash
46
+ else; :unknown
29
47
  end
30
48
  end
31
49
 
32
- end
50
+ # get the hash160 for this hash160 or pubkey script
51
+ def get_hash160
52
+ return @chunks[2..-3][0].unpack("H*")[0] if is_hash160?
53
+ return @chunks[-2].unpack("H*")[0] if is_p2sh?
54
+ return Bitcoin.hash160(get_pubkey) if is_pubkey?
55
+ return @chunks[1].unpack("H*")[0] if is_witness_v0_keyhash?
56
+ return @chunks[1].unpack("H*")[0] if is_witness_v0_scripthash?
57
+ end
33
58
 
34
- class Bitcoin::Script
35
- prepend SegwitScript
59
+ # generate p2wpkh tx for given +address+. returns a raw binary script of the form:
60
+ # 0 <hash160>
61
+ def self.to_witness_hash160_script(hash160)
62
+ return nil unless hash160
63
+ # witness ver length hash160
64
+ [ ["00", "14", hash160].join ].pack("H*")
65
+ end
66
+
67
+ # generate p2wsh output script for given +p2sh+ sha256. returns a raw binary script of the form:
68
+ # 0 <p2sh>
69
+ def self.to_witness_p2sh_script(p2sh)
70
+ return nil unless p2sh
71
+ # witness ver length sha256
72
+ [ [ "00", "20", p2sh].join].pack("H*")
73
+ end
74
+
75
+ def codeseparator_count
76
+ @chunks.select{|c|c == Bitcoin::Script::OP_CODESEPARATOR}.length
77
+ end
36
78
  end
@@ -1,23 +1,35 @@
1
- class Bitcoin::Protocol::ScriptWitness
1
+ # encoding: ascii-8bit
2
2
 
3
- # witness stack
4
- attr_reader :stack
3
+ module Bitcoin
5
4
 
6
- def initialize
7
- @stack = []
8
- end
5
+ module Protocol
9
6
 
10
- def empty?
11
- stack.empty?
12
- end
7
+ class ScriptWitness
8
+
9
+ # witness stack
10
+ attr_reader :stack
11
+
12
+ def initialize
13
+ @stack = []
14
+ end
15
+
16
+ # check empty
17
+ def empty?
18
+ stack.empty?
19
+ end
20
+
21
+ # output script in raw binary format
22
+ def to_payload
23
+ payload = Bitcoin::Protocol.pack_var_int(stack.size)
24
+ stack.each{|e|
25
+ payload << Bitcoin::Protocol.pack_var_int(e.htb.bytesize)
26
+ payload << e.htb
27
+ }
28
+ payload
29
+ end
30
+
31
+ end
13
32
 
14
- # output script in raw binary format
15
- def to_payload
16
- payload = Bitcoin::Protocol.pack_var_int(stack.size)
17
- stack.each{|e|
18
- payload << Bitcoin::Protocol.pack_var_int(e.htb.bytesize)
19
- payload << e.htb
20
- }
21
- payload
22
33
  end
34
+
23
35
  end
data/lib/segwit/tx.rb CHANGED
@@ -1,76 +1,235 @@
1
- # extension for Bitcoin::Protocol::Tx to support segwit
2
- class Bitcoin::Protocol::Tx
3
- include Bitcoin::Util
4
-
5
- attr_reader :witness
6
-
7
- def initialize(data=nil)
8
- @ver, @lock_time, @in, @out, @scripts, @witness = 1, 0, [], [], [], Bitcoin::Protocol::TxWitness.new
9
- @enable_bitcoinconsensus = !!ENV['USE_BITCOINCONSENSUS']
10
- if data
11
- begin
12
- parse_witness_data_from_io(data) unless parse_data_from_io(data).is_a?(TrueClass)
13
- rescue Exception
14
- parse_witness_data_from_io(data)
1
+ # encoding: ascii-8bit
2
+
3
+ require 'bitcoin/script'
4
+
5
+ module Bitcoin
6
+ module Protocol
7
+
8
+ class Tx
9
+
10
+ # witness (TxWitness)
11
+ attr_reader :witness
12
+
13
+ # create tx from raw binary +data+
14
+ def initialize(data=nil)
15
+ @ver, @lock_time, @in, @out, @scripts, @witness = 1, 0, [], [], [], TxWitness.new
16
+ @enable_bitcoinconsensus = !!ENV['USE_BITCOINCONSENSUS']
17
+ if data
18
+ begin
19
+ parse_witness_data_from_io(data) unless parse_data_from_io(data).is_a?(TrueClass)
20
+ rescue Exception
21
+ parse_witness_data_from_io(data)
22
+ end
23
+ end
15
24
  end
16
- end
17
- end
18
25
 
19
- # get witness hash
20
- def witness_hash
21
- hash_from_payload(to_witness_payload)
22
- end
26
+ # parse witness raw binary data
27
+ # serialization format is defined by https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki
28
+ def parse_witness_data_from_io(data)
29
+ buf = data.is_a?(String) ? StringIO.new(data) : data
23
30
 
24
- # parse raw data which include witness data
25
- # serialization format is defined by https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki
26
- def parse_witness_data_from_io(data)
27
- buf = data.is_a?(String) ? StringIO.new(data) : data
28
-
29
- @ver = buf.read(4).unpack("V").first
30
-
31
- @marker = buf.read(1).unpack("c").first
32
-
33
- @flag = buf.read(1).unpack("c").first
34
-
35
- in_size = Bitcoin::Protocol.unpack_var_int_from_io(buf)
36
- @in = []
37
- in_size.times{
38
- break if buf.eof?
39
- @in << Bitcoin::Protocol::TxIn.from_io(buf)
40
- }
41
-
42
- out_size = Bitcoin::Protocol.unpack_var_int_from_io(buf)
43
- @out = []
44
- out_size.times{
45
- break if buf.eof?
46
- @out << Bitcoin::Protocol::TxOut.from_io(buf)
47
- }
48
-
49
- @witness = Bitcoin::Protocol::TxWitness.new
50
- in_size.times{
51
- witness_count = Bitcoin::Protocol.unpack_var_int_from_io(buf)
52
- in_witness = Bitcoin::Protocol::TxInWitness.new
53
- witness_count.times{
54
- length = Bitcoin::Protocol.unpack_var_int_from_io(buf)
55
- in_witness.add_stack(buf.read(length).unpack("H*").first)
56
- }
57
- @witness.add_witness(in_witness)
58
- }
59
-
60
- @lock_time = buf.read(4).unpack("V").first
61
-
62
- @hash = hash_from_payload(to_payload)
63
- end
31
+ @ver = buf.read(4).unpack("V").first
64
32
 
65
- # output transaction in raw binary format with witness
66
- def to_witness_payload
67
- pin = ""
68
- @in.each{|input| pin << input.to_payload }
69
- pout = ""
70
- @out.each{|output| pout << output.to_payload }
71
- payload = [@ver].pack("V") << [0].pack("c") << [1].pack("c") << Bitcoin::Protocol.pack_var_int(@in.size) << pin <<
72
- Bitcoin::Protocol.pack_var_int(@out.size) << pout << @witness.to_payload << [@lock_time].pack("V")
73
- payload
74
- end
33
+ @marker = buf.read(1).unpack("c").first
34
+
35
+ @flag = buf.read(1).unpack("c").first
36
+
37
+ in_size = Bitcoin::Protocol.unpack_var_int_from_io(buf)
38
+ @in = []
39
+ in_size.times{
40
+ break if buf.eof?
41
+ @in << Bitcoin::Protocol::TxIn.from_io(buf)
42
+ }
43
+
44
+ out_size = Bitcoin::Protocol.unpack_var_int_from_io(buf)
45
+ @out = []
46
+ out_size.times{
47
+ break if buf.eof?
48
+ @out << Bitcoin::Protocol::TxOut.from_io(buf)
49
+ }
50
+
51
+ @witness = Bitcoin::Protocol::TxWitness.new
52
+ in_size.times{
53
+ witness_count = Bitcoin::Protocol.unpack_var_int_from_io(buf)
54
+ in_witness = Bitcoin::Protocol::TxInWitness.new
55
+ witness_count.times{
56
+ length = Bitcoin::Protocol.unpack_var_int_from_io(buf)
57
+ in_witness.add_stack(buf.read(length).unpack("H*").first)
58
+ }
59
+ @witness.add_witness(in_witness)
60
+ }
61
+
62
+ @lock_time = buf.read(4).unpack("V").first
63
+
64
+ @hash = hash_from_payload(to_payload)
65
+
66
+ if buf.eof?
67
+ true
68
+ else
69
+ data.is_a?(StringIO) ? buf : buf.read
70
+ end
71
+ end
72
+
73
+ alias :parse_witness_data :parse_witness_data_from_io
74
+
75
+ # output transaction in raw binary format with witness
76
+ def to_witness_payload
77
+ pin = ""
78
+ @in.each{|input| pin << input.to_payload }
79
+ pout = ""
80
+ @out.each{|output| pout << output.to_payload }
81
+ [@ver].pack("V") << [0].pack("c") << [1].pack("c") << Bitcoin::Protocol.pack_var_int(@in.size) << pin <<
82
+ Bitcoin::Protocol.pack_var_int(@out.size) << pout << @witness.to_payload << [@lock_time].pack("V")
83
+ end
84
+
85
+ # generate a witness signature hash for input +input_idx+.
86
+ # https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
87
+ def signature_hash_for_witness_input(input_idx, witness_program, prev_out_value, witness_script = nil, hash_type=nil, skip_separator_index = 0)
88
+ return "\x01".ljust(32, "\x00") if input_idx >= @in.size # ERROR: SignatureHash() : input_idx=%d out of range
89
+
90
+ hash_type ||= SIGHASH_TYPE[:all]
91
+
92
+ script = Bitcoin::Script.new(witness_program)
93
+ raise "ScriptPubkey does not contain witness program." unless script.is_witness?
94
+
95
+ hash_prevouts = Digest::SHA256.digest(Digest::SHA256.digest(@in.map{|i| [i.prev_out_hash, i.prev_out_index].pack("a32V")}.join))
96
+ hash_sequence = Digest::SHA256.digest(Digest::SHA256.digest(@in.map{|i|i.sequence}.join))
97
+ outpoint = [@in[input_idx].prev_out_hash, @in[input_idx].prev_out_index].pack("a32V")
98
+ amount = [prev_out_value].pack("Q")
99
+ nsequence = @in[input_idx].sequence
100
+
101
+ if script.is_witness_v0_keyhash?
102
+ script_code = [["1976a914", script.get_hash160, "88ac"].join].pack("H*")
103
+ elsif script.is_witness_v0_scripthash?
104
+ raise "witness script does not match script pubkey" unless Bitcoin::Script.to_witness_p2sh_script(Digest::SHA256.digest(witness_script).bth) == witness_program
105
+ script = skip_separator_index > 0 ? Bitcoin::Script.new(witness_script).subscript_codeseparator(skip_separator_index) : witness_script
106
+ script_code = Bitcoin::Protocol.pack_var_string(script)
107
+ end
75
108
 
76
- end
109
+ hash_outputs = Digest::SHA256.digest(Digest::SHA256.digest(@out.map{|o|o.to_payload}.join))
110
+
111
+ case (hash_type & 0x1f)
112
+ when SIGHASH_TYPE[:single]
113
+ hash_outputs = input_idx >= @out.size ? "\x00".ljust(32, "\x00") : Digest::SHA256.digest(Digest::SHA256.digest(@out[input_idx].to_payload))
114
+ hash_sequence = "\x00".ljust(32, "\x00")
115
+ when SIGHASH_TYPE[:none]
116
+ hash_sequence = hash_outputs = "\x00".ljust(32, "\x00")
117
+ end
118
+
119
+ if (hash_type & SIGHASH_TYPE[:anyonecanpay]) != 0
120
+ hash_prevouts = hash_sequence ="\x00".ljust(32, "\x00")
121
+ end
122
+
123
+ buf = [ [@ver].pack("V"), hash_prevouts, hash_sequence, outpoint,
124
+ script_code, amount, nsequence, hash_outputs, [@lock_time, hash_type].pack("VV")].join
125
+
126
+ Digest::SHA256.digest( Digest::SHA256.digest( buf ) )
127
+ end
128
+
129
+ # verify witness input signature +in_idx+ against the corresponding
130
+ # output in +outpoint_tx+
131
+ # outpoint
132
+ #
133
+ # options are: verify_sigpushonly, verify_minimaldata, verify_cleanstack, verify_dersig, verify_low_s, verify_strictenc
134
+ def verify_witness_input_signature(in_idx, outpoint_tx_or_script, prev_out_amount, block_timestamp=Time.now.to_i, opts={})
135
+ if @enable_bitcoinconsensus
136
+ return bitcoinconsensus_verify_script(in_idx, outpoint_tx_or_script, block_timestamp, opts)
137
+ end
138
+
139
+ outpoint_idx = @in[in_idx].prev_out_index
140
+ script_sig = ''
141
+
142
+ # If given an entire previous transaction, take the script from it
143
+ script_pubkey = if outpoint_tx_or_script.respond_to?(:out)
144
+ Bitcoin::Script.new(outpoint_tx_or_script.out[outpoint_idx].pk_script)
145
+ else
146
+ # Otherwise, it's already a script.
147
+ Bitcoin::Script.new(outpoint_tx_or_script)
148
+ end
149
+
150
+ if script_pubkey.is_p2sh?
151
+ redeem_script = Bitcoin::Script.new(@in[in_idx].script_sig).get_pubkey
152
+ script_pubkey = Bitcoin::Script.new(redeem_script.htb) if Bitcoin.hash160(redeem_script) == script_pubkey.get_hash160 # P2SH-P2WPKH or P2SH-P2WSH
153
+ end
154
+
155
+ witness.tx_in_wit[in_idx].stack.each{|s|script_sig << Bitcoin::Script.pack_pushdata(s.htb)}
156
+ code_separator_index = 0
157
+
158
+ if script_pubkey.is_witness_v0_keyhash? # P2WPKH
159
+ @scripts[in_idx] = Bitcoin::Script.new(script_sig, Bitcoin::Script.to_hash160_script(script_pubkey.get_hash160))
160
+ elsif script_pubkey.is_witness_v0_scripthash? # P2WSH
161
+ witness_hex = witness.tx_in_wit[in_idx].stack.last
162
+ witness_script = Bitcoin::Script.new(witness_hex.htb)
163
+ return false unless Bitcoin.sha256(witness_hex) == script_pubkey.get_hash160
164
+ @scripts[in_idx] = Bitcoin::Script.new(script_sig, Bitcoin::Script.to_p2sh_script(Bitcoin.hash160(witness_hex)))
165
+ else
166
+ return false
167
+ end
168
+
169
+ return false if opts[:verify_sigpushonly] && !@scripts[in_idx].is_push_only?(script_sig)
170
+ return false if opts[:verify_minimaldata] && !@scripts[in_idx].pushes_are_canonical?
171
+ sig_valid = @scripts[in_idx].run(block_timestamp, opts) do |pubkey,sig,hash_type,subscript|
172
+ if script_pubkey.is_witness_v0_keyhash?
173
+ hash = signature_hash_for_witness_input(in_idx, script_pubkey.to_payload, prev_out_amount, nil, hash_type)
174
+ elsif script_pubkey.is_witness_v0_scripthash?
175
+ hash = signature_hash_for_witness_input(in_idx, script_pubkey.to_payload, prev_out_amount, witness_hex.htb, hash_type, code_separator_index)
176
+ code_separator_index += 1 if witness_script.codeseparator_count > code_separator_index
177
+ end
178
+ Bitcoin.verify_signature( hash, sig, pubkey.unpack("H*")[0] )
179
+ end
180
+ # BIP62 rule #6
181
+ return false if opts[:verify_cleanstack] && !@scripts[in_idx].stack.empty?
182
+
183
+ return sig_valid
184
+ end
185
+
186
+ # convert to ruby hash (see also #from_hash)
187
+ def to_hash(options = {})
188
+ @hash ||= hash_from_payload(to_payload)
189
+ h = {
190
+ 'hash' => @hash, 'ver' => @ver, # 'nid' => normalized_hash,
191
+ 'vin_sz' => @in.size, 'vout_sz' => @out.size,
192
+ 'lock_time' => @lock_time, 'size' => (@payload ||= to_payload).bytesize,
193
+ 'in' => @in.map.with_index{|i, index|
194
+ h = i.to_hash(options)
195
+ h.merge!('witness' => @witness.tx_in_wit[index].stack) if @witness.tx_in_wit[index]
196
+ h
197
+ },
198
+ 'out' => @out.map{|o| o.to_hash(options) }
199
+ }
200
+ h['nid'] = normalized_hash if options[:with_nid]
201
+ h
202
+ end
203
+
204
+ # parse ruby hash (see also #to_hash)
205
+ def self.from_hash(h, do_raise=true)
206
+ tx = new(nil)
207
+ tx.ver, tx.lock_time = (h['ver'] || h['version']), h['lock_time']
208
+ ins = h['in'] || h['inputs']
209
+ outs = h['out'] || h['outputs']
210
+ ins .each{|input|
211
+ tx.add_in(TxIn.from_hash(input))
212
+ tx.witness.add_witness(TxInWitness.from_hash(input['witness'])) if input['witness']
213
+ }
214
+ outs.each{|output| tx.add_out TxOut.from_hash(output) }
215
+ tx.instance_eval{ @hash = hash_from_payload(@payload = to_payload) }
216
+ if h['hash'] && (h['hash'] != tx.hash)
217
+ raise "Tx hash mismatch! Claimed: #{h['hash']}, Actual: #{tx.hash}" if do_raise
218
+ end
219
+ tx
220
+ end
221
+
222
+ # convert ruby hash to raw binary
223
+ def self.binary_from_hash(h)
224
+ tx = from_hash(h)
225
+ tx.witness.empty? ? tx.to_payload : tx.to_witness_payload
226
+ end
227
+
228
+ # get witness hash
229
+ def witness_hash
230
+ hash_from_payload(to_witness_payload)
231
+ end
232
+
233
+ end
234
+ end
235
+ end
@@ -1,22 +1,38 @@
1
- class Bitcoin::Protocol::TxInWitness
1
+ # encoding: ascii-8bit
2
2
 
3
- attr_reader :script_witness
3
+ module Bitcoin
4
4
 
5
- def initialize
6
- @script_witness = Bitcoin::Protocol::ScriptWitness.new
7
- end
5
+ module Protocol
8
6
 
9
- def add_stack(script)
10
- script_witness.stack << script
11
- end
7
+ class TxInWitness
8
+ attr_reader :script_witness
12
9
 
13
- # output witness script in raw binary format with witness
14
- def to_payload
15
- script_witness.to_payload
16
- end
10
+ def initialize
11
+ @script_witness = Bitcoin::Protocol::ScriptWitness.new
12
+ end
17
13
 
18
- def stack
19
- script_witness.stack
20
- end
14
+ # add witness script to stack
15
+ def add_stack(script)
16
+ script_witness.stack << script
17
+ end
18
+
19
+ # output witness script in raw binary format with witness
20
+ def to_payload
21
+ script_witness.to_payload
22
+ end
21
23
 
24
+ # get witness script stack
25
+ def stack
26
+ script_witness.stack
27
+ end
28
+
29
+ def self.from_hash(witnesses)
30
+ w = TxInWitness.new
31
+ witnesses.each{|item|w.add_stack(item)}
32
+ w
33
+ end
34
+
35
+ end
36
+
37
+ end
22
38
  end
@@ -1,22 +1,43 @@
1
- class Bitcoin::Protocol::TxWitness
1
+ # encoding: ascii-8bit
2
2
 
3
- attr_reader :tx_in_wit
3
+ module Bitcoin
4
+ module Protocol
4
5
 
5
- def initialize
6
- @tx_in_wit = []
7
- end
6
+ class TxWitness
8
7
 
9
- # Add witness
10
- # @param[Bitcoin::Protocol::TxInWitness] tx_in_wit witness object
11
- def add_witness(tx_in_wit)
12
- (@tx_in_wit ||= []) << tx_in_wit
13
- end
8
+ attr_reader :tx_in_wit
14
9
 
15
- # output witness in raw binary format
16
- def to_payload
17
- payload = ""
18
- tx_in_wit.each{|w|payload << w.to_payload}
19
- payload
20
- end
10
+ def initialize
11
+ @tx_in_wit = []
12
+ end
13
+
14
+ # Add witness
15
+ # @param[Bitcoin::Protocol::TxInWitness] tx_in_wit witness object
16
+ def add_witness(tx_in_wit)
17
+ (@tx_in_wit ||= []) << tx_in_wit
18
+ end
19
+
20
+ # add empty witness
21
+ def add_empty_witness
22
+ add_witness(TxInWitness.new)
23
+ end
21
24
 
25
+ # output witness in raw binary format
26
+ def to_payload
27
+ payload = ""
28
+ @tx_in_wit.each{|w|payload << w.to_payload}
29
+ payload
30
+ end
31
+
32
+ def size
33
+ tx_in_wit.length
34
+ end
35
+
36
+ def empty?
37
+ size == 0
38
+ end
39
+
40
+ end
41
+
42
+ end
22
43
  end
data/lib/segwit.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # This is a temporary implementation until bitcoin-ruby formally supports Segregated Witness.
2
+ # This implementation ported from the implementation of the pull request below.
3
+ # https://github.com/lian/bitcoin-ruby/pull/203
1
4
  module Bitcoin
2
5
  module Protocol
3
6
  require 'segwit/tx'
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.bindir = "exe"
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
- spec.add_runtime_dependency "bitcoin-ruby", "~> 0.0.7"
21
+ spec.add_runtime_dependency "bitcoin-ruby", "~> 0.0.10"
22
22
  spec.add_runtime_dependency "ffi", "~>1.9.8"
23
23
  spec.add_runtime_dependency "rest-client", "~>1.8.0"
24
24
  spec.add_runtime_dependency "httpclient"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openassets-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-02-17 00:00:00.000000000 Z
11
+ date: 2017-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bitcoin-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.7
19
+ version: 0.0.10
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.0.7
26
+ version: 0.0.10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ffi
29
29
  requirement: !ruby/object:Gem::Requirement