Class: ScaleRb::Address
- Inherits:
-
Object
- Object
- ScaleRb::Address
- Defined in:
- lib/address.rb
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
- .decode(address, addr_type = 42, _ignore_checksum = true) ⇒ Object
- .encode(pubkey, addr_type = 42) ⇒ Object
- .is_ss58_address?(address) ⇒ Boolean
- .make_hash(body) ⇒ Object
Class Method Details
.decode(address, addr_type = 42, _ignore_checksum = true) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/address.rb', line 34 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].unpack1('C*') raise 'Invalid address type' unless TYPES.include?(addr_type) hash_bytes = make_hash(decoded[0, size]) is_valid_checksum = if is_pubkey decoded[-2].unpack1('C*') == hash_bytes[0] && decoded[-1].unpack1('C*') == hash_bytes[1] else decoded[-1].unpack1('C*') == hash_bytes[0] end # raise "Invalid decoded address checksum" unless is_valid_checksum && ignore_checksum decoded[1...size].unpack1('H*') end |
.encode(pubkey, addr_type = 42) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/address.rb', line 57 def encode(pubkey, addr_type = 42) pubkey = pubkey[2..-1] if pubkey =~ /^0x/i key = [pubkey].pack('H*') pubkey_bytes = key.bytes checksum_length = case pubkey_bytes.length when 32, 33 2 when 1, 2, 4, 8 1 else raise 'Invalid pubkey length' end ss58_format_bytes = if addr_type < 64 [addr_type].pack('C*') else [ ((ss58_format & 0b0000_0000_1111_1100) >> 2) | 0b0100_0000, (ss58_format >> 8) | ((ss58_format & 0b0000_0000_0000_0011) << 6) ].pack('C*') end input_bytes = ss58_format_bytes.bytes + pubkey_bytes checksum = Utils.hex_to_u8a(Blake2b.hex(SS58_PREFIX.bytes + input_bytes, 64)) Base58.binary_to_base58((input_bytes + checksum[0...checksum_length]).pack('C*'), :bitcoin) end |
.is_ss58_address?(address) ⇒ Boolean
91 92 93 94 95 96 97 98 |
# File 'lib/address.rb', line 91 def is_ss58_address?(address) begin decode(address) rescue StandardError return false end true end |
.make_hash(body) ⇒ Object
87 88 89 |
# File 'lib/address.rb', line 87 def make_hash(body) Blake2b.hex("#{SS58_PREFIX}#{body}".bytes, 64) end |