openassets-ruby 0.6.1 → 0.6.2

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 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