arkecosystem-crypto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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