From fa6300c2a28d35052bae799da104c299efbea3c0 Mon Sep 17 00:00:00 2001 From: Dan Shields <35669742+NukeManDan@users.noreply.github.com> Date: Tue, 2 Nov 2021 00:16:00 +0100 Subject: [PATCH 1/5] update ss58 page --- v3/docs/07-advanced/h-ss58/index.mdx | 143 ++++++++++++++++++++++----- 1 file changed, 119 insertions(+), 24 deletions(-) diff --git a/v3/docs/07-advanced/h-ss58/index.mdx b/v3/docs/07-advanced/h-ss58/index.mdx index c9606095e..a9eac675f 100644 --- a/v3/docs/07-advanced/h-ss58/index.mdx +++ b/v3/docs/07-advanced/h-ss58/index.mdx @@ -7,13 +7,113 @@ category: advanced keywords: --- -SS58 is a simple address format designed for Substrate based chains. There's no problem with using -other address formats for a chain, but this serves as a robust default. It is heavily based on -Bitcoin's Base-58-check format with a few alterations. +SS58 is a simple address format designed for Substrate based chains. +There's no problem with using other address formats for a chain, but this serves as a robust default. +It is heavily based on Bitcoin's Base-58-check format with a few alterations. -The basic idea is a base-58 encoded value that can identify a specific account on the Substrate -chain. Different chains have different means of identifying accounts. SS58 is designed to be -extensible for this reason. +The basic idea is a base-58 encoded value which can identify a specific account on the Substrate chain. +Different chains have different means of identifying accounts. +SS58 is designed to be extensible for this reason. + +## Format in detail + +This page outlines the implimented of [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html). +Also of note is the cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) of adress type mappings to various networks described below. + +### Basic Format + +The basic format conforms to: + +``` +base58encode ( concat ( ,
, ) ) +``` + +That is, the concatenated byte series of address type, address and checksum then passed into a base-58 encoder. +The `base58encode` function is exactly as [defined](https://en.wikipedia.org/wiki/Base58) in Bitcoin and IPFS, +using the same alphabet as both. + +### Address Type + +The `` is one or more bytes that describe the precise format of the following bytes. + +Currently, there exist several valid values: + +- 00000000b..=00111111b (0..=63 inclusive): Simple account/address/network identifier. + The byte can be interpreted directly as such an identifier. +- 01000000b..=01111111b (64..=127 inclusive) Full address/address/network identifier. + The low 6 bits of this byte should be treated as the upper 6 bits of a 14 bit identifier value, + with the lower 8 bits defined by the following byte. This works for all identifiers up to 2**14 (16,383). +- 10000000b..=11111111b (128..=255 inclusive) Reserved for future address format extensions. + +The latter (42) is a "wildcard" address that is meant to be equally valid on all Substrate networks that support fixed-length addresses. +For production networks, however, a network-specific version may be desirable to help avoid the key-reuse between networks and some of the problems that it can cause. +Substrate Node will default to printing keys in address type 42, +though alternative Substrate-based node implementations (e.g. Polkadot) may elect to default to some other type. + +### Address Formats for Substrate + +There are 16 different address formats, identified by the length (**in bytes**) of the total payload (i.e. including the checksum). + +| Total | Type | Raw Account | Checksum | +|:-----:|:----:|:-----------:|:--------:| +| 3 | 1 | 1 | 1 | +| 4 | 1 | 2 | 1 | +| 5 | 1 | 2 | 2 | +| 6 | 1 | 4 | 1 | +| 7 | 1 | 4 | 2 | +| 8 | 1 | 4 | 3 | +| 9 | 1 | 4 | 4 | +| 10 | 1 | 8 | 1 | +| 11 | 1 | 8 | 2 | +| 12 | 1 | 8 | 3 | +| 13 | 1 | 8 | 4 | +| 14 | 1 | 8 | 5 | +| 15 | 1 | 8 | 6 | +| 16 | 1 | 8 | 7 | +| 17 | 1 | 8 | 8 | +| 34 | 1 | 32 | 2 | + +## Checksum types + +Several potential checksum strategies exist within Substrate, giving different length and longevity guarantees. +There are two types of checksum preimage (known as SS58 and AccountID) and many different checksum lengths (1 to 8 bytes). + +In all cases for Substrate, the [Blake2-256](https://en.wikipedia.org/wiki/BLAKE_(hash_function)) hash function is used. +The variants simply select the preimage used as the input to the hash function and the number of bytes taken from its output. + +The bytes used are always the left most bytes. +The input to be used is the non-checksum portion of the SS58 byte series used as input to the base-58 function, i.e. `concat( ,
)`. +A context prefix of `0x53533538505245`, (the string `SS58PRE`) is prepended to the input to give the final hashing preimage. + +The advantage of using more checksum bytes is simply that more bytes provide a greater degree of protection against input errors and +index alteration at the cost of widening the textual address by an extra few characters. +For the account ID form, this is insignificant and therefore no 1-byte alternative is provided. +For the shorter account-index formats, the extra byte represents a far greater portion of the final address and +so it is left for further up the stack (though not necessarily the user themself) to determine the best tradeoff for their purposes. + +## Simple/full address types and account/address/network identifiers + +[The registry](https://github.com/paritytech/ss58-registry) expresses the status of the account/address/network *identifiers*. + +*Identifiers* up to value 64 may be expressed in a *simple* format address, +in which the LSB byte of the identifier value is expressed as the first byte of the encoded address. + +For identifiers of between 64 and 16,383, the *full* format address must be used. + +The encoding of this is slightly fiddly since we encode as LE, +yet the first two bits (which should encode 64s and 128s) are already used up with the necessary `01` prefix. +We treat the first two bytes as a 16 bit sequence, +and we disregard the first two bits of that (since they're already fixed to be `01`. +With the remaining 14 bits, we encode our identifier value as little endian, +with the assumption that the two missing higher order bits are zero. +This effectively spreads the low-order byte across the boundary between the two bytes. + +Thus the 14-bit identifier `0b00HHHHHH_MMLLLLLL` is expressed in the two bytes as: + +- `0b01LLLLLL` +- `0bHHHHHHMM` + +Identifiers of 16384 and beyond are not currently supported. ## Validating addresses @@ -21,14 +121,14 @@ There are several ways to verify that a value is a valid SS58 address. ### Subkey -You can use the [Subkey](/v3/tools/subkey) `inspect` -subcommand, which accepts the seed phrase, a hex-encoded private key, or an SS58 address as the input -URI. If the input is a valid address, it will return a list containing the corresponding public -key (hex), account ID, and SS58 values. +You can use the [Subkey](/v3/tools/subkey) `inspect` subcommand, +which accepts the seed phrase, a hex-encoded private key, or an SS58 address as the input URI. +If the input is a valid address, +it will return a list containing the corresponding public key (hex), account ID, and SS58 values. -Subkey assumes that an address is based on a public/private keypair. In the case of inspecting an -address, it will return the 32 byte account ID. Not all addresses in Substrate-based networks are -based on keys. +Subkey assumes that an address is based on a public/private keypair. +In the case of inspecting an address, it will return the 32 byte account ID. +Not all addresses in Substrate-based networks are based on keys. Date: Mon, 8 Nov 2021 11:12:12 +0100 Subject: [PATCH 2/5] Update v3/docs/07-advanced/h-ss58/index.mdx Co-authored-by: Sacha Lansky --- v3/docs/07-advanced/h-ss58/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v3/docs/07-advanced/h-ss58/index.mdx b/v3/docs/07-advanced/h-ss58/index.mdx index a9eac675f..5baf51c7d 100644 --- a/v3/docs/07-advanced/h-ss58/index.mdx +++ b/v3/docs/07-advanced/h-ss58/index.mdx @@ -17,7 +17,7 @@ SS58 is designed to be extensible for this reason. ## Format in detail -This page outlines the implimented of [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html). +This page outlines the implementation of [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html). Also of note is the cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) of adress type mappings to various networks described below. ### Basic Format From 9412e2df60b869bd0a14ebd6559064bc5e48a04c Mon Sep 17 00:00:00 2001 From: Dan Shields <35669742+NukeManDan@users.noreply.github.com> Date: Mon, 8 Nov 2021 11:17:20 +0100 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Sacha Lansky --- v3/docs/07-advanced/h-ss58/index.mdx | 51 +++++++++++----------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/v3/docs/07-advanced/h-ss58/index.mdx b/v3/docs/07-advanced/h-ss58/index.mdx index 5baf51c7d..48962e368 100644 --- a/v3/docs/07-advanced/h-ss58/index.mdx +++ b/v3/docs/07-advanced/h-ss58/index.mdx @@ -20,7 +20,7 @@ SS58 is designed to be extensible for this reason. This page outlines the implementation of [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html). Also of note is the cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) of adress type mappings to various networks described below. -### Basic Format +### Basic format The basic format conforms to: @@ -29,10 +29,9 @@ base58encode ( concat ( ,
, ) ) ``` That is, the concatenated byte series of address type, address and checksum then passed into a base-58 encoder. -The `base58encode` function is exactly as [defined](https://en.wikipedia.org/wiki/Base58) in Bitcoin and IPFS, -using the same alphabet as both. +The `base58encode` function is implemented exactly as [defined](https://en.wikipedia.org/wiki/Base58) in Bitcoin and IPFS, using the same alphabet as both. -### Address Type +### Address type The `` is one or more bytes that describe the precise format of the following bytes. @@ -40,15 +39,14 @@ Currently, there exist several valid values: - 00000000b..=00111111b (0..=63 inclusive): Simple account/address/network identifier. The byte can be interpreted directly as such an identifier. -- 01000000b..=01111111b (64..=127 inclusive) Full address/address/network identifier. - The low 6 bits of this byte should be treated as the upper 6 bits of a 14 bit identifier value, - with the lower 8 bits defined by the following byte. This works for all identifiers up to 2**14 (16,383). -- 10000000b..=11111111b (128..=255 inclusive) Reserved for future address format extensions. +- 01000000b..=01111111b (64..=127 inclusive): Full address/address/network identifier. + The lower 6 bits of this byte should be treated as the upper 6 bits of a 14 bit identifier value, with the lower 8 bits defined by the following byte. + This works for all identifiers up to 2**14 (16,383). +- 10000000b..=11111111b (128..=255 inclusive): Reserved for future address format extensions. The latter (42) is a "wildcard" address that is meant to be equally valid on all Substrate networks that support fixed-length addresses. For production networks, however, a network-specific version may be desirable to help avoid the key-reuse between networks and some of the problems that it can cause. -Substrate Node will default to printing keys in address type 42, -though alternative Substrate-based node implementations (e.g. Polkadot) may elect to default to some other type. +Substrate nodes will default to printing keys in address type 42, though alternative Substrate-based node implementations (e.g. Polkadot) may elect to default to some other type. ### Address Formats for Substrate @@ -76,7 +74,7 @@ There are 16 different address formats, identified by the length (**in bytes**) ## Checksum types Several potential checksum strategies exist within Substrate, giving different length and longevity guarantees. -There are two types of checksum preimage (known as SS58 and AccountID) and many different checksum lengths (1 to 8 bytes). +There are two types of checksum preimages (known as SS58 and AccountID) and many different checksum lengths (1 to 8 bytes). In all cases for Substrate, the [Blake2-256](https://en.wikipedia.org/wiki/BLAKE_(hash_function)) hash function is used. The variants simply select the preimage used as the input to the hash function and the number of bytes taken from its output. @@ -85,27 +83,21 @@ The bytes used are always the left most bytes. The input to be used is the non-checksum portion of the SS58 byte series used as input to the base-58 function, i.e. `concat( ,
)`. A context prefix of `0x53533538505245`, (the string `SS58PRE`) is prepended to the input to give the final hashing preimage. -The advantage of using more checksum bytes is simply that more bytes provide a greater degree of protection against input errors and -index alteration at the cost of widening the textual address by an extra few characters. -For the account ID form, this is insignificant and therefore no 1-byte alternative is provided. -For the shorter account-index formats, the extra byte represents a far greater portion of the final address and -so it is left for further up the stack (though not necessarily the user themself) to determine the best tradeoff for their purposes. +The advantage of using more checksum bytes is simply that more bytes provide a greater degree of protection against input errors and index alteration at the cost of widening the textual address by an extra few characters. +For the account ID format, this is insignificant and therefore no 1-byte alternative is provided. +For the shorter account-index formats, the extra byte represents a far greater portion of the final address, so it is left for further up the stack (though not necessarily the user themself) to determine the best tradeoff for their purposes. ## Simple/full address types and account/address/network identifiers [The registry](https://github.com/paritytech/ss58-registry) expresses the status of the account/address/network *identifiers*. -*Identifiers* up to value 64 may be expressed in a *simple* format address, -in which the LSB byte of the identifier value is expressed as the first byte of the encoded address. +*Identifiers* up to value 64 may be expressed in a *simple* format address, in which the least significant byte (LSB) of the identifier value is expressed as the first byte of the encoded address. For identifiers of between 64 and 16,383, the *full* format address must be used. -The encoding of this is slightly fiddly since we encode as LE, -yet the first two bits (which should encode 64s and 128s) are already used up with the necessary `01` prefix. -We treat the first two bytes as a 16 bit sequence, -and we disregard the first two bits of that (since they're already fixed to be `01`. -With the remaining 14 bits, we encode our identifier value as little endian, -with the assumption that the two missing higher order bits are zero. +This encoding is slightly fiddly since we encode as little endian (LE), yet the first two bits (which should encode 64s and 128s) are already used up with the necessary `01` prefix. +We treat the first two bytes as a 16 bit sequence, and we disregard the first two bits of that (since they're already fixed to be `01`). +With the remaining 14 bits, we encode our identifier value as LE, with the assumption that the two missing higher order bits are zero. This effectively spreads the low-order byte across the boundary between the two bytes. Thus the 14-bit identifier `0b00HHHHHH_MMLLLLLL` is expressed in the two bytes as: @@ -121,10 +113,8 @@ There are several ways to verify that a value is a valid SS58 address. ### Subkey -You can use the [Subkey](/v3/tools/subkey) `inspect` subcommand, -which accepts the seed phrase, a hex-encoded private key, or an SS58 address as the input URI. -If the input is a valid address, -it will return a list containing the corresponding public key (hex), account ID, and SS58 values. +You can use the [Subkey](/v3/tools/subkey) `inspect` subcommand, which accepts the seed phrase, a hex-encoded private key, or an SS58 address as the input URI. +If the input is a valid address, it will return a list containing the corresponding public key (hex), account ID and SS58 values. Subkey assumes that an address is based on a public/private keypair. In the case of inspecting an address, it will return the 32 byte account ID. @@ -153,8 +143,7 @@ Invalid phrase/URI given ### PolkadotJS API -For verifying an address in your JavaScript projects, -you can utilize the functions built into the [PolkadotJS API](https://polkadot.js.org/docs/api/). +For verifying an address in your JavaScript projects, you can utilize the functions built into the [PolkadotJS API](https://polkadot.js.org/docs/api/). ```javascript // Import Polkadot.js API dependencies. @@ -193,7 +182,7 @@ They each validate addresses in their own way, and can act as a starting point. - [SS58 Transform](https://polkadot.subscan.io/tools/ss58_transform) - to manually verify an address (sanity check). ## Learn more -- [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html). +- [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html) - The cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) - [Polkadot-js API on GitHub](https://github.com/polkadot-js/api) - [Install Subkey](/v3/tools/subkey#installation) From 9ebfa75cf6065c41e8884ee62584e4c4705b050b Mon Sep 17 00:00:00 2001 From: Dan Shields Date: Mon, 8 Nov 2021 11:24:37 +0100 Subject: [PATCH 4/5] tweak --- v3/docs/07-advanced/h-ss58/index.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/v3/docs/07-advanced/h-ss58/index.mdx b/v3/docs/07-advanced/h-ss58/index.mdx index 48962e368..1036b8ece 100644 --- a/v3/docs/07-advanced/h-ss58/index.mdx +++ b/v3/docs/07-advanced/h-ss58/index.mdx @@ -169,10 +169,10 @@ const isValid = isValidSubstrateAddress() console.log(isValid) ``` -### Ecosystem tools +### Ecosystem SS58 tools Below you will find a list of other Substrate API tools built in various languages by our community. -They each validate addresses in their own way, and can act as a starting point. +They each validate SS58 addresses in their own way, and can be used to transform and interact with addresses, as well act as a guide for implimenting tools like this yourself. - [Python Substrate Interface](https://polkascan.github.io/py-substrate-interface/#substrateinterface.Keypair) - developed by Polkascan. - [Go Substrate RPC client](https://github.com/centrifuge/go-substrate-rpc-client) - developed by Centrifuge. @@ -182,6 +182,7 @@ They each validate addresses in their own way, and can act as a starting point. - [SS58 Transform](https://polkadot.subscan.io/tools/ss58_transform) - to manually verify an address (sanity check). ## Learn more + - [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html) - The cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) - [Polkadot-js API on GitHub](https://github.com/polkadot-js/api) From a8db5b665bd86cb27c972d50cd98d48b541bb529 Mon Sep 17 00:00:00 2001 From: Dan Shields Date: Mon, 8 Nov 2021 11:44:56 +0100 Subject: [PATCH 5/5] move to awesomelist --- v3/docs/07-advanced/h-ss58/index.mdx | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/v3/docs/07-advanced/h-ss58/index.mdx b/v3/docs/07-advanced/h-ss58/index.mdx index 1036b8ece..cdf99b9ec 100644 --- a/v3/docs/07-advanced/h-ss58/index.mdx +++ b/v3/docs/07-advanced/h-ss58/index.mdx @@ -169,21 +169,11 @@ const isValid = isValidSubstrateAddress() console.log(isValid) ``` -### Ecosystem SS58 tools - -Below you will find a list of other Substrate API tools built in various languages by our community. -They each validate SS58 addresses in their own way, and can be used to transform and interact with addresses, as well act as a guide for implimenting tools like this yourself. - -- [Python Substrate Interface](https://polkascan.github.io/py-substrate-interface/#substrateinterface.Keypair) - developed by Polkascan. -- [Go Substrate RPC client](https://github.com/centrifuge/go-substrate-rpc-client) - developed by Centrifuge. -- [C++ Polkadot Substrate API](https://github.com/usetech-llc/polkadot_api_cpp) - developed by Usetech. -- [.Net API](https://github.com/usetech-llc/polkadot_api_dotnet) - developed by Usetech. -- [Go implemented utilities](https://github.com/itering/subscan-essentials) - developed by Subscan. -- [SS58 Transform](https://polkadot.subscan.io/tools/ss58_transform) - to manually verify an address (sanity check). - ## Learn more - [`Ss58Codec` in Substrate](https://paritytech.github.io/substrate/master/sp_core/crypto/trait.Ss58Codec.html) - The cannonical [SS58 registry](https://github.com/paritytech/ss58-registry) - [Polkadot-js API on GitHub](https://github.com/polkadot-js/api) - [Install Subkey](/v3/tools/subkey#installation) +- [Ecosystem client +libs](https://substrate.io/ecosystem/resources/awesome-substrate/#client-libraries) and [tools(https://substrate.io/ecosystem/resources/awesome-substrate/#tools)] \ No newline at end of file