tapyrus 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -14
- 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 +9 -11
- data/lib/tapyrus/block.rb +1 -32
- data/lib/tapyrus/block_header.rb +7 -6
- data/lib/tapyrus/chain_params.rb +13 -26
- data/lib/tapyrus/chainparams/{testnet.yml → dev.yml} +7 -9
- data/lib/tapyrus/chainparams/{mainnet.yml → prod.yml} +7 -10
- data/lib/tapyrus/constants.rb +12 -34
- data/lib/tapyrus/ext.rb +5 -0
- data/lib/tapyrus/ext/json_parser.rb +47 -0
- data/lib/tapyrus/ext_key.rb +5 -10
- data/lib/tapyrus/key.rb +57 -29
- data/lib/tapyrus/message.rb +2 -2
- data/lib/tapyrus/message/base.rb +1 -0
- data/lib/tapyrus/message/block.rb +3 -3
- data/lib/tapyrus/message/cmpct_block.rb +3 -5
- 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 +3 -3
- 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 +16 -4
- data/lib/tapyrus/secp256k1.rb +1 -0
- data/lib/tapyrus/secp256k1/rfc6979.rb +43 -0
- data/lib/tapyrus/secp256k1/ruby.rb +5 -31
- data/lib/tapyrus/store/chain_entry.rb +1 -0
- 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 +42 -39
- data/lib/tapyrus/chainparams/regtest.yml +0 -38
- data/lib/tapyrus/descriptor.rb +0 -147
- data/lib/tapyrus/script_witness.rb +0 -38
@@ -1,10 +1,11 @@
|
|
1
1
|
--- !ruby/object:Tapyrus::ChainParams
|
2
|
-
network: "
|
2
|
+
network: "prod"
|
3
3
|
magic_head: "f9beb4d9"
|
4
|
-
message_magic: "
|
4
|
+
message_magic: "Tapyrus Signed Message:\n"
|
5
5
|
address_version: "00"
|
6
6
|
p2sh_version: "05"
|
7
|
-
|
7
|
+
cp2pkh_version: "01"
|
8
|
+
cp2sh_version: "06"
|
8
9
|
privkey_version: "80"
|
9
10
|
extended_privkey_version: "0488ade4"
|
10
11
|
extended_pubkey_version: "0488b21e"
|
@@ -16,8 +17,9 @@ bip84_pubkey_p2wpkh_version: "04b24746"
|
|
16
17
|
bip84_pubkey_p2wsh_version: "02aa7ed3"
|
17
18
|
bip84_privkey_p2wpkh_version: "04b2430c"
|
18
19
|
bip84_privkey_p2wsh_version: "02aa7a99"
|
19
|
-
default_port:
|
20
|
-
|
20
|
+
default_port: 2357
|
21
|
+
rpc_port: 2377
|
22
|
+
protocol_version: 10000
|
21
23
|
retarget_interval: 2016
|
22
24
|
retarget_time: 1209600 # 2 weeks
|
23
25
|
target_spacing: 600 # block interval
|
@@ -25,11 +27,6 @@ max_money: 21000000
|
|
25
27
|
bip34_height: 227931
|
26
28
|
proof_of_work_limit: 0x1d00ffff
|
27
29
|
dns_seeds:
|
28
|
-
- "seed.bitcoin.sipa.be"
|
29
|
-
- "dnsseed.bluematt.me"
|
30
|
-
- "dnsseed.bitcoin.dashjr.org"
|
31
|
-
- "seed.bitcoinstats.com"
|
32
|
-
- "seed.bitcoin.jonasschnelli.ch"
|
33
30
|
genesis:
|
34
31
|
hash: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
35
32
|
merkle_root: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
|
data/lib/tapyrus/constants.rb
CHANGED
@@ -38,11 +38,8 @@ module Tapyrus
|
|
38
38
|
SCRIPT_VERIFY_CLEANSTACK = (1 << 8)
|
39
39
|
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1 << 9) # Verify CHECKLOCKTIMEVERIFY (BIP-65)
|
40
40
|
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1 << 10) # support CHECKSEQUENCEVERIFY opcode (BIP-112)
|
41
|
-
SCRIPT_VERIFY_WITNESS = (1 << 11) # Support segregated witness
|
42
|
-
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = (1 << 12) # Making v1-v16 witness program non-standard
|
43
41
|
SCRIPT_VERIFY_MINIMALIF = (1 << 13) # Segwit script only: Require the argument of OP_IF/NOTIF to be exactly 0x01 or empty vector
|
44
42
|
SCRIPT_VERIFY_NULLFAIL = (1 << 14) # Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
|
45
|
-
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE = (1 << 15) # Public keys in segregated witness scripts must be compressed
|
46
43
|
SCRIPT_VERIFY_CONST_SCRIPTCODE = (1 << 16) # Making OP_CODESEPARATOR and FindAndDelete fail any non-segwit scripts
|
47
44
|
|
48
45
|
MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH
|
@@ -60,16 +57,10 @@ module Tapyrus
|
|
60
57
|
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY,
|
61
58
|
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY,
|
62
59
|
SCRIPT_VERIFY_LOW_S,
|
63
|
-
SCRIPT_VERIFY_WITNESS,
|
64
|
-
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,
|
65
|
-
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE,
|
66
60
|
SCRIPT_VERIFY_CONST_SCRIPTCODE].inject(SCRIPT_VERIFY_NONE){|flags, f| flags |= f}
|
67
61
|
|
68
62
|
# for script
|
69
63
|
|
70
|
-
# witness version
|
71
|
-
WITNESS_VERSION = 0x00
|
72
|
-
|
73
64
|
# Maximum script length in bytes
|
74
65
|
MAX_SCRIPT_SIZE = 10000
|
75
66
|
|
@@ -91,20 +82,13 @@ module Tapyrus
|
|
91
82
|
# Signature hash types/flags
|
92
83
|
SIGHASH_TYPE = { all: 1, none: 2, single: 3, anyonecanpay: 128 }
|
93
84
|
|
94
|
-
# SIGHASH_FORK_ID for replay protection of the fork coin
|
95
|
-
SIGHASH_FORK_ID = 0x40
|
96
|
-
|
97
|
-
# fork coin id.
|
98
|
-
FORK_ID_CASH = 0
|
99
|
-
FORK_ID_GOLD = 79
|
100
|
-
|
101
85
|
# Maximum number length in bytes
|
102
86
|
DEFAULT_MAX_NUM_SIZE = 4
|
103
87
|
|
104
88
|
# 80 bytes of data, +1 for OP_RETURN, +2 for the pushdata opcodes.
|
105
89
|
MAX_OP_RETURN_RELAY = 83
|
106
90
|
|
107
|
-
SIG_VERSION = [:base
|
91
|
+
SIG_VERSION = [:base]
|
108
92
|
|
109
93
|
# for script error
|
110
94
|
SCRIPT_ERR_OK = 0
|
@@ -126,6 +110,7 @@ module Tapyrus
|
|
126
110
|
SCRIPT_ERR_CHECKMULTISIGVERIFY = 22
|
127
111
|
SCRIPT_ERR_CHECKSIGVERIFY = 23
|
128
112
|
SCRIPT_ERR_NUMEQUALVERIFY = 24
|
113
|
+
SCRIPT_ERR_CHECKDATASIGVERIFY = 25
|
129
114
|
|
130
115
|
# Logical/Format/Canonical errors
|
131
116
|
SCRIPT_ERR_BAD_OPCODE = 30
|
@@ -133,6 +118,7 @@ module Tapyrus
|
|
133
118
|
SCRIPT_ERR_INVALID_STACK_OPERATION = 32
|
134
119
|
SCRIPT_ERR_INVALID_ALTSTACK_OPERATION = 33
|
135
120
|
SCRIPT_ERR_UNBALANCED_CONDITIONAL = 34
|
121
|
+
SCRIPT_ERR_MIXED_SCHEME_MULTISIG = 35
|
136
122
|
|
137
123
|
# CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY
|
138
124
|
SCRIPT_ERR_NEGATIVE_LOCKTIME = 40
|
@@ -146,35 +132,27 @@ module Tapyrus
|
|
146
132
|
SCRIPT_ERR_SIG_HIGH_S = 54
|
147
133
|
SCRIPT_ERR_SIG_NULLDUMMY = 55
|
148
134
|
SCRIPT_ERR_PUBKEYTYPE = 56
|
149
|
-
SCRIPT_ERR_CLEANSTACK =
|
150
|
-
SCRIPT_ERR_MINIMALIF =
|
151
|
-
SCRIPT_ERR_SIG_NULLFAIL =
|
135
|
+
SCRIPT_ERR_CLEANSTACK = 57
|
136
|
+
SCRIPT_ERR_MINIMALIF = 58
|
137
|
+
SCRIPT_ERR_SIG_NULLFAIL = 59
|
152
138
|
|
153
139
|
# softfork safeness
|
154
140
|
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS = 60
|
155
|
-
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM = 61
|
156
|
-
|
157
|
-
# segregated witness
|
158
|
-
SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH = 70
|
159
|
-
SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY = 71
|
160
|
-
SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH = 72
|
161
|
-
SCRIPT_ERR_WITNESS_MALLEATED = 73
|
162
|
-
SCRIPT_ERR_WITNESS_MALLEATED_P2SH = 74
|
163
|
-
SCRIPT_ERR_WITNESS_UNEXPECTED = 75
|
164
|
-
SCRIPT_ERR_WITNESS_PUBKEYTYPE = 76
|
165
141
|
|
166
142
|
# Constant scriptCode
|
167
143
|
SCRIPT_ERR_OP_CODESEPARATOR = 77
|
168
144
|
SCRIPT_ERR_SIG_FINDANDDELETE = 78
|
169
145
|
|
170
|
-
|
146
|
+
SCRIPT_ERR_OP_COLOR_UNEXPECTED = 79
|
147
|
+
SCRIPT_ERR_OP_COLOR_ID_INVALID = 80
|
148
|
+
SCRIPT_ERR_OP_COLOR_MULTIPLE = 81
|
149
|
+
SCRIPT_ERR_OP_COLOR_IN_BRANCH = 82
|
150
|
+
|
151
|
+
SCRIPT_ERR_ERROR_COUNT = 83
|
171
152
|
|
172
153
|
ERRCODES_MAP = Hash[*constants.grep(/^SCRIPT_ERR_/).map { |c| [const_get(c), c.to_s] }.flatten]
|
173
154
|
NAME_MAP = Hash[*constants.grep(/^SCRIPT_ERR_/).map { |c| [c.to_s, const_get(c)] }.flatten]
|
174
155
|
|
175
|
-
# witness commitment
|
176
|
-
WITNESS_COMMITMENT_HEADER = 'aa21a9ed'
|
177
|
-
|
178
156
|
COINBASE_WTXID = '00'* 32
|
179
157
|
|
180
158
|
# for message
|
data/lib/tapyrus/ext.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'json/pure'
|
2
|
+
|
3
|
+
module Tapyrus
|
4
|
+
module Ext
|
5
|
+
|
6
|
+
# Extension of JSON::Pure::Parser.
|
7
|
+
# This class convert Float value to String value.
|
8
|
+
class JsonParser < JSON::Pure::Parser
|
9
|
+
|
10
|
+
def parse_value
|
11
|
+
case
|
12
|
+
when scan(FLOAT)
|
13
|
+
self[1].to_s
|
14
|
+
when scan(INTEGER)
|
15
|
+
Integer(self[1])
|
16
|
+
when scan(TRUE)
|
17
|
+
true
|
18
|
+
when scan(FALSE)
|
19
|
+
false
|
20
|
+
when scan(NULL)
|
21
|
+
nil
|
22
|
+
when !UNPARSED.equal?(string = parse_string)
|
23
|
+
string
|
24
|
+
when scan(ARRAY_OPEN)
|
25
|
+
@current_nesting += 1
|
26
|
+
ary = parse_array
|
27
|
+
@current_nesting -= 1
|
28
|
+
ary
|
29
|
+
when scan(OBJECT_OPEN)
|
30
|
+
@current_nesting += 1
|
31
|
+
obj = parse_object
|
32
|
+
@current_nesting -= 1
|
33
|
+
obj
|
34
|
+
when @allow_nan && scan(NAN)
|
35
|
+
NaN
|
36
|
+
when @allow_nan && scan(INFINITY)
|
37
|
+
Infinity
|
38
|
+
when @allow_nan && scan(MINUS_INFINITY)
|
39
|
+
MinusInfinity
|
40
|
+
else
|
41
|
+
UNPARSED
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/tapyrus/ext_key.rb
CHANGED
@@ -5,6 +5,7 @@ module Tapyrus
|
|
5
5
|
|
6
6
|
# BIP32 Extended private key
|
7
7
|
class ExtKey
|
8
|
+
include Tapyrus::HexConverter
|
8
9
|
|
9
10
|
attr_accessor :ver
|
10
11
|
attr_accessor :depth
|
@@ -47,7 +48,7 @@ module Tapyrus
|
|
47
48
|
|
48
49
|
# Base58 encoded extended private key
|
49
50
|
def to_base58
|
50
|
-
h =
|
51
|
+
h = to_hex
|
51
52
|
hex = h + Tapyrus.calc_checksum(h)
|
52
53
|
Base58.encode(hex)
|
53
54
|
end
|
@@ -190,6 +191,7 @@ module Tapyrus
|
|
190
191
|
|
191
192
|
# BIP-32 Extended public key
|
192
193
|
class ExtPubkey
|
194
|
+
include Tapyrus::HexConverter
|
193
195
|
|
194
196
|
attr_accessor :ver
|
195
197
|
attr_accessor :depth
|
@@ -214,14 +216,7 @@ module Tapyrus
|
|
214
216
|
|
215
217
|
# get address
|
216
218
|
def addr
|
217
|
-
|
218
|
-
when Tapyrus.chain_params.bip49_pubkey_p2wpkh_p2sh_version
|
219
|
-
key.to_nested_p2wpkh
|
220
|
-
when Tapyrus.chain_params.bip84_pubkey_p2wpkh_version
|
221
|
-
key.to_p2wpkh
|
222
|
-
else
|
223
|
-
key.to_p2pkh
|
224
|
-
end
|
219
|
+
key.to_p2pkh
|
225
220
|
end
|
226
221
|
|
227
222
|
# get key object
|
@@ -242,7 +237,7 @@ module Tapyrus
|
|
242
237
|
|
243
238
|
# Base58 encoded extended pubkey
|
244
239
|
def to_base58
|
245
|
-
h =
|
240
|
+
h = to_hex
|
246
241
|
hex = h + Tapyrus.calc_checksum(h)
|
247
242
|
Base58.encode(hex)
|
248
243
|
end
|
data/lib/tapyrus/key.rb
CHANGED
@@ -11,6 +11,8 @@ module Tapyrus
|
|
11
11
|
SIGNATURE_SIZE = 72
|
12
12
|
COMPACT_SIGNATURE_SIZE = 65
|
13
13
|
|
14
|
+
SIG_ALGO = [:ecdsa, :schnorr]
|
15
|
+
|
14
16
|
attr_accessor :priv_key
|
15
17
|
attr_accessor :pubkey
|
16
18
|
attr_accessor :key_type
|
@@ -89,29 +91,31 @@ module Tapyrus
|
|
89
91
|
# @param [String] data a data to be signed with binary format
|
90
92
|
# @param [Boolean] low_r flag to apply low-R.
|
91
93
|
# @param [String] extra_entropy the extra entropy for rfc6979.
|
94
|
+
# @param [Symbol] algo Algorithms used for verification. Either :ecdsa or :schnorr is supported. default value is :ecdsa.
|
92
95
|
# @return [String] signature data with binary format
|
93
|
-
def sign(data, low_r = true, extra_entropy = nil)
|
94
|
-
|
95
|
-
if
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
sig = secp256k1_module.sign_data(data, priv_key, extra_entropy)
|
100
|
-
counter += 1
|
101
|
-
end
|
96
|
+
def sign(data, low_r = true, extra_entropy = nil, algo: :ecdsa)
|
97
|
+
raise ArgumentError, "Unsupported algorithm has been specified." unless SIG_ALGO.include?(algo)
|
98
|
+
if algo == :ecdsa
|
99
|
+
sign_ecdsa(data, low_r, extra_entropy)
|
100
|
+
else
|
101
|
+
sign_schnorr(data)
|
102
102
|
end
|
103
|
-
sig
|
104
103
|
end
|
105
104
|
|
106
105
|
# verify signature using public key
|
107
106
|
# @param [String] sig signature data with binary format
|
108
107
|
# @param [String] origin original message
|
108
|
+
# @param [Symbol] algo Algorithms used for verification. Either :ecdsa or :schnorr is supported. default value is :ecdsa.
|
109
109
|
# @return [Boolean] verify result
|
110
|
-
def verify(sig, origin)
|
110
|
+
def verify(sig, origin, algo: :ecdsa)
|
111
111
|
return false unless valid_pubkey?
|
112
112
|
begin
|
113
|
-
|
114
|
-
|
113
|
+
raise ArgumentError, "Unsupported algorithm has been specified." unless SIG_ALGO.include?(algo)
|
114
|
+
if algo == :ecdsa
|
115
|
+
verify_ecdsa_sig(sig, origin)
|
116
|
+
else
|
117
|
+
verify_schnorr_sig(sig, origin)
|
118
|
+
end
|
115
119
|
rescue Exception
|
116
120
|
false
|
117
121
|
end
|
@@ -128,18 +132,6 @@ module Tapyrus
|
|
128
132
|
Tapyrus::Script.to_p2pkh(hash160).addresses.first
|
129
133
|
end
|
130
134
|
|
131
|
-
# get pay to witness pubkey hash address
|
132
|
-
# @deprecated
|
133
|
-
def to_p2wpkh
|
134
|
-
Tapyrus::Script.to_p2wpkh(hash160).addresses.first
|
135
|
-
end
|
136
|
-
|
137
|
-
# get p2wpkh address nested in p2sh.
|
138
|
-
# @deprecated
|
139
|
-
def to_nested_p2wpkh
|
140
|
-
Tapyrus::Script.to_p2wpkh(hash160).to_p2sh.addresses.first
|
141
|
-
end
|
142
|
-
|
143
135
|
def compressed?
|
144
136
|
key_type != TYPES[:uncompressed]
|
145
137
|
end
|
@@ -191,18 +183,24 @@ module Tapyrus
|
|
191
183
|
|
192
184
|
# check +sig+ is correct der encoding.
|
193
185
|
# This function is consensus-critical since BIP66.
|
194
|
-
|
195
|
-
|
186
|
+
# @param [String] sig a signature data with binary format.
|
187
|
+
# @param [Boolean] data_sig whether data signature or not.
|
188
|
+
# @return [Boolean] result
|
189
|
+
def self.valid_signature_encoding?(sig, data_sig = false)
|
190
|
+
num_parts = data_sig ? 8 : 9
|
191
|
+
size = data_sig ? 72 : 73
|
192
|
+
|
193
|
+
return false if sig.bytesize < num_parts || sig.bytesize > size # Minimum and maximum size check
|
196
194
|
|
197
195
|
s = sig.unpack('C*')
|
198
196
|
|
199
|
-
return false if s[0] != 0x30 || s[1] != s.size - 3 # A signature is of type 0x30 (compound). Make sure the length covers the entire signature.
|
197
|
+
return false if s[0] != 0x30 || s[1] != s.size - (data_sig ? 2 : 3) # A signature is of type 0x30 (compound). Make sure the length covers the entire signature.
|
200
198
|
|
201
199
|
len_r = s[3]
|
202
200
|
return false if 5 + len_r >= s.size # Make sure the length of the S element is still inside the signature.
|
203
201
|
|
204
202
|
len_s = s[5 + len_r]
|
205
|
-
return false unless len_r + len_s + 7 == s.size #Verify that the length of the signature matches the sum of the length of the elements.
|
203
|
+
return false unless len_r + len_s + (data_sig ? 6 : 7) == s.size #Verify that the length of the signature matches the sum of the length of the elements.
|
206
204
|
|
207
205
|
return false unless s[2] == 0x02 # Check whether the R element is an integer.
|
208
206
|
|
@@ -291,6 +289,36 @@ module Tapyrus
|
|
291
289
|
sig[3].bth.to_i(16) == 0x20 && sig[4].bth.to_i(16) < 0x80
|
292
290
|
end
|
293
291
|
|
292
|
+
# generate ecdsa signature
|
293
|
+
def sign_ecdsa(data, low_r, extra_entropy)
|
294
|
+
sig = secp256k1_module.sign_data(data, priv_key, extra_entropy)
|
295
|
+
if low_r && !sig_has_low_r?(sig)
|
296
|
+
counter = 1
|
297
|
+
until sig_has_low_r?(sig)
|
298
|
+
extra_entropy = [counter].pack('I*').bth.ljust(64, '0').htb
|
299
|
+
sig = secp256k1_module.sign_data(data, priv_key, extra_entropy)
|
300
|
+
counter += 1
|
301
|
+
end
|
302
|
+
end
|
303
|
+
sig
|
304
|
+
end
|
305
|
+
|
306
|
+
# generate schnorr signature
|
307
|
+
def sign_schnorr(msg)
|
308
|
+
Schnorr.sign(msg, priv_key.to_i(16)).encode
|
309
|
+
end
|
310
|
+
|
311
|
+
# verify ecdsa signature
|
312
|
+
def verify_ecdsa_sig(sig, message)
|
313
|
+
sig = ecdsa_signature_parse_der_lax(sig)
|
314
|
+
secp256k1_module.verify_sig(message, sig, pubkey)
|
315
|
+
end
|
316
|
+
|
317
|
+
# verify schnorr signature
|
318
|
+
def verify_schnorr_sig(sig, message)
|
319
|
+
Schnorr.valid_sig?(message, sig, pubkey.htb)
|
320
|
+
end
|
321
|
+
|
294
322
|
end
|
295
323
|
|
296
324
|
end
|
data/lib/tapyrus/message.rb
CHANGED
@@ -45,13 +45,13 @@ module Tapyrus
|
|
45
45
|
network: 1 << 0, # the node is capable of serving the block chain. It is currently set by all Bitcoin Core node, and is unset by SPV clients or other peers that just want network services but don't provide them.
|
46
46
|
# getutxo: 1 << 1, # BIP-64. not implemented in Bitcoin Core.
|
47
47
|
bloom: 1 << 2, # the node is capable and willing to handle bloom-filtered connections. Bitcoin Core node used to support this by default, without advertising this bit, but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION)
|
48
|
-
witness: 1 << 3, # the node can be asked for blocks and transactions including witness data.
|
48
|
+
#witness: 1 << 3, # the node can be asked for blocks and transactions including witness data.
|
49
49
|
# xthin: 1 << 4 # support Xtreme Thinblocks. not implemented in Bitcoin Core
|
50
50
|
}
|
51
51
|
|
52
52
|
# DEFAULT_SERVICE_FLAGS = SERVICE_FLAGS[:network] | SERVICE_FLAGS[:bloom] | SERVICE_FLAGS[:witness]
|
53
53
|
|
54
|
-
DEFAULT_SERVICE_FLAGS = SERVICE_FLAGS[:none]
|
54
|
+
DEFAULT_SERVICE_FLAGS = SERVICE_FLAGS[:none]
|
55
55
|
|
56
56
|
DEFAULT_STOP_HASH = "00"*32
|
57
57
|
|
data/lib/tapyrus/message/base.rb
CHANGED
@@ -11,10 +11,10 @@ module Tapyrus
|
|
11
11
|
|
12
12
|
COMMAND = 'block'
|
13
13
|
|
14
|
-
def initialize(header, transactions = []
|
14
|
+
def initialize(header, transactions = [])
|
15
15
|
@header = header
|
16
16
|
@transactions = transactions
|
17
|
-
@use_segwit =
|
17
|
+
@use_segwit = false
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.parse_from_payload(payload)
|
@@ -32,7 +32,7 @@ module Tapyrus
|
|
32
32
|
|
33
33
|
def to_payload
|
34
34
|
header.to_payload << Tapyrus.pack_var_int(transactions.size) <<
|
35
|
-
transactions.map
|
35
|
+
transactions.map(&:to_payload).join
|
36
36
|
end
|
37
37
|
|
38
38
|
# generate Tapyrus::Block object.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
3
|
|
4
|
-
# cmpctblock message
|
4
|
+
# cmpctblock message. support only version 1.
|
5
5
|
# https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
6
6
|
class CmpctBlock < Base
|
7
7
|
|
@@ -15,14 +15,12 @@ module Tapyrus
|
|
15
15
|
|
16
16
|
# generate CmpctBlock from Block data.
|
17
17
|
# @param [Tapyrus::Block] block the block to generate CmpctBlock.
|
18
|
-
# @param [Integer] version Compact Block version specified by sendcmpct message.
|
19
18
|
# @param [Integer] nonce
|
20
19
|
# @return [Tapyrus::Message::CmpctBlock]
|
21
|
-
def self.from_block(block,
|
22
|
-
raise 'Unsupported version.' unless [1, 2].include?(version)
|
20
|
+
def self.from_block(block, nonce = SecureRandom.hex(8).to_i(16))
|
23
21
|
h = HeaderAndShortIDs.new(block.header, nonce)
|
24
22
|
block.transactions[1..-1].each do |tx|
|
25
|
-
h.short_ids << h.short_id(
|
23
|
+
h.short_ids << h.short_id(tx.txid)
|
26
24
|
end
|
27
25
|
h.prefilled_txn << PrefilledTx.new(0, block.transactions.first)
|
28
26
|
self.new(h)
|