arkecosystem-crypto 0.1.0

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/lib/arkecosystem/crypto.rb +49 -0
  3. data/lib/arkecosystem/crypto/builder/delegate_registration.rb +33 -0
  4. data/lib/arkecosystem/crypto/builder/multi_signature_registration.rb +45 -0
  5. data/lib/arkecosystem/crypto/builder/second_signature_registration.rb +27 -0
  6. data/lib/arkecosystem/crypto/builder/transaction.rb +109 -0
  7. data/lib/arkecosystem/crypto/builder/transfer.rb +32 -0
  8. data/lib/arkecosystem/crypto/builder/vote.rb +28 -0
  9. data/lib/arkecosystem/crypto/configuration/fee.rb +30 -0
  10. data/lib/arkecosystem/crypto/configuration/network.rb +18 -0
  11. data/lib/arkecosystem/crypto/crypto.rb +144 -0
  12. data/lib/arkecosystem/crypto/deserialiser.rb +94 -0
  13. data/lib/arkecosystem/crypto/deserialisers/base.rb +15 -0
  14. data/lib/arkecosystem/crypto/deserialisers/delegate_registration.rb +22 -0
  15. data/lib/arkecosystem/crypto/deserialisers/delegate_resignation.rb +12 -0
  16. data/lib/arkecosystem/crypto/deserialisers/ipfs.rb +18 -0
  17. data/lib/arkecosystem/crypto/deserialisers/multi_payment.rb +38 -0
  18. data/lib/arkecosystem/crypto/deserialisers/multi_signature_registration.rb +32 -0
  19. data/lib/arkecosystem/crypto/deserialisers/second_signature_registration.rb +18 -0
  20. data/lib/arkecosystem/crypto/deserialisers/timelock_transfer.rb +19 -0
  21. data/lib/arkecosystem/crypto/deserialisers/transfer.rb +18 -0
  22. data/lib/arkecosystem/crypto/deserialisers/vote.rb +31 -0
  23. data/lib/arkecosystem/crypto/enums/fees.rb +18 -0
  24. data/lib/arkecosystem/crypto/enums/types.rb +18 -0
  25. data/lib/arkecosystem/crypto/identity/address.rb +35 -0
  26. data/lib/arkecosystem/crypto/identity/private_key.rb +14 -0
  27. data/lib/arkecosystem/crypto/identity/public_key.rb +18 -0
  28. data/lib/arkecosystem/crypto/identity/wif.rb +22 -0
  29. data/lib/arkecosystem/crypto/message.rb +42 -0
  30. data/lib/arkecosystem/crypto/models/transaction.rb +16 -0
  31. data/lib/arkecosystem/crypto/networks/devnet.rb +24 -0
  32. data/lib/arkecosystem/crypto/networks/mainnet.rb +24 -0
  33. data/lib/arkecosystem/crypto/networks/testnet.rb +24 -0
  34. data/lib/arkecosystem/crypto/serialiser.rb +84 -0
  35. data/lib/arkecosystem/crypto/serialisers/base.rb +13 -0
  36. data/lib/arkecosystem/crypto/serialisers/delegate_registration.rb +17 -0
  37. data/lib/arkecosystem/crypto/serialisers/delegate_resignation.rb +12 -0
  38. data/lib/arkecosystem/crypto/serialisers/ipfs.rb +17 -0
  39. data/lib/arkecosystem/crypto/serialisers/multi_payment.rb +23 -0
  40. data/lib/arkecosystem/crypto/serialisers/multi_signature_registration.rb +31 -0
  41. data/lib/arkecosystem/crypto/serialisers/second_signature_registration.rb +14 -0
  42. data/lib/arkecosystem/crypto/serialisers/timelock_transfer.rb +21 -0
  43. data/lib/arkecosystem/crypto/serialisers/transfer.rb +20 -0
  44. data/lib/arkecosystem/crypto/serialisers/vote.rb +23 -0
  45. data/lib/arkecosystem/crypto/version.rb +15 -0
  46. metadata +159 -0
@@ -0,0 +1,94 @@
1
+ require 'arkecosystem/crypto/identity/address'
2
+
3
+ module ArkEcosystem
4
+ module Crypto
5
+ # The base deserialiser for transactions.
6
+ class Deserialiser
7
+ def initialize(serialised)
8
+ @serialised = serialised
9
+ @binary = BTC::Data.data_from_hex(@serialised)
10
+
11
+ @handlers = %w[
12
+ Transfer
13
+ SecondSignatureRegistration
14
+ DelegateRegistration
15
+ Vote
16
+ MultiSignatureRegistration
17
+ Ipfs
18
+ TimelockTransfer
19
+ MultiPayment
20
+ DelegateResignation
21
+ ]
22
+ end
23
+
24
+ def deserialise
25
+ transaction = {}
26
+ transaction[:version] = @binary.unpack('C2').last
27
+ transaction[:network] = @binary.unpack('C3').last
28
+ transaction[:type] = @binary.unpack('C4').last
29
+ transaction[:timestamp] = @binary.unpack('V2').last
30
+ transaction[:sender_public_key] = @binary.unpack('H16H66').last
31
+ transaction[:fee] = @binary.unpack('C41Q<').last
32
+
33
+ vendor_field_length = @binary.unpack('C49C1').last
34
+
35
+ if vendor_field_length > 0
36
+ vendor_field_offset = (41 + 8 + 1) * 2
37
+ vendor_field_take = vendor_field_length * 2
38
+
39
+ transaction[:vendor_field_hex] = @binary.unpack("H#{vendor_field_offset}H#{vendor_field_take}").last
40
+ end
41
+
42
+ asset_offset = (41 + 8 + 1) * 2 + vendor_field_length * 2
43
+
44
+ transaction = handle_type(asset_offset, transaction)
45
+
46
+ transaction[:amount] = 0 unless transaction[:amount]
47
+
48
+ if transaction[:version] == 1 || transaction[:version].empty?
49
+ transaction = handle_version_one(transaction)
50
+ end
51
+
52
+ transaction
53
+ end
54
+
55
+ private
56
+
57
+ def handle_type(asset_offset, transaction)
58
+ deserialiser = @handlers[transaction[:type]]
59
+ deserialiser = Object.const_get("ArkEcosystem::Crypto::Deserialisers::#{deserialiser}")
60
+ deserialiser.new(@serialised, @binary, asset_offset, transaction).deserialise
61
+ end
62
+
63
+ def handle_version_one(transaction)
64
+ if transaction[:second_signature]
65
+ transaction[:sign_signature] = transaction[:second_signature]
66
+ end
67
+
68
+ if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION
69
+ transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address.from_public_key(transaction[:sender_public_key])
70
+ end
71
+
72
+ if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::VOTE
73
+ transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address.from_public_key(transaction[:sender_public_key])
74
+ end
75
+
76
+ if transaction[:type] == ArkEcosystem::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION
77
+ # The "recipientId" doesn't exist on v1 multi signature registrations
78
+ # transaction[:recipient_id] = ArkEcosystem::Crypto::Identity::Address::from_public_key(transaction[:sender_public_key]);
79
+ transaction[:asset][:multisignature][:keysgroup] = transaction[:asset][:multisignature][:keysgroup].map! { |key| '+' + key }
80
+ end
81
+
82
+ if transaction[:vendor_field_hex]
83
+ transaction[:vendor_field] = BTC::Data.data_from_hex(transaction[:vendor_field_hex])
84
+ end
85
+
86
+ unless transaction[:id]
87
+ transaction[:id] = ArkEcosystem::Crypto::Crypto.get_id(transaction)
88
+ end
89
+
90
+ transaction
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,15 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The base deserialiser for transactions.
5
+ class Base
6
+ def initialize(serialised, binary, asset_offset, transaction)
7
+ @serialised = serialised
8
+ @binary = binary
9
+ @asset_offset = asset_offset
10
+ @transaction = transaction
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for delegate registration transactions.
5
+ class DelegateRegistration < Base
6
+ def deserialise
7
+ @transaction[:asset] = {
8
+ delegate: {}
9
+ }
10
+
11
+ username_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
12
+
13
+ username = @serialised[@asset_offset + 2, username_length * 2]
14
+
15
+ @transaction[:asset][:delegate][:username] = BTC::Data.data_from_hex(username)
16
+
17
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (username_length + 1) * 2)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for delegate resignation transactions.
5
+ class DelegateResignation < Base
6
+ def deserialise
7
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for IPFS transactions.
5
+ class IPFS < Base
6
+ def deserialise
7
+ @transaction[:asset] = {}
8
+
9
+ dag_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
10
+
11
+ @transaction[:asset][:dag] = @serialised[@asset_offset + 2, dag_length * 2]
12
+
13
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 2 + length * 2)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for multi payment transactions.
5
+ class MultiPayment < Base
6
+ def deserialise
7
+ @transaction[:asset] = {
8
+ amount: 0,
9
+ payments: []
10
+ }
11
+
12
+ total = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
13
+ offset = @asset_offset / 2 + 1
14
+
15
+ i = 0
16
+ while i < total
17
+ recipient_id = @binary.unpack("H#{(offset + 1) * 2}H42").last
18
+
19
+ payment = {
20
+ amount: @binary.unpack("C#{@asset_offset / 2}Q<").last,
21
+ recipient_id: BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
22
+ }
23
+
24
+ @transaction[:asset][:payments].push(payment)
25
+
26
+ offset += 22
27
+
28
+ i += 1
29
+ end
30
+
31
+ products.each { |item| @transaction[:amount] += item[:amount] }
32
+
33
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, offset * 2)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,32 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for multi signature registrations transactions.
5
+ class MultiSignatureRegistration < Base
6
+ def deserialise
7
+ @transaction[:asset] = {
8
+ multisignature: {
9
+ keysgroup: []
10
+ }
11
+ }
12
+
13
+ @transaction[:asset][:multisignature][:min] = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
14
+ @transaction[:asset][:multisignature][:lifetime] = @binary.unpack("C#{@asset_offset / 2 + 2}Q<").last & 0xff
15
+
16
+ count = @binary.unpack("C#{@asset_offset / 2 + 1}Q<").last & 0xff
17
+
18
+ i = 0
19
+ while i < count
20
+ index_start = @asset_offset + 6 + i * 66
21
+
22
+ @transaction[:asset][:multisignature][:keysgroup].push(@serialised[index_start, 66])
23
+
24
+ i += 1
25
+ end
26
+
27
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 6 + count * 66)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for second signature registrations transactions.
5
+ class SecondSignatureRegistration < Base
6
+ def deserialise
7
+ @transaction[:asset] = {
8
+ signature: {}
9
+ }
10
+
11
+ @transaction[:asset][:signature][:public_key] = @serialised[@asset_offset, 66]
12
+
13
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 66)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for timelock transfer transactions.
5
+ class TimelockTransfer < Base
6
+ def deserialise
7
+ @transaction[:amount] = @binary.unpack("C#{@asset_offset / 2}Q<").last
8
+ @transaction[:timelocktype] = @binary.unpack("C#{@asset_offset / 2 + 8}").last & 0xff
9
+ @transaction[:timelock] = @binary.unpack("C#{@asset_offset / 2 + 9}Q<").last
10
+
11
+ recipient_id = @binary.unpack("H#{(@asset_offset / 2 + 13) * 2}H42").last
12
+ @transaction[:recipient_id] = BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
13
+
14
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (21 + 13) * 2)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for transfer transactions.
5
+ class Transfer < Base
6
+ def deserialise
7
+ @transaction[:amount] = @binary.unpack("C#{@asset_offset / 2}Q<").last
8
+ @transaction[:expiration] = @binary.unpack("C#{@asset_offset / 2 + 8}").last
9
+
10
+ recipient_id = @binary.unpack("H#{(@asset_offset / 2 + 12) * 2}H42").last
11
+ @transaction[:recipient_id] = BTC::Base58.base58check_from_data([recipient_id].pack('H*'))
12
+
13
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + (21 + 12) * 2)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Deserialisers
4
+ # The deserialiser for vote transactions.
5
+ class Vote < Base
6
+ def deserialise
7
+ @transaction[:asset] = {
8
+ votes: []
9
+ }
10
+
11
+ vote_length = @binary.unpack("C#{@asset_offset / 2}Q<").last & 0xff
12
+
13
+ i = 0
14
+ while i < vote_length
15
+ index_start = @asset_offset + 2 + i * 2 * 34
16
+ index_end = 2 * 34
17
+
18
+ vote = @serialised[index_start, index_end]
19
+ vote = (vote[1] == '1' ? '+' : '-') + vote[2..-1]
20
+
21
+ @transaction[:asset][:votes].push(vote)
22
+
23
+ i += 1
24
+ end
25
+
26
+ ArkEcosystem::Crypto::Crypto.parse_signatures(@serialised, @transaction, @asset_offset + 2 + vote_length * 34 * 2)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Enums
4
+ # The list of available tansaction fees.
5
+ class Fees
6
+ TRANSFER = 10_000_000
7
+ SECOND_SIGNATURE_REGISTRATION = 500_000_000
8
+ DELEGATE_REGISTRATION = 2_500_000_000
9
+ VOTE = 100_000_000
10
+ MULTI_SIGNATURE_REGISTRATION = 500_000_000
11
+ IPFS = 0
12
+ TIMELOCK_TRANSFER = 0
13
+ MULTI_PAYMENT = 0
14
+ DELEGATE_RESIGNATION = 0
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module ArkEcosystem
2
+ module Crypto
3
+ module Enums
4
+ # The list of available tansaction types.
5
+ class Types
6
+ TRANSFER = 0
7
+ SECOND_SIGNATURE_REGISTRATION = 1
8
+ DELEGATE_REGISTRATION = 2
9
+ VOTE = 3
10
+ MULTI_SIGNATURE_REGISTRATION = 4
11
+ IPFS = 5
12
+ TIMELOCK_TRANSFER = 6
13
+ MULTI_PAYMENT = 7
14
+ DELEGATE_RESIGNATION = 8
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ require 'btcruby'
2
+ require 'arkecosystem/crypto/configuration/network'
3
+
4
+ module ArkEcosystem
5
+ module Crypto
6
+ module Identity
7
+ # The identity utility for an address.
8
+ class Address
9
+ def self.from_secret(secret, network = nil)
10
+ private_key = PrivateKey.from_secret(secret)
11
+
12
+ from_private_key(private_key, network)
13
+ end
14
+
15
+ def self.from_public_key(public_key, network = nil)
16
+ private_key = BTC::Key.new(public_key: [public_key].pack('H*'))
17
+
18
+ from_private_key(private_key, network)
19
+ end
20
+
21
+ def self.from_private_key(private_key, network = nil)
22
+ network ||= ArkEcosystem::Crypto::Configuration::Network.get
23
+
24
+ public_key = Digest::RMD160.digest(private_key.public_key)
25
+
26
+ BTC::Base58.base58check_from_data([network.version.to_i(16)].pack('c') + public_key)
27
+ end
28
+
29
+ def self.validate(address)
30
+ BTC::Address.parse(address)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'btcruby'
2
+
3
+ module ArkEcosystem
4
+ module Crypto
5
+ module Identity
6
+ # The identity utility for a private key.
7
+ class PrivateKey
8
+ def self.from_secret(secret)
9
+ BTC::Key.new(private_key: Digest::SHA256.digest(secret), public_key_compressed: true)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ require 'btcruby'
2
+
3
+ module ArkEcosystem
4
+ module Crypto
5
+ module Identity
6
+ # The identity utility for a public key.
7
+ class PublicKey
8
+ def self.from_secret(secret)
9
+ PrivateKey.from_secret(secret).public_key
10
+ end
11
+
12
+ def self.from_secret_as_hex(secret)
13
+ from_secret(secret).unpack('H*').first
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'btcruby'
2
+
3
+ module ArkEcosystem
4
+ module Crypto
5
+ module Identity
6
+ # The identity utility for a WIF.
7
+ class WIF
8
+ def self.from_secret(secret, network = nil)
9
+ network ||= ArkEcosystem::Crypto::Configuration::Network.get
10
+
11
+ secret = Digest::SHA256.digest(secret)
12
+
13
+ seed = [network.wif].pack('C*')
14
+ seed << secret
15
+ seed << [0x01].pack('C*')
16
+
17
+ BTC::Base58.base58check_from_data(seed)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end