tapyrus 0.2.4 → 0.2.9
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/.github/workflows/ruby.yml +37 -0
- data/.prettierignore +3 -0
- data/.prettierrc.yaml +3 -0
- data/CODE_OF_CONDUCT.md +7 -7
- data/README.md +14 -17
- data/Rakefile +3 -3
- data/lib/openassets.rb +0 -2
- data/lib/openassets/marker_output.rb +0 -4
- data/lib/openassets/payload.rb +4 -10
- data/lib/schnorr.rb +14 -9
- data/lib/schnorr/sign_to_contract.rb +51 -0
- data/lib/schnorr/signature.rb +3 -6
- data/lib/tapyrus.rb +8 -30
- data/lib/tapyrus/base58.rb +7 -6
- data/lib/tapyrus/bip175.rb +67 -0
- data/lib/tapyrus/block.rb +1 -2
- data/lib/tapyrus/block_header.rb +15 -9
- data/lib/tapyrus/bloom_filter.rb +5 -3
- data/lib/tapyrus/chain_params.rb +1 -4
- data/lib/tapyrus/chainparams/dev.yml +3 -2
- data/lib/tapyrus/chainparams/prod.yml +3 -2
- data/lib/tapyrus/constants.rb +29 -23
- data/lib/tapyrus/errors.rb +1 -3
- data/lib/tapyrus/ext.rb +1 -1
- data/lib/tapyrus/ext/ecdsa.rb +4 -4
- data/lib/tapyrus/ext/json_parser.rb +1 -4
- data/lib/tapyrus/ext_key.rb +44 -32
- data/lib/tapyrus/key.rb +31 -35
- data/lib/tapyrus/key_path.rb +15 -12
- data/lib/tapyrus/logger.rb +20 -16
- data/lib/tapyrus/merkle_tree.rb +19 -20
- data/lib/tapyrus/message.rb +14 -16
- data/lib/tapyrus/message/addr.rb +1 -7
- data/lib/tapyrus/message/base.rb +0 -3
- data/lib/tapyrus/message/block.rb +2 -9
- data/lib/tapyrus/message/block_transaction_request.rb +3 -6
- data/lib/tapyrus/message/block_transactions.rb +2 -6
- data/lib/tapyrus/message/block_txn.rb +0 -4
- data/lib/tapyrus/message/cmpct_block.rb +1 -7
- data/lib/tapyrus/message/error.rb +1 -4
- data/lib/tapyrus/message/fee_filter.rb +1 -4
- data/lib/tapyrus/message/filter_add.rb +0 -4
- data/lib/tapyrus/message/filter_clear.rb +0 -4
- data/lib/tapyrus/message/filter_load.rb +2 -5
- data/lib/tapyrus/message/get_addr.rb +0 -4
- data/lib/tapyrus/message/get_block_txn.rb +0 -4
- data/lib/tapyrus/message/get_blocks.rb +0 -3
- data/lib/tapyrus/message/get_data.rb +1 -4
- data/lib/tapyrus/message/get_headers.rb +1 -3
- data/lib/tapyrus/message/header_and_short_ids.rb +3 -9
- data/lib/tapyrus/message/headers.rb +0 -4
- data/lib/tapyrus/message/headers_parser.rb +3 -8
- data/lib/tapyrus/message/inv.rb +1 -4
- data/lib/tapyrus/message/inventories_parser.rb +2 -7
- data/lib/tapyrus/message/inventory.rb +12 -5
- data/lib/tapyrus/message/mem_pool.rb +0 -4
- data/lib/tapyrus/message/merkle_block.rb +4 -9
- data/lib/tapyrus/message/network_addr.rb +7 -6
- data/lib/tapyrus/message/not_found.rb +0 -3
- data/lib/tapyrus/message/ping.rb +0 -3
- data/lib/tapyrus/message/pong.rb +0 -3
- data/lib/tapyrus/message/prefilled_tx.rb +0 -4
- data/lib/tapyrus/message/reject.rb +0 -3
- data/lib/tapyrus/message/send_cmpct.rb +1 -3
- data/lib/tapyrus/message/send_headers.rb +0 -3
- data/lib/tapyrus/message/tx.rb +0 -4
- data/lib/tapyrus/message/ver_ack.rb +1 -5
- data/lib/tapyrus/message/version.rb +2 -5
- data/lib/tapyrus/mnemonic.rb +17 -15
- data/lib/tapyrus/network.rb +0 -2
- data/lib/tapyrus/network/connection.rb +0 -3
- data/lib/tapyrus/network/message_handler.rb +61 -60
- data/lib/tapyrus/network/peer.rb +13 -12
- data/lib/tapyrus/network/peer_discovery.rb +3 -5
- data/lib/tapyrus/network/pool.rb +12 -12
- data/lib/tapyrus/node.rb +1 -1
- data/lib/tapyrus/node/cli.rb +12 -14
- data/lib/tapyrus/node/configuration.rb +1 -3
- data/lib/tapyrus/node/spv.rb +2 -3
- data/lib/tapyrus/opcodes.rb +9 -7
- data/lib/tapyrus/out_point.rb +5 -5
- data/lib/tapyrus/rpc.rb +1 -0
- data/lib/tapyrus/rpc/http_server.rb +21 -22
- data/lib/tapyrus/rpc/request_handler.rb +42 -44
- data/lib/tapyrus/rpc/tapyrus_core_client.rb +67 -25
- data/lib/tapyrus/script/color.rb +20 -2
- data/lib/tapyrus/script/multisig.rb +13 -12
- data/lib/tapyrus/script/script.rb +104 -67
- data/lib/tapyrus/script/script_error.rb +1 -4
- data/lib/tapyrus/script/script_interpreter.rb +439 -399
- data/lib/tapyrus/script/tx_checker.rb +20 -10
- data/lib/tapyrus/secp256k1.rb +0 -4
- data/lib/tapyrus/secp256k1/native.rb +14 -15
- data/lib/tapyrus/secp256k1/rfc6979.rb +7 -4
- data/lib/tapyrus/secp256k1/ruby.rb +10 -12
- data/lib/tapyrus/slip39.rb +20 -5
- data/lib/tapyrus/slip39/share.rb +41 -29
- data/lib/tapyrus/slip39/sss.rb +101 -57
- data/lib/tapyrus/store.rb +1 -3
- data/lib/tapyrus/store/chain_entry.rb +0 -4
- data/lib/tapyrus/store/db.rb +0 -2
- data/lib/tapyrus/store/db/level_db.rb +5 -9
- data/lib/tapyrus/store/spv_chain.rb +11 -17
- data/lib/tapyrus/tx.rb +45 -37
- data/lib/tapyrus/tx_builder.rb +158 -0
- data/lib/tapyrus/tx_in.rb +1 -6
- data/lib/tapyrus/tx_out.rb +2 -7
- data/lib/tapyrus/util.rb +20 -7
- data/lib/tapyrus/validation.rb +12 -11
- data/lib/tapyrus/version.rb +1 -1
- data/lib/tapyrus/wallet/account.rb +22 -18
- data/lib/tapyrus/wallet/base.rb +12 -9
- data/lib/tapyrus/wallet/db.rb +6 -9
- data/lib/tapyrus/wallet/master_key.rb +2 -4
- data/tapyrusrb.gemspec +13 -16
- metadata +22 -31
- data/.travis.yml +0 -12
@@ -1,23 +1,18 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# Common message parser which only handle multiple inventory as payload.
|
5
4
|
module InventoriesParser
|
6
|
-
|
7
5
|
def parse_from_payload(payload)
|
8
6
|
size, payload = Tapyrus.unpack_var_int(payload)
|
9
7
|
buf = StringIO.new(payload)
|
10
8
|
i = new
|
11
|
-
size.times
|
12
|
-
i.inventories << Inventory.parse_from_payload(buf.read(36))
|
13
|
-
end
|
9
|
+
size.times { i.inventories << Inventory.parse_from_payload(buf.read(36)) }
|
14
10
|
i
|
15
11
|
end
|
16
12
|
|
17
13
|
def to_payload
|
18
14
|
Tapyrus.pack_var_int(inventories.length) << inventories.map(&:to_payload).join
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
17
|
end
|
23
|
-
end
|
18
|
+
end
|
@@ -3,7 +3,6 @@ module Tapyrus
|
|
3
3
|
# inventory class. inventory is a part of message.
|
4
4
|
# https://bitcoin.org/en/developer-reference#term-inventory
|
5
5
|
class Inventory
|
6
|
-
|
7
6
|
SEGWIT_FLAG = 1 << 30
|
8
7
|
|
9
8
|
MSG_TX = 1
|
@@ -18,7 +17,9 @@ module Tapyrus
|
|
18
17
|
attr_accessor :hash
|
19
18
|
|
20
19
|
def initialize(identifier, hash)
|
21
|
-
|
20
|
+
unless valid_identifier?(identifier)
|
21
|
+
raise Error, "invalid type identifier specified. identifier = #{identifier}"
|
22
|
+
end
|
22
23
|
@identifier = identifier
|
23
24
|
@hash = hash
|
24
25
|
end
|
@@ -42,10 +43,16 @@ module Tapyrus
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def valid_identifier?(identifier)
|
45
|
-
[
|
46
|
-
|
46
|
+
[
|
47
|
+
MSG_TX,
|
48
|
+
MSG_BLOCK,
|
49
|
+
MSG_FILTERED_BLOCK,
|
50
|
+
MSG_CMPCT_BLOCK,
|
51
|
+
MSG_WITNESS_TX,
|
52
|
+
MSG_WITNESS_BLOCK,
|
53
|
+
MSG_FILTERED_WITNESS_BLOCK
|
54
|
+
].include?(identifier)
|
47
55
|
end
|
48
|
-
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# merckleblock message
|
5
4
|
# https://bitcoin.org/en/developer-reference#merkleblock
|
6
5
|
class MerkleBlock < Base
|
7
|
-
|
8
6
|
COMMAND = 'merkleblock'
|
9
7
|
|
10
8
|
attr_accessor :header
|
@@ -22,21 +20,18 @@ module Tapyrus
|
|
22
20
|
m.header = Tapyrus::BlockHeader.parse_from_payload(buf)
|
23
21
|
m.tx_count = buf.read(4).unpack('V').first
|
24
22
|
hash_count = Tapyrus.unpack_var_int_from_io(buf)
|
25
|
-
hash_count.times
|
26
|
-
m.hashes << buf.read(32).bth
|
27
|
-
end
|
23
|
+
hash_count.times { m.hashes << buf.read(32).bth }
|
28
24
|
flag_count = Tapyrus.unpack_var_int_from_io(buf)
|
25
|
+
|
29
26
|
# A sequence of bits packed eight in a byte with the least significant bit first.
|
30
27
|
m.flags = buf.read(flag_count).bth
|
31
28
|
m
|
32
29
|
end
|
33
30
|
|
34
31
|
def to_payload
|
35
|
-
header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) <<
|
36
|
-
|
32
|
+
header.to_payload << [tx_count].pack('V') << Tapyrus.pack_var_int(hashes.size) << hashes.map(&:htb).join <<
|
33
|
+
Tapyrus.pack_var_int(flags.htb.bytesize) << flags.htb
|
37
34
|
end
|
38
|
-
|
39
35
|
end
|
40
|
-
|
41
36
|
end
|
42
37
|
end
|
@@ -2,9 +2,7 @@ require 'ipaddr'
|
|
2
2
|
|
3
3
|
module Tapyrus
|
4
4
|
module Message
|
5
|
-
|
6
5
|
class NetworkAddr
|
7
|
-
|
8
6
|
# unix time.
|
9
7
|
# Nodes advertising their own IP address set this to the current time.
|
10
8
|
# Nodes advertising IP addresses they’ve connected to set this to the last time they connected to that node.
|
@@ -20,7 +18,12 @@ module Tapyrus
|
|
20
18
|
|
21
19
|
attr_reader :skip_time
|
22
20
|
|
23
|
-
def initialize(
|
21
|
+
def initialize(
|
22
|
+
ip: '127.0.0.1',
|
23
|
+
port: Tapyrus.chain_params.default_port,
|
24
|
+
services: DEFAULT_SERVICE_FLAGS,
|
25
|
+
time: Time.now.to_i
|
26
|
+
)
|
24
27
|
@time = time
|
25
28
|
@ip_addr = IPAddr.new(ip)
|
26
29
|
@port = port
|
@@ -33,7 +36,7 @@ module Tapyrus
|
|
33
36
|
addr = new(time: nil)
|
34
37
|
addr.time = buf.read(4).unpack('V').first if has_time
|
35
38
|
addr.services = buf.read(8).unpack('Q').first
|
36
|
-
addr.ip_addr = IPAddr
|
39
|
+
addr.ip_addr = IPAddr.new_ntoh(buf.read(16))
|
37
40
|
addr.port = buf.read(2).unpack('n').first
|
38
41
|
addr
|
39
42
|
end
|
@@ -56,8 +59,6 @@ module Tapyrus
|
|
56
59
|
addr = ip_addr.ipv4? ? ip_addr.ipv4_mapped : ip_addr
|
57
60
|
p << [services].pack('Q') << addr.hton << [port].pack('n')
|
58
61
|
end
|
59
|
-
|
60
62
|
end
|
61
|
-
|
62
63
|
end
|
63
64
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# notfound message
|
5
4
|
# https://bitcoin.org/en/developer-reference#notfound
|
6
5
|
class NotFound < Base
|
@@ -14,8 +13,6 @@ module Tapyrus
|
|
14
13
|
def initialize(inventories = [])
|
15
14
|
@inventories = inventories
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
20
|
-
|
21
18
|
end
|
data/lib/tapyrus/message/ping.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# ping message class
|
5
4
|
# https://bitcoin.org/en/developer-reference#ping
|
6
5
|
class Ping < Base
|
7
|
-
|
8
6
|
COMMAND = 'ping'
|
9
7
|
|
10
8
|
attr_accessor :nonce
|
@@ -24,7 +22,6 @@ module Tapyrus
|
|
24
22
|
def to_response
|
25
23
|
Pong.new(nonce)
|
26
24
|
end
|
27
|
-
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
data/lib/tapyrus/message/pong.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# pong message
|
5
4
|
# https://bitcoin.org/en/developer-reference#pong
|
6
5
|
class Pong < Base
|
7
|
-
|
8
6
|
COMMAND = 'pong'
|
9
7
|
|
10
8
|
attr_reader :nonce
|
@@ -21,6 +19,5 @@ module Tapyrus
|
|
21
19
|
[nonce].pack('Q')
|
22
20
|
end
|
23
21
|
end
|
24
|
-
|
25
22
|
end
|
26
23
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# A PrefilledTransaction structure is used in HeaderAndShortIDs to provide a list of a few transactions explicitly.
|
5
4
|
# https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
6
5
|
class PrefilledTx
|
7
|
-
|
8
6
|
attr_accessor :index
|
9
7
|
attr_accessor :tx
|
10
8
|
|
@@ -22,8 +20,6 @@ module Tapyrus
|
|
22
20
|
def to_payload
|
23
21
|
Tapyrus.pack_var_int(index) << tx.to_payload
|
24
22
|
end
|
25
|
-
|
26
23
|
end
|
27
|
-
|
28
24
|
end
|
29
25
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# reject message
|
5
4
|
# https://bitcoin.org/en/developer-reference#reject
|
6
5
|
class Reject < Base
|
7
|
-
|
8
6
|
attr_accessor :message
|
9
7
|
attr_accessor :code
|
10
8
|
attr_accessor :reason
|
@@ -40,7 +38,6 @@ module Tapyrus
|
|
40
38
|
e = ['tx', 'block'].include?(message) ? extra.htb : extra
|
41
39
|
Tapyrus.pack_var_string(message) << [code].pack('C') << Tapyrus.pack_var_string(reason) << e
|
42
40
|
end
|
43
|
-
|
44
41
|
end
|
45
42
|
end
|
46
43
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# sendcmpct message
|
5
4
|
# https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki
|
6
5
|
class SendCmpct < Base
|
7
|
-
|
8
6
|
COMMAND = 'sendcmpct'
|
9
7
|
|
10
8
|
MODE_HIGH = 1
|
@@ -12,6 +10,7 @@ module Tapyrus
|
|
12
10
|
|
13
11
|
attr_accessor :mode
|
14
12
|
attr_accessor :version
|
13
|
+
|
15
14
|
# TODO support version 2
|
16
15
|
|
17
16
|
def initialize(mode = MODE_HIGH, version = 1)
|
@@ -38,6 +37,5 @@ module Tapyrus
|
|
38
37
|
mode.zero?
|
39
38
|
end
|
40
39
|
end
|
41
|
-
|
42
40
|
end
|
43
41
|
end
|
data/lib/tapyrus/message/tx.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tapyrus
|
2
2
|
module Message
|
3
|
-
|
4
3
|
# tx message
|
5
4
|
# https://bitcoin.org/en/developer-reference#tx
|
6
5
|
class Tx < Base
|
7
|
-
|
8
6
|
COMMAND = 'tx'
|
9
7
|
|
10
8
|
attr_accessor :tx
|
@@ -23,8 +21,6 @@ module Tapyrus
|
|
23
21
|
def to_payload
|
24
22
|
tx.to_payload
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
|
-
|
29
25
|
end
|
30
26
|
end
|
@@ -2,10 +2,8 @@
|
|
2
2
|
require 'ipaddr'
|
3
3
|
module Tapyrus
|
4
4
|
module Message
|
5
|
-
|
6
5
|
# https://bitcoin.org/en/developer-reference#version
|
7
6
|
class Version < Base
|
8
|
-
|
9
7
|
COMMAND = 'version'
|
10
8
|
|
11
9
|
attr_accessor :version
|
@@ -61,9 +59,8 @@ module Tapyrus
|
|
61
59
|
end
|
62
60
|
|
63
61
|
def unpack_relay_field(payload)
|
64
|
-
(
|
62
|
+
(version >= 70_001 && payload) ? unpack_boolean(payload) : [true, nil]
|
65
63
|
end
|
66
|
-
|
67
64
|
end
|
68
65
|
end
|
69
|
-
end
|
66
|
+
end
|
data/lib/tapyrus/mnemonic.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Tapyrus
|
2
|
-
|
3
2
|
# Mnemonic code for generating deterministic keys
|
4
3
|
# https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
5
4
|
class Mnemonic
|
6
|
-
|
7
5
|
WORD_DIR = "#{__dir__}/mnemonic/wordlist"
|
8
6
|
|
9
7
|
attr_reader :word_list
|
@@ -15,7 +13,7 @@ module Tapyrus
|
|
15
13
|
|
16
14
|
# get support language list
|
17
15
|
def self.word_lists
|
18
|
-
Dir.glob("#{WORD_DIR}/**.txt").map{|f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
|
16
|
+
Dir.glob("#{WORD_DIR}/**.txt").map { |f| f.gsub("#{WORD_DIR}/", '').gsub('.txt', '') }
|
19
17
|
end
|
20
18
|
|
21
19
|
# generate entropy from mnemonic word
|
@@ -23,11 +21,12 @@ module Tapyrus
|
|
23
21
|
# @return [String] an entropy with hex format.
|
24
22
|
def to_entropy(words)
|
25
23
|
word_master = load_words
|
26
|
-
mnemonic =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
mnemonic =
|
25
|
+
words.map do |w|
|
26
|
+
index = word_master.index(w.downcase)
|
27
|
+
raise IndexError, 'word not found in words list.' unless index
|
28
|
+
index.to_s(2).rjust(11, '0')
|
29
|
+
end.join
|
31
30
|
entropy = mnemonic.slice(0, (mnemonic.length * 32) / 33)
|
32
31
|
checksum = mnemonic.gsub(entropy, '')
|
33
32
|
raise SecurityError, 'checksum mismatch.' unless checksum == checksum(entropy)
|
@@ -41,9 +40,9 @@ module Tapyrus
|
|
41
40
|
raise ArgumentError, 'entropy is empty.' if entropy.nil? || entropy.empty?
|
42
41
|
e = entropy.htb.unpack('B*').first
|
43
42
|
seed = e + checksum(e)
|
44
|
-
mnemonic_index = seed.chars.each_slice(11).map{|i|i.join.to_i(2)}
|
43
|
+
mnemonic_index = seed.chars.each_slice(11).map { |i| i.join.to_i(2) }
|
45
44
|
word_master = load_words
|
46
|
-
mnemonic_index.map{|i|word_master[i]}
|
45
|
+
mnemonic_index.map { |i| word_master[i] }
|
47
46
|
end
|
48
47
|
|
49
48
|
# generate seed from mnemonic
|
@@ -53,8 +52,13 @@ module Tapyrus
|
|
53
52
|
# @return [String] seed
|
54
53
|
def to_seed(mnemonic, passphrase: '')
|
55
54
|
to_entropy(mnemonic)
|
56
|
-
OpenSSL::PKCS5.pbkdf2_hmac(
|
57
|
-
|
55
|
+
OpenSSL::PKCS5.pbkdf2_hmac(
|
56
|
+
mnemonic.join(' ').downcase,
|
57
|
+
'mnemonic' + passphrase,
|
58
|
+
2048,
|
59
|
+
64,
|
60
|
+
OpenSSL::Digest::SHA512.new
|
61
|
+
).bth
|
58
62
|
end
|
59
63
|
|
60
64
|
# calculate entropy checksum
|
@@ -62,7 +66,7 @@ module Tapyrus
|
|
62
66
|
# @return [String] an entropy checksum with bit string format
|
63
67
|
def checksum(entropy)
|
64
68
|
b = Tapyrus.sha256([entropy].pack('B*')).unpack('B*').first
|
65
|
-
b.slice(0, (entropy.length/32))
|
69
|
+
b.slice(0, (entropy.length / 32))
|
66
70
|
end
|
67
71
|
|
68
72
|
private
|
@@ -71,7 +75,5 @@ module Tapyrus
|
|
71
75
|
def load_words
|
72
76
|
File.readlines("#{WORD_DIR}/#{word_list}.txt").map(&:strip)
|
73
77
|
end
|
74
|
-
|
75
78
|
end
|
76
|
-
|
77
79
|
end
|