Class: Address

Inherits:
Object
  • Object
show all
Defined in:
lib/address.rb

Overview

Constant Summary collapse

SS58_PREFIX =
'SS58PRE'
TYPES =
[
  # Polkadot Live (SS58, AccountId)
  0, 1,
  # Polkadot Canary (SS58, AccountId)
  2, 3,
  # Kulupu (SS58, Reserved)
  16, 17,
  # Darwinia Live
  18,
  # Dothereum (SS58, AccountId)
  20, 21, 
  # Generic Substrate wildcard (SS58, AccountId)
  42, 43,
  
  # Schnorr/Ristretto 25519 ("S/R 25519") key
  48,
  # Edwards Ed25519 key
  49,
  # ECDSA SECP256k1 key
  50,
  
  # Reserved for future address format extensions.
  *64..255
]

Class Method Summary collapse

Class Method Details

.array_to_hex_string(arr) ⇒ Object


58
59
60
61
# File 'lib/address.rb', line 58

def array_to_hex_string(arr)
  body = arr.map { |i| i.to_s(16).rjust(2, '0') }.join
  "0x#{body}"
end

.decode(address, addr_type = 42, ignore_checksum = true) ⇒ Object


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/address.rb', line 63

def decode(address, addr_type = 42, ignore_checksum = true)
  decoded = Base58.base58_to_binary(address, :bitcoin)
  is_pubkey = decoded.size == 35
  
  size = decoded.size - ( is_pubkey ? 2 : 1 )
  
  prefix = decoded[0, 1].unpack("C*").first
  
  raise "Invalid address type" unless TYPES.include?(addr_type)
  
  hash_bytes = make_hash(decoded[0, size])
  if is_pubkey
    is_valid_checksum = decoded[-2].unpack("C*").first == hash_bytes[0] && decoded[-1].unpack("C*").first == hash_bytes[1]
  else
    is_valid_checksum = decoded[-1].unpack("C*").first == hash_bytes[0]
  end
  
  raise "Invalid decoded address checksum" unless is_valid_checksum && ignore_checksum
  
  decoded[1...size].unpack("H*").first
end

.encode(pubkey, addr_type = 42) ⇒ Object


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/address.rb', line 86

def encode(pubkey, addr_type = 42)
  pubkey = pubkey[2..-1] if pubkey =~ /^0x/i
  key = [pubkey].pack("H*")
  
  u8_array = key.bytes
  
  u8_array.unshift(addr_type)
  
  bytes = make_hash(u8_array.pack("C*"))
  
  checksum = bytes[0, key.size == 32 ? 2 : 1]
  
  u8_array.push(*checksum)
  
  input = u8_array.pack("C*")
  
  Base58.binary_to_base58(input, :bitcoin)
end

.make_hash(body) ⇒ Object


105
106
107
# File 'lib/address.rb', line 105

def make_hash(body)
  Blake2b.bytes("#{SS58_PREFIX}#{body}", Blake2b::Key.none, 64)
end