module Base58::SS58

Overview

Substrate's SS58 encoding can be used generically in the same way that Base58Check and CB58 can be. However, the intention of the encoding is to encode Substrate addresses, specifically, and when used for that purpose, there are some additional specifications which apply to encoding and to decoding. There is a small, fixed set of byte sizes which can be encoded, and there are some strict rules regarding how the prefix is structured, how the checksum is calculated, and how many bytes of the checksum are used. Details can be found in the Substrate documentation.

The .encode_address and .decode_address methods here provide implementations of the Substrate specific style of using SS58 for encoding and decoding Substrate compatible addresses.

To use this library to encode and decode data of any arbitrary length, use the .encode and .decode methods instead. These will use a 2 byte checksum for any data that is not 1, 2, 4, 8, or 32 bytes

NOTE Some of these overloads are implemented expediently, but there are places where extra memory copying is done, and so there is room for improvement with regard to performance and efficiency.

Defined in:

base58/ss58.cr

Constant Summary

ChecksumPrefix = "SS58PRE"

This is the standard prefix used for Substrate addresses.

Class Method Summary

Class Method Detail

def self.checksum(check, value : Pointer(UInt8), size) : Tuple(Pointer(UInt8), Slice(UInt8)) #

Calculate a Blake2b checksum on the data referenced by the pointer and size. A tuple containing the pointer to the checksum and the checksum itself is returned.


def self.checksum(check, data : Slice(UInt8)) : Tuple(Pointer(UInt8), Slice(UInt8)) #

Calculate a Blake2b checksum on the data referenced by the slice. A tuple containing the pointer to the checksum and the checksum itself is returned.


def self.decode(payload, into, format = 42) #

To decode content with an arbitrary length payload, use .decode instead of .decode_address.


def self.decode_address(address, into : StaticArray(UInt8, N).class, format : Int | Nil = nil) forall N #

def self.decode_address(address, into : String.class = String, format : Int | Nil = nil) #

def self.decode_address(address, into : Array(UInt8).class, format : Int | Nil = nil) #

def self.decode_address(address, into : Array(Char).class, format : Int | Nil = nil) #

def self.decode_address(address, into : Slice(UInt8).class, format : Int | Nil = nil) #

def self.decode_address(address, into : StringBuffer.class, format : Int | Nil = nil) #

def self.decode_address(address, into : Pointer(UInt8).class, format : Int | Nil = nil) #

def self.decode_address(address, into : String, mutate : Bool = false, format : Int | Nil = nil) #

def self.decode_address(address, into : Array(UInt8), format : Int | Nil = nil) #

def self.decode_address(address, into : Array(Char), format : Int | Nil = nil) #

def self.decode_address(address, into : Slice(UInt8), format : Int | Nil = nil) #

def self.decode_address(address, into : StaticArray(UInt8, N), format : Int | Nil = nil) forall N #

def self.decode_address(address, into : StringBuffer, format : Int | Nil = nil) #

def self.decode_address(address, into : Pointer(UInt8), format : Int | Nil = nil) #

def self.encode(payload, into, format : Int = 42) #

To encode content with an arbitrary length payload, use the .encode method instead of .encode_address. The Substrate SS58 spec only prescribes checksum lengths for payloads which are 1, 2, 4, 8, or 32 bytes long. So, for other payloads, this library is defaulting to a 2 byte checksum.


def self.encode_address(address, into : StaticArray(UInt8, N).class, format : Int = 42) forall N #

def self.encode_address(address, into : String.class = String, format : Int = 42) #

def self.encode_address(address, into : Array(UInt8).class, format : Int = 42) #

def self.encode_address(address, into : Array(Char).class, format : Int = 42) #

def self.encode_address(address, into : Slice(UInt8).class, format : Int = 42) #

def self.encode_address(address, into : StringBuffer.class, format : Int = 42) #

def self.encode_address(address, into : Pointer(UInt8).class, format : Int = 42) #

def self.encode_address(address, into : String, mutate : Bool = false, format : Int = 42) #

def self.encode_address(address, into : Array(UInt8), format : Int = 42) #

def self.encode_address(address, into : Array(Char), format : Int = 42) #

def self.encode_address(address, into : Slice(UInt8), format : Int = 42) #

def self.encode_address(address, into : StaticArray(UInt8, N), format : Int = 42) forall N #

def self.encode_address(address, into : StringBuffer, format : Int = 42) #

def self.encode_address(address, into : Pointer(UInt8), format : Int = 42) #