Closed wbh1328551759 closed 3 years ago
Happy to help.
Do you have a sample file JSON that fails?
yes, like this , and password is '1'
{"address":"5PjeoaQzCoYbSi42aQRKB3Sx18StCaEAzCbGEEbWbZyfKS3H","encoded":"JQUl8ZpoXv2OMkL9TPylLmcIye2cYhaS9INICbFgZTsAgAAAAQAAAAgAAAAr/0hJOOzokIdBG71TstigLABX9D5xGD7L37ySxtjDrVRg26LL90jLQ47quT9o3bq6ppXMVL6USk7Q4p3WU66bojTFuCDyhpYRhNbUqU6s0rD3S4bhv9lG+pG9vQ4eD5PVQUvxdANmJpYuDg45nrTmsMC5AHGdFGkHW/LHnkmbFid1cvPYkdiBoef5CIEdoly512pxMupVxnJWF1NT","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0x012cfb6997279fed8ff754a5a90cb30627c70fcdd79ee9c480bcef07de754810","name":"ss","tags":[],"whenCreated":1614751681701}}
So technically, this should work -
import { decodePair } from '@polkadot/keyring/pair';
import { base64Decode } from '@polkadot/util-crypto';
...
const JSONPair = pair.toJson('1')
const decoded = decodePair('1', base64Decode(JSONPair.encoded), JSONPair.encoding.type);
So above the encoded part is base64, so needs to be decoded from that.
Ohhh, thanks !. It worked successfully. I got the publicKey and secretKey through this method. Then I used the u8aToHex()
method to process the secretKey and got a 64-bit Uint8Array data, so what do I need to do next to let the user to create the original account through this secretKey?
Then I used the subarray(32)
method, and then put it into the account creation component of the wallet, and found that the address generated by this result is not the address of the original account, but I have used publicKey to confirm that it is indeed corresponding, so is the method I used wrong? Still need to use what method to operate secretKey?
This is the publicKey and secretKey I got
publicKey: 0x044adc4365288575acaaa1544e983b7e24255ad298fa0d09df8f4e96c458a923
secretKey: 0xe0f3d7c96717943a21213eb3f0137c10466ac9f9262a938af6ce40410092fc66e885414439fe67aa9a3480c76bfbcbc71b9852854b7f1ff43eaaa622d10c7d1b
I'm sorry i'm not very familiar with this
If you have the public & secret, you can just use them as-is into createPair.
If you wish to extract the seed part, at least for sr25519 it would be .subarray(0, 32)
(the first 32 bytes)
I have verified that the publicKey of the account is indeed correct, but the account address of the seed conversion obtained through .subarray(0,32)
is indeed not the same as the original one. I think I need to discuss this process with my colleagues tomorrow.
Thank you for your reply, I will reply to you the result of this question as soon as the discussion is completed
If the publicKey is correct, the private needs to match. Who’s means the address should be the same - the ss58 is just an encoding of the publicKey.
So assuming the address mismatch is just the ss58 format.
Hi @jacogr . Now I get this object containing publicKey and secretKey through the decodePair()
method, but the length of the secretKey obtained is 64 bits, which does not match expectations. I understand that the return value should be a 32-bit publicKey and secretKey, so yes what operation caused the difference in the number of digits of the secretKey? Do I need to use any operation to process the secretKey to make it the same as expected? And My goal now is to convert this secretKey into the seed that users can use to create the original account
This is the object I got using decodePair
So it really depends on the type. For instance -
So it is tricky gong back to seed. The best way, which is what the keyring uses (which generally manages all the JSON encoding/decoding), is to actually pass the full public/private to the createPair
from https://github.com/polkadot-js/common/blob/master/packages/keyring/src/pair/index.ts#L91 to re-create the pair.
It it optimized for the case to use the keyring to manage all of this. Internally the keyring applies the correct logic from JSON, from seed, etc.
I think this is not a tricky way. Since users are allowed to create accounts through privateKeys, it should be possible in theory to allow users to export their private keys. This is convenient for users without saving their private keys. Then re-export the private key to save
I saw that the "ed25519" encrypted account can directly get the 32-byte seed, and since the encryption method we currently use is "sr25519", we can’t get the seed directly, so for the "sr25519" encrypted account, how should we parse out the 32-bit seed? What about the correct private key?
The 64 bytes as-is is the correct private key (fully-expanded) for sr25519. (And which is actually used in all sr25519 interfaces)
I know this, but why the raw seed generated by sr25519 encryption on this account creation page is 32-bit? The goal now is to be able to get this 32-bit and be able to use it to create the original account again, but the current implementation is the 64-bit secretKey I obtained cannot be used to recreate the original account
The above is a minisecret in sr25519 terminology - it gets expanded into a full pair with private/public when the creation takes place, see eg. https://github.com/polkadot-js/wasm/blob/master/packages/wasm-crypto/src/rs/sr25519.rs#L82-L88
See https://github.com/polkadot-js/common/pull/918/files for the additional createFromPair on the keyring.
Hi, @jacogr ,At present, the function we want to achieve is to provide this minisecretkey to users, which is what the community wants us to do, so we want to know what method we should use to convert this 64-bit secretKey into the correct 32-bit minisecretKey
I don’t believe that is exposed on the wasm layer, nor is there a function like this on the sr25519 libs.
This is the one area where I would suggest not listening to users - passing hex strings around instead of mnemonics is a very bad idea.
If you want to try, the secretKey is made of of 32 bytes + 32 bytes nonce - so the first 32 is the mini, but the ed25519 expansion mode shift is applied to it - not sure if the shift is on-way, if it is, can be re-used. See https://github.com/w3f/schnorrkel/blob/master/src/keys.rs
OK, I understand what you mean. I think we should listen to your suggestions. Thank you for your patience and prompt reply. Thank you very much!
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.
Hello, I am a member of the chainx team. During the development of the wallet, we need to convert the keystore to the private key. After I try to use keyring.getPair to get the pair, I convert its encoded with stringToU8a and then use the decodePair method to decode it. But it failed and reported this error: This is the code of my process:
Then I read the code of decodePair function and found that the error is in this code But what I can’t understand is that I manually printed out N, p, r, and found that this assert trigger condition was not met, but it triggered this problem. So I'm here for help. If I want to get the private key of my account from the keystore, how should I get it?