-
Notifications
You must be signed in to change notification settings - Fork 153
Open
Description
Hi again. Reopening #2006 as this is happening again:
import { ethers, Mnemonic, HDNodeWallet, Signature } from 'ethers';
import { Keyring } from '@polkadot/keyring';
import { stringToU8a, u8aToHex } from '@polkadot/util';
import { keccakAsU8a, cryptoWaitReady } from '@polkadot/util-crypto';
// ======= config =======
const MNEMONIC = process.env.MNEMONIC || 'hover message cause expand once spare impact unhappy risk lecture explain join';
const MESSAGE = 'Test';
const PRIMARY_PATH = "m/44'/60'/0'/0/0";
const LOOK_FOR = '0xDf43C58c3b353e273Fbf68b5FBBaA518e1Df7757'; // your "expected"
// ======================
async function deriveEthers(mnemonic, path) {
const m = Mnemonic.fromPhrase(mnemonic);
return HDNodeWallet.fromMnemonic(m, path);
}
function normalizeSigV(sigHex) {
const b = Buffer.from(sigHex.slice(2), 'hex');
if (b[64] === 0 || b[64] === 1) b[64] += 27;
return '0x' + b.toString('hex');
}
(async () => {
await cryptoWaitReady();
// -------- derive on both SDKs (same mnemonic & path) --------
const wallet = await deriveEthers(MNEMONIC, PRIMARY_PATH);
const keyring = new Keyring();
const pair = keyring.createFromUri(`${MNEMONIC}/${PRIMARY_PATH}`, undefined, 'ethereum', undefined, 2048);
console.log('--- Derived account (primary path) ---');
console.log('Path :', PRIMARY_PATH);
console.log('Expected :', LOOK_FOR);
console.log('ethers address :', wallet.address);
console.log('polkadot.js address :', pair.address);
console.log('same? :', wallet.address.toLowerCase() === pair.address.toLowerCase());
console.log();
// -------- sign RAW digest (no EIP-191), then recover --------
const digest = keccakAsU8a(stringToU8a(MESSAGE)); // 32-byte keccak256("Test")
const digestHex = ethers.hexlify(digest);
const sigEthersStruct = await wallet.signingKey.sign(digestHex);
const sigEthers = Signature.from(sigEthersStruct).serialized;
const sigDot = normalizeSigV(u8aToHex(pair.sign(digest, { withType: false })));
const recFromEthersSig = ethers.recoverAddress(digestHex, sigEthers);
const recFromDotSig = ethers.recoverAddress(digestHex, sigDot);
console.log('--- Signing & recovery check ---');
console.log('Message :', MESSAGE);
console.log('Digest :', digestHex);
console.log('ethers sig :', sigEthers);
console.log('dot sig :', sigDot);
console.log('rec(ethers sig) :', recFromEthersSig);
console.log('rec(dot sig) :', recFromDotSig);
console.log('==> matches derived? :', recFromEthersSig.toLowerCase() === wallet.address.toLowerCase()
&& recFromDotSig.toLowerCase() === wallet.address.toLowerCase());
console.log();
// -------- optional: search common paths/indexes for your EXPECTED address --------
const commonRoots = [
"m/44'/60'/0'/0", // most wallets (account 0, change 0)
"m/44'/60'/0'", // some tools show account as the leaf
];
})();
Result:
--- Derived account (primary path) ---
Path : m/44'/60'/0'/0/0
Expected : 0xDf43C58c3b353e273Fbf68b5FBBaA518e1Df7757
ethers address : 0xDf43C58c3b353e273Fbf68b5FBBaA518e1Df7757
polkadot.js address : 0xDf43C58c3b353e273Fbf68b5FBBaA518e1Df7757
same? : true
--- Signing & recovery check ---
Message : Test
Digest : 0x85cc825a98ec217d960f113f5f80a95d7fd18e3725d37df428eb14f880bdfc12
ethers sig : 0x7ebee7a1d35775aaf8a39c759676b380cfac887959205792c034e4e9e8ab4f7c5b0a23adbec207d833f8d78b29cc5a0d87b069a0f053b93f5b69460a9201d2ca1b
dot sig : 0x89a7081374ddc746d4792d03cead8c0ac25b449fff8ee8884eb6f8bcbc51d99d0b1511d0a9c1a231e3a7e809c1be83cd19ff9b71174661d126a31818d19471361b
rec(ethers sig) : 0xDf43C58c3b353e273Fbf68b5FBBaA518e1Df7757
rec(dot sig) : 0x584F579Dd674CCa3c2c9C1EDD2A27725ee6f449e
==> matches derived? : false
Versions:
"@polkadot/keyring": "14.0.1",
"@polkadot/util": "14.0.1",
"@polkadot/util-crypto": "14.0.1",
"ethers": "^6.16.0",
Metadata
Metadata
Assignees
Labels
No labels