tapyrus 0.1.0 → 0.2.4
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/README.md +7 -15
- data/exe/tapyrusrbd +2 -2
- data/lib/openassets/util.rb +2 -4
- data/lib/schnorr.rb +83 -0
- data/lib/schnorr/signature.rb +38 -0
- data/lib/tapyrus.rb +11 -18
- data/lib/tapyrus/block.rb +3 -38
- data/lib/tapyrus/block_header.rb +70 -41
- data/lib/tapyrus/chain_params.rb +13 -36
- data/lib/tapyrus/chainparams/{regtest.yml → dev.yml} +10 -19
- data/lib/tapyrus/chainparams/{mainnet.yml → prod.yml} +7 -19
- data/lib/tapyrus/constants.rb +12 -34
- data/lib/tapyrus/errors.rb +17 -0
- data/lib/tapyrus/ext.rb +5 -0
- data/lib/tapyrus/ext/ecdsa.rb +39 -0
- data/lib/tapyrus/ext/json_parser.rb +47 -0
- data/lib/tapyrus/ext_key.rb +42 -23
- data/lib/tapyrus/key.rb +47 -40
- data/lib/tapyrus/message.rb +2 -2
- data/lib/tapyrus/message/base.rb +1 -0
- data/lib/tapyrus/message/block.rb +4 -4
- data/lib/tapyrus/message/cmpct_block.rb +3 -5
- data/lib/tapyrus/message/header_and_short_ids.rb +1 -1
- data/lib/tapyrus/message/headers.rb +1 -1
- data/lib/tapyrus/message/merkle_block.rb +1 -1
- data/lib/tapyrus/message/tx.rb +2 -2
- data/lib/tapyrus/network/peer.rb +1 -15
- data/lib/tapyrus/node/cli.rb +15 -11
- data/lib/tapyrus/node/configuration.rb +1 -1
- data/lib/tapyrus/node/spv.rb +1 -1
- data/lib/tapyrus/opcodes.rb +5 -0
- data/lib/tapyrus/out_point.rb +1 -1
- data/lib/tapyrus/rpc/request_handler.rb +7 -6
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +17 -15
- data/lib/tapyrus/script/color.rb +79 -0
- data/lib/tapyrus/script/multisig.rb +0 -27
- data/lib/tapyrus/script/script.rb +74 -89
- data/lib/tapyrus/script/script_error.rb +8 -14
- data/lib/tapyrus/script/script_interpreter.rb +65 -86
- data/lib/tapyrus/script/tx_checker.rb +21 -5
- data/lib/tapyrus/secp256k1.rb +1 -0
- data/lib/tapyrus/secp256k1/native.rb +93 -20
- data/lib/tapyrus/secp256k1/rfc6979.rb +43 -0
- data/lib/tapyrus/secp256k1/ruby.rb +63 -54
- data/lib/tapyrus/store/chain_entry.rb +3 -2
- data/lib/tapyrus/store/db/level_db.rb +58 -0
- data/lib/tapyrus/store/spv_chain.rb +29 -11
- data/lib/tapyrus/tx.rb +18 -160
- data/lib/tapyrus/tx_in.rb +4 -11
- data/lib/tapyrus/tx_out.rb +2 -1
- data/lib/tapyrus/util.rb +8 -0
- data/lib/tapyrus/validation.rb +1 -6
- data/lib/tapyrus/version.rb +1 -1
- data/lib/tapyrus/wallet/account.rb +1 -0
- data/lib/tapyrus/wallet/master_key.rb +1 -0
- data/tapyrusrb.gemspec +3 -3
- metadata +44 -39
- data/lib/tapyrus/chainparams/testnet.yml +0 -41
- data/lib/tapyrus/descriptor.rb +0 -147
- data/lib/tapyrus/script_witness.rb +0 -38
data/lib/tapyrus/version.rb
CHANGED
data/tapyrusrb.gemspec
CHANGED
@@ -23,25 +23,25 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_runtime_dependency 'ecdsa'
|
24
24
|
spec.add_runtime_dependency 'eventmachine'
|
25
25
|
spec.add_runtime_dependency 'murmurhash3'
|
26
|
-
spec.add_runtime_dependency 'bech32', '~> 1.0.3'
|
27
26
|
spec.add_runtime_dependency 'daemon-spawn'
|
28
27
|
spec.add_runtime_dependency 'thor'
|
29
28
|
spec.add_runtime_dependency 'ffi'
|
30
29
|
spec.add_runtime_dependency 'leb128', '~> 1.0.0'
|
31
30
|
spec.add_runtime_dependency 'eventmachine_httpserver'
|
32
|
-
spec.add_runtime_dependency 'rest-client'
|
33
31
|
spec.add_runtime_dependency 'iniparse'
|
34
32
|
spec.add_runtime_dependency 'siphash'
|
35
33
|
spec.add_runtime_dependency 'protobuf', '3.8.5'
|
36
34
|
spec.add_runtime_dependency 'scrypt'
|
37
35
|
spec.add_runtime_dependency 'activesupport', '>= 5.2.3'
|
36
|
+
spec.add_runtime_dependency 'json_pure', '>= 2.3.1'
|
38
37
|
|
39
38
|
# for options
|
40
39
|
spec.add_development_dependency 'leveldb-native'
|
41
40
|
|
42
41
|
spec.add_development_dependency 'bundler'
|
43
|
-
spec.add_development_dependency 'rake', '
|
42
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
44
43
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
45
44
|
spec.add_development_dependency 'timecop'
|
45
|
+
spec.add_development_dependency 'webmock', '~> 3.0'
|
46
46
|
|
47
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tapyrus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bech32
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 1.0.3
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 1.0.3
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: daemon-spawn
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,20 +122,6 @@ dependencies:
|
|
136
122
|
- - ">="
|
137
123
|
- !ruby/object:Gem::Version
|
138
124
|
version: '0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rest-client
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :runtime
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
125
|
- !ruby/object:Gem::Dependency
|
154
126
|
name: iniparse
|
155
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,6 +192,20 @@ dependencies:
|
|
220
192
|
- - ">="
|
221
193
|
- !ruby/object:Gem::Version
|
222
194
|
version: 5.2.3
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: json_pure
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 2.3.1
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 2.3.1
|
223
209
|
- !ruby/object:Gem::Dependency
|
224
210
|
name: leveldb-native
|
225
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -252,16 +238,16 @@ dependencies:
|
|
252
238
|
name: rake
|
253
239
|
requirement: !ruby/object:Gem::Requirement
|
254
240
|
requirements:
|
255
|
-
- - "
|
241
|
+
- - ">="
|
256
242
|
- !ruby/object:Gem::Version
|
257
|
-
version:
|
243
|
+
version: 12.3.3
|
258
244
|
type: :development
|
259
245
|
prerelease: false
|
260
246
|
version_requirements: !ruby/object:Gem::Requirement
|
261
247
|
requirements:
|
262
|
-
- - "
|
248
|
+
- - ">="
|
263
249
|
- !ruby/object:Gem::Version
|
264
|
-
version:
|
250
|
+
version: 12.3.3
|
265
251
|
- !ruby/object:Gem::Dependency
|
266
252
|
name: rspec
|
267
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -290,6 +276,20 @@ dependencies:
|
|
290
276
|
- - ">="
|
291
277
|
- !ruby/object:Gem::Version
|
292
278
|
version: '0'
|
279
|
+
- !ruby/object:Gem::Dependency
|
280
|
+
name: webmock
|
281
|
+
requirement: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - "~>"
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '3.0'
|
286
|
+
type: :development
|
287
|
+
prerelease: false
|
288
|
+
version_requirements: !ruby/object:Gem::Requirement
|
289
|
+
requirements:
|
290
|
+
- - "~>"
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '3.0'
|
293
293
|
description: "[WIP]The implementation of Tapyrus Protocol for Ruby."
|
294
294
|
email:
|
295
295
|
- azuchi@chaintope.com
|
@@ -317,17 +317,21 @@ files:
|
|
317
317
|
- lib/openassets/marker_output.rb
|
318
318
|
- lib/openassets/payload.rb
|
319
319
|
- lib/openassets/util.rb
|
320
|
+
- lib/schnorr.rb
|
321
|
+
- lib/schnorr/signature.rb
|
320
322
|
- lib/tapyrus.rb
|
321
323
|
- lib/tapyrus/base58.rb
|
322
324
|
- lib/tapyrus/block.rb
|
323
325
|
- lib/tapyrus/block_header.rb
|
324
326
|
- lib/tapyrus/bloom_filter.rb
|
325
327
|
- lib/tapyrus/chain_params.rb
|
326
|
-
- lib/tapyrus/chainparams/
|
327
|
-
- lib/tapyrus/chainparams/
|
328
|
-
- lib/tapyrus/chainparams/testnet.yml
|
328
|
+
- lib/tapyrus/chainparams/dev.yml
|
329
|
+
- lib/tapyrus/chainparams/prod.yml
|
329
330
|
- lib/tapyrus/constants.rb
|
330
|
-
- lib/tapyrus/
|
331
|
+
- lib/tapyrus/errors.rb
|
332
|
+
- lib/tapyrus/ext.rb
|
333
|
+
- lib/tapyrus/ext/ecdsa.rb
|
334
|
+
- lib/tapyrus/ext/json_parser.rb
|
331
335
|
- lib/tapyrus/ext_key.rb
|
332
336
|
- lib/tapyrus/key.rb
|
333
337
|
- lib/tapyrus/key_path.rb
|
@@ -394,14 +398,15 @@ files:
|
|
394
398
|
- lib/tapyrus/rpc/http_server.rb
|
395
399
|
- lib/tapyrus/rpc/request_handler.rb
|
396
400
|
- lib/tapyrus/rpc/tapyrus_core_client.rb
|
401
|
+
- lib/tapyrus/script/color.rb
|
397
402
|
- lib/tapyrus/script/multisig.rb
|
398
403
|
- lib/tapyrus/script/script.rb
|
399
404
|
- lib/tapyrus/script/script_error.rb
|
400
405
|
- lib/tapyrus/script/script_interpreter.rb
|
401
406
|
- lib/tapyrus/script/tx_checker.rb
|
402
|
-
- lib/tapyrus/script_witness.rb
|
403
407
|
- lib/tapyrus/secp256k1.rb
|
404
408
|
- lib/tapyrus/secp256k1/native.rb
|
409
|
+
- lib/tapyrus/secp256k1/rfc6979.rb
|
405
410
|
- lib/tapyrus/secp256k1/ruby.rb
|
406
411
|
- lib/tapyrus/slip39.rb
|
407
412
|
- lib/tapyrus/slip39/share.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
--- !ruby/object:Tapyrus::ChainParams
|
2
|
-
network: "testnet"
|
3
|
-
magic_head: "0b110907"
|
4
|
-
message_magic: "Bitcoin Signed Message:\n"
|
5
|
-
address_version: "6f"
|
6
|
-
p2sh_version: "c4"
|
7
|
-
bech32_hrp: 'tb'
|
8
|
-
privkey_version: "ef"
|
9
|
-
extended_privkey_version: "04358394"
|
10
|
-
extended_pubkey_version: "043587cf"
|
11
|
-
bip49_pubkey_p2wpkh_p2sh_version: "044a5262"
|
12
|
-
bip49_pubkey_p2wsh_p2sh_version: "024285ef"
|
13
|
-
bip49_privkey_p2wpkh_p2sh_version: "044a4e28"
|
14
|
-
bip49_privkey_p2wsh_p2sh_version: "024285b5"
|
15
|
-
bip84_pubkey_p2wpkh_version: "045f1cf6"
|
16
|
-
bip84_pubkey_p2wsh_version: "02575483"
|
17
|
-
bip84_privkey_p2wpkh_version: "045f18bc"
|
18
|
-
bip84_privkey_p2wsh_version: "02575048"
|
19
|
-
default_port: 18333
|
20
|
-
protocol_version: 70013
|
21
|
-
retarget_interval: 2016
|
22
|
-
retarget_time: 1209600 # 2 weeks
|
23
|
-
target_spacing: 600 # block interval
|
24
|
-
max_money: 21000000
|
25
|
-
bip34_height: 227931
|
26
|
-
genesis_hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
27
|
-
proof_of_work_limit: 0x1d00ffff
|
28
|
-
dns_seeds:
|
29
|
-
- "testnet-seed.bitcoin.jonasschnelli.ch"
|
30
|
-
- "seed.tbtc.petertodd.org"
|
31
|
-
- "testnet-seed.bluematt.me"
|
32
|
-
- "testnet-seed.bitcoin.schildbach.de"
|
33
|
-
genesis:
|
34
|
-
hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
|
35
|
-
merkle_root: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
36
|
-
time: 1296688602
|
37
|
-
nonce: 414098458
|
38
|
-
bits: 0x1d00ffff
|
39
|
-
version: 1
|
40
|
-
prev_hash: "0000000000000000000000000000000000000000000000000000000000000000"
|
41
|
-
bip44_coin_type: 1
|
data/lib/tapyrus/descriptor.rb
DELETED
@@ -1,147 +0,0 @@
|
|
1
|
-
module Tapyrus
|
2
|
-
|
3
|
-
module Descriptor
|
4
|
-
|
5
|
-
include Tapyrus::Opcodes
|
6
|
-
|
7
|
-
# generate P2PK output for the given public key.
|
8
|
-
# @param [String] key private key or public key with hex format
|
9
|
-
# @return [Tapyrus::Script] P2PK script.
|
10
|
-
def pk(key)
|
11
|
-
Tapyrus::Script.new << extract_pubkey(key) << OP_CHECKSIG
|
12
|
-
end
|
13
|
-
|
14
|
-
# generate P2PKH output for the given public key.
|
15
|
-
# @param [String] key private key or public key with hex format.
|
16
|
-
# @return [Tapyrus::Script] P2PKH script.
|
17
|
-
def pkh(key)
|
18
|
-
Tapyrus::Script.to_p2pkh(Tapyrus.hash160(extract_pubkey(key)))
|
19
|
-
end
|
20
|
-
|
21
|
-
# generate P2PKH output for the given public key.
|
22
|
-
# @param [String] key private key or public key with hex format.
|
23
|
-
# @return [Tapyrus::Script] P2WPKH script.
|
24
|
-
def wpkh(key)
|
25
|
-
pubkey = extract_pubkey(key)
|
26
|
-
raise ArgumentError, "Uncompressed key are not allowed." unless compressed_key?(pubkey)
|
27
|
-
Tapyrus::Script.to_p2wpkh(Tapyrus.hash160(pubkey))
|
28
|
-
end
|
29
|
-
|
30
|
-
# generate P2SH embed the argument.
|
31
|
-
# @param [String or Script] script script to be embed.
|
32
|
-
# @return [Tapyrus::Script] P2SH script.
|
33
|
-
def sh(script)
|
34
|
-
script = script.to_hex if script.is_a?(Tapyrus::Script)
|
35
|
-
raise ArgumentError, "P2SH script is too large, 547 bytes is larger than #{Tapyrus::MAX_SCRIPT_ELEMENT_SIZE} bytes." if script.htb.bytesize > Tapyrus::MAX_SCRIPT_ELEMENT_SIZE
|
36
|
-
Tapyrus::Script.to_p2sh(Tapyrus.hash160(script))
|
37
|
-
end
|
38
|
-
|
39
|
-
# generate P2WSH embed the argument.
|
40
|
-
# @param [String or Script] script script to be embed.
|
41
|
-
# @return [Tapyrus::Script] P2WSH script.
|
42
|
-
def wsh(script)
|
43
|
-
script = Tapyrus::Script(script.htb) if script.is_a?(String)
|
44
|
-
raise ArgumentError, "P2SH script is too large, 547 bytes is larger than #{Tapyrus::MAX_SCRIPT_ELEMENT_SIZE} bytes." if script.to_payload.bytesize > Tapyrus::MAX_SCRIPT_ELEMENT_SIZE
|
45
|
-
raise ArgumentError, "Uncompressed key are not allowed." if script.get_pubkeys.any?{|p|!compressed_key?(p)}
|
46
|
-
Tapyrus::Script.to_p2wsh(script)
|
47
|
-
end
|
48
|
-
|
49
|
-
# an alias for the collection of `pk(KEY)` and `pkh(KEY)`.
|
50
|
-
# If the key is compressed, it also includes `wpkh(KEY)` and `sh(wpkh(KEY))`.
|
51
|
-
# @param [String] key private key or public key with hex format.
|
52
|
-
# @return [Array[Tapyrus::Script]]
|
53
|
-
def combo(key)
|
54
|
-
result = [pk(key), pkh(key)]
|
55
|
-
pubkey = extract_pubkey(key)
|
56
|
-
if compressed_key?(pubkey)
|
57
|
-
result << wpkh(key)
|
58
|
-
result << sh(result.last)
|
59
|
-
end
|
60
|
-
result
|
61
|
-
end
|
62
|
-
|
63
|
-
# generate multisig output for given keys.
|
64
|
-
# @param [Integer] threshold the threshold of multisig.
|
65
|
-
# @param [Array[String]] keys an array of keys.
|
66
|
-
# @return [Tapyrus::Script] multisig script.
|
67
|
-
def multi(threshold, *keys, sort: false)
|
68
|
-
raise ArgumentError, 'Multisig threshold is not valid.' unless threshold.is_a?(Integer)
|
69
|
-
raise ArgumentError, 'Multisig threshold cannot be 0, must be at least 1.' unless threshold > 0
|
70
|
-
raise ArgumentError, 'Multisig threshold cannot be larger than the number of keys.' if threshold > keys.size
|
71
|
-
raise ArgumentError, 'Multisig must have between 1 and 16 keys, inclusive.' if keys.size > 16
|
72
|
-
pubkeys = keys.map{|key| extract_pubkey(key) }
|
73
|
-
Tapyrus::Script.to_multisig_script(threshold, pubkeys, sort: sort)
|
74
|
-
end
|
75
|
-
|
76
|
-
# generate sorted multisig output for given keys.
|
77
|
-
# @param [Integer] threshold the threshold of multisig.
|
78
|
-
# @param [Array[String]] keys an array of keys.
|
79
|
-
# @return [Tapyrus::Script] multisig script.
|
80
|
-
def sortedmulti(threshold, *keys)
|
81
|
-
multi(threshold, *keys, sort: true)
|
82
|
-
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
# extract public key from KEY format.
|
87
|
-
# @param [String] key KEY string.
|
88
|
-
# @return [String] public key.
|
89
|
-
def extract_pubkey(key)
|
90
|
-
if key.start_with?('[') # BIP32 fingerprint
|
91
|
-
raise ArgumentError, 'Invalid key origin.' if key.count('[') > 1 || key.count(']') > 1
|
92
|
-
info = key[1...key.index(']')] # TODO
|
93
|
-
fingerprint, *paths = info.split('/')
|
94
|
-
raise ArgumentError, 'Fingerprint is not hex.' unless fingerprint.valid_hex?
|
95
|
-
raise ArgumentError, 'Fingerprint is not 4 bytes.' unless fingerprint.size == 8
|
96
|
-
key = key[(key.index(']') + 1)..-1]
|
97
|
-
else
|
98
|
-
raise ArgumentError, 'Invalid key origin.' if key.include?(']')
|
99
|
-
end
|
100
|
-
|
101
|
-
# check BIP32 derivation path
|
102
|
-
key, *paths = key.split('/')
|
103
|
-
|
104
|
-
if key.start_with?('xprv')
|
105
|
-
key = Tapyrus::ExtKey.from_base58(key)
|
106
|
-
key = derive_path(key, paths, true) if paths
|
107
|
-
elsif key.start_with?('xpub')
|
108
|
-
key = Tapyrus::ExtPubkey.from_base58(key)
|
109
|
-
key = derive_path(key, paths, false) if paths
|
110
|
-
else
|
111
|
-
begin
|
112
|
-
key = Tapyrus::Key.from_wif(key)
|
113
|
-
rescue ArgumentError
|
114
|
-
key_type = compressed_key?(key) ? Tapyrus::Key::TYPES[:compressed] : Tapyrus::Key::TYPES[:uncompressed]
|
115
|
-
key = Tapyrus::Key.new(pubkey: key, key_type: key_type)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
key = key.is_a?(Tapyrus::Key) ? key : key.key
|
119
|
-
raise ArgumentError, 'Invalid pubkey.' unless key.fully_valid_pubkey?
|
120
|
-
key.pubkey
|
121
|
-
end
|
122
|
-
|
123
|
-
def compressed_key?(key)
|
124
|
-
%w(02 03).include?(key[0..1]) && [key].pack("H*").bytesize == 33
|
125
|
-
end
|
126
|
-
|
127
|
-
def derive_path(key, paths, is_private)
|
128
|
-
paths.each do |path|
|
129
|
-
raise ArgumentError, 'xpub can not derive hardened key.' if !is_private && path.end_with?("'")
|
130
|
-
if is_private
|
131
|
-
hardened = path.end_with?("'")
|
132
|
-
path = hardened ? path[0..-2] : path
|
133
|
-
raise ArgumentError, 'Key path value is not a valid value.' unless path =~ /^[0-9]+$/
|
134
|
-
raise ArgumentError, 'Key path value is out of range.' if !hardened && path.to_i >= Tapyrus::HARDENED_THRESHOLD
|
135
|
-
key = key.derive(path.to_i, hardened)
|
136
|
-
else
|
137
|
-
raise ArgumentError, 'Key path value is not a valid value.' unless path =~ /^[0-9]+$/
|
138
|
-
raise ArgumentError, 'Key path value is out of range.' if path.to_i >= Tapyrus::HARDENED_THRESHOLD
|
139
|
-
key = key.derive(path.to_i)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
key
|
143
|
-
end
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module Tapyrus
|
2
|
-
|
3
|
-
# witness
|
4
|
-
class ScriptWitness
|
5
|
-
|
6
|
-
attr_reader :stack
|
7
|
-
|
8
|
-
def initialize(stack = [])
|
9
|
-
@stack = stack
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.parse_from_payload(payload)
|
13
|
-
buf = payload.is_a?(StringIO) ? payload : StringIO.new(payload)
|
14
|
-
size = Tapyrus.unpack_var_int_from_io(buf)
|
15
|
-
stack = size.times.map do
|
16
|
-
buf.read(Tapyrus.unpack_var_int_from_io(buf))
|
17
|
-
end
|
18
|
-
self.new(stack)
|
19
|
-
end
|
20
|
-
|
21
|
-
def empty?
|
22
|
-
stack.empty?
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_payload
|
26
|
-
p = Tapyrus.pack_var_int(stack.size)
|
27
|
-
p << stack.map { |s|
|
28
|
-
Tapyrus.pack_var_int(s.bytesize) << s
|
29
|
-
}.join
|
30
|
-
end
|
31
|
-
|
32
|
-
def to_s
|
33
|
-
stack.map{|s|s.bth}.join(' ')
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|