How are Accounts on Polkadot and Substrate created?
You may be familiar with this user interface when you want to interact with the network for the first time 🕹.
You will see fields like name, mnemonic seed, password, and keypair crypto type (Schnorrkel — sr25519 or Edwards — ed25519) and secret derivation path.
🧠 The mnemonic seed is 12 (default), 15, 18, 21 and 24 words. You literally don’t need to remember these as you will download your account to file and can be restored lately or used in a wallet that supports Polkadot accounts
🔑 Password is used to encode your secret key in the keyring, so no one can steal your funds/tokens when will randomly find it on the table.
Keypair crypto type is preferred to use sr25519. Ed25519 is an older cryptography to generate keys. It was used more in the past and for validator sets mostly.
You’ve clicked create & save backup and ta-da 🔊 Your account is now created and saved locally, you are safe now 😌
🤔 What happened in the background?
Disclaimer, I’m an author of offline Polkadot/Substrate keyring tool where you can generate Polkadot and Substrate accounts too. It works straight from mobile and offline. Bonus part, it’s written in Vue.js & Typescript 😎
That’s why I was curious to know more about how accounts are made at Polkadot, I’ve made reimplementation into Vue.js using Typescript.
What you can see here is literally the same. Duh.
Name of your account, 🏷 tags (recognized for now only in your dashboard, not by the network), 🧠mnemonic seed, 🔑password, keypair crypto type (sr25519 — default).
After clicking 💾Download account, the browser will save your account into local file. Take care of that file and don’t stick it with your password.
🎭 Behind the scenes: Create account
Beware, dirty sketchy code without tests 👨🏼🔬🧙♂️
The main function for a mnemonic generation on load is mnemonicGenerate() which is based on top of bip39Generate() which is Javascript wrapper on top of bip39.rs.
Then we will initialize keyring(), which is the real core abstraction around key management in our tool to manage various keypairs. To utilize keyring, we will use function addFromMnemonic() with a generated mnemonic, meta and our keyringType which is in this case sr25519.
In another line you find mnemonicValidate() which literally checksums if your mnemonic is the right one.
For the next operations, we need to know what is our SS58 address (specification in details). SS58 is a simple address format designed for Substrate based chains. It is heavily based on Bitcoin’s Base-58-check format with a few alterations. For this, we will use getPair() on top of the keyring. It will retrieve an account keyring pair from the Keyring Pair Dictionary, given an account address.
For verifying signatures, we need publicKey, we will get it same using getPair() but also need to use Uint8Array to Hexadecimal function, using u8aToHex()
🍰 Bonus stage. Sign and verify the signature
Next action, what we can do with this web-based Subkey is to sign data by your secret key. This is good whenever you need to pass some data and you need to verify it by the same keypair if it’s signed by your trusted party, your keypair.
Now if somebody supplied you signed data with the same keypair you have, you can verify them with your keypair.
Ta-da, that’s it, you successfully verified data with a keypair.
🎭 Behind the scenes: Sign & Verify Signature
What’s happening in the background during these two actions?
To sign data, we will use sub-method from KeyringPair, called sign(). It requires data in Uint8Array and will return them in Uint8Array. Next step we will convert it to hexadecimal for easier transportation over the network.
To verify signed data, we need to put into schnorrkelVerify() (it’s based on top of sr25519.rs) function three things. Signed data, signature and our publicKey. We got them all from the previous steps.
This seems like basic cryptography 101, but in the background, there are a lot of cryptography utils running from wasm-crypto. Thanks to awesome parity team Parity Technologies and Polkadot. 👏
Basic utils we are using are a subset of https://polkadot.js.org/common/ namely
- Key management of user accounts — https://polkadot.js.org/common/keyring/
- Various useful crypto utility like mnemonicGenerate — https://polkadot.js.org/common/util-crypto/
- Utilities for converting formats i.e. u8aToHex, stringToU8A — https://polkadot.js.org/common/util/
🗝 Subkey 🍉
Subkey is a commandline utility included with Substrate that generates or restores Substrate keys. You can find more in subkey documentation
subkey generate
What we see here is mnemonic seed (secret phrase), secret seed, that’s in hexadecimal format, public key in hexadecimal and our SS58 address
We can do also the same actions as we did with web-based Subkey.
Sign data
Verify Signature
Conclusion
For kind readers, creating and using accounts on Polkadot is a subset of various crypto utilities which are crucial for basic interaction with the network. Around these utils are built other apps like app-democracy or app-council, app-staking, app-transfer and others.
Sources
https://polkadot.js.org/common
https://wiki.polkadot.network/en/latest/polkadot/build/tools/subkey