openassets-ruby 0.6.4 → 0.6.5
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 +2 -0
- data/lib/openassets.rb +1 -1
- data/lib/openassets/version.rb +1 -1
- data/openassets-ruby.gemspec +1 -1
- metadata +5 -11
- data/lib/segwit.rb +0 -12
- data/lib/segwit/script.rb +0 -78
- data/lib/segwit/script_witness.rb +0 -35
- data/lib/segwit/tx.rb +0 -235
- data/lib/segwit/tx_in_witness.rb +0 -38
- data/lib/segwit/tx_witness.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f4f00149febc1e6b4b339fb9a9129befccff7be
|
4
|
+
data.tar.gz: ef6701a208bd54ed9bfc99f5d2df6ac2299c76b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 999d13563e91a619f001ec4941077e7825de88735a6ad460389e2956d3fe843ba0b2e0a3577731862cecbbdcfef0eeffc9d67526630ae3b3354a2a348581d831
|
7
|
+
data.tar.gz: e15ec20eda29fc0d2c01632457c79e8148c28b1af73be73f7a27b931f0695c3273250e02680cf7e18c11bbeb332819558d705bc503201b2d53d86cdf476ab5b5
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.4.1
|
data/.travis.yml
CHANGED
data/lib/openassets.rb
CHANGED
data/lib/openassets/version.rb
CHANGED
data/openassets-ruby.gemspec
CHANGED
@@ -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.
|
21
|
+
spec.add_runtime_dependency "bitcoin-ruby", "~> 0.0.11"
|
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.
|
4
|
+
version: 0.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06
|
11
|
+
date: 2017-07-06 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.
|
19
|
+
version: 0.0.11
|
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.
|
26
|
+
version: 0.0.11
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ffi
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,12 +218,6 @@ files:
|
|
218
218
|
- lib/openassets/transaction/transfer_parameters.rb
|
219
219
|
- lib/openassets/util.rb
|
220
220
|
- lib/openassets/version.rb
|
221
|
-
- lib/segwit.rb
|
222
|
-
- lib/segwit/script.rb
|
223
|
-
- lib/segwit/script_witness.rb
|
224
|
-
- lib/segwit/tx.rb
|
225
|
-
- lib/segwit/tx_in_witness.rb
|
226
|
-
- lib/segwit/tx_witness.rb
|
227
221
|
- openassets-ruby.gemspec
|
228
222
|
homepage: https://github.com/haw-itn/openassets-ruby
|
229
223
|
licenses:
|
@@ -245,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
245
239
|
version: '0'
|
246
240
|
requirements: []
|
247
241
|
rubyforge_project:
|
248
|
-
rubygems_version: 2.
|
242
|
+
rubygems_version: 2.6.11
|
249
243
|
signing_key:
|
250
244
|
specification_version: 4
|
251
245
|
summary: The implementation of the Open Assets Protocol for Ruby.
|
data/lib/segwit.rb
DELETED
@@ -1,12 +0,0 @@
|
|
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
|
4
|
-
module Bitcoin
|
5
|
-
module Protocol
|
6
|
-
require 'segwit/tx'
|
7
|
-
require 'segwit/script'
|
8
|
-
autoload :TxWitness, 'segwit/tx_witness'
|
9
|
-
autoload :TxInWitness, 'segwit/tx_in_witness'
|
10
|
-
autoload :ScriptWitness, 'segwit/script_witness'
|
11
|
-
end
|
12
|
-
end
|
data/lib/segwit/script.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
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
|
18
|
-
def is_standard?
|
19
|
-
is_pubkey? || is_hash160? || is_multisig? || is_p2sh? || is_op_return? || is_witness_v0_keyhash? || is_witness_v0_scripthash?
|
20
|
-
end
|
21
|
-
|
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
|
28
|
-
def is_witness_v0_keyhash?
|
29
|
-
@chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 20
|
30
|
-
end
|
31
|
-
|
32
|
-
# is this a witness script hash
|
33
|
-
def is_witness_v0_scripthash?
|
34
|
-
@chunks.length == 2 &&@chunks[0] == 0 && @chunks[1].is_a?(String) && @chunks[1].bytesize == 32
|
35
|
-
end
|
36
|
-
|
37
|
-
# get type of this tx
|
38
|
-
def type
|
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
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
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
|
58
|
-
|
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
|
78
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
|
5
|
-
module Protocol
|
6
|
-
|
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
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
data/lib/segwit/tx.rb
DELETED
@@ -1,235 +0,0 @@
|
|
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
|
24
|
-
end
|
25
|
-
|
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
|
30
|
-
|
31
|
-
@ver = buf.read(4).unpack("V").first
|
32
|
-
|
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
|
108
|
-
|
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
|
data/lib/segwit/tx_in_witness.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
|
5
|
-
module Protocol
|
6
|
-
|
7
|
-
class TxInWitness
|
8
|
-
attr_reader :script_witness
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@script_witness = Bitcoin::Protocol::ScriptWitness.new
|
12
|
-
end
|
13
|
-
|
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
|
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
|
38
|
-
end
|
data/lib/segwit/tx_witness.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
module Bitcoin
|
4
|
-
module Protocol
|
5
|
-
|
6
|
-
class TxWitness
|
7
|
-
|
8
|
-
attr_reader :tx_in_wit
|
9
|
-
|
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
|
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
|
43
|
-
end
|