Posted on Jan 17, 2022Read on Mirror.xyz

How does Metamask generate your accounts with the 12 words?

First let’s distinguish the difference between seed and mnemonic phrase. Those words are often used interchangeably. But if we refer to BIP-32, seed is just a byte sequence such as 000102030405060708090a0b0c0d0e0f.

On the other hand, mnemonic phrase is a list of selected words, which are designed to be easy to remember, to help generate the seed. This was first introduced at BIP-39.

Going back to BIP-32, we can see how a seed can be used to deterministically generate a sequence of bitcoin wallets in a hierarchal way:

Later on, a new standard BIP-44 was introduced aiming to make BIP-32 usable for other compatible blockchains. This standard was used by Ethereum and the Metamask uses the exact algorithm to generate accounts using the 12 English words.

The algorithm can be abstracted as the following API (example at ethers.io):

{address, publicKey, privateKey} = fromMnemonic(mnemonic, path);

There are a couple of things worth explaining:

Firstly, account address and public key are actually different things. There is a common misunderstanding between those two concepts so they are used interchangeably in most cases. But according to


A Bitcoin address is a 160-bit hash of the public portion of a public/private ECDSA keypair

Another question will be asked is: what is the path argument?

That’s exactly how Metamask can generate countless number of accounts with simply the 12-word secret mnemonic phrase. This is referred in BIP-44 as “path levels”. We can easily test it out on this website.

You can select the coin type to be ETH and you will find the derivation path to be:


Here 44 refers to BIP-44 and 60 is the coin type representing ETH.

The website will generate the addresses and the keys for you and you will see similar results as below:

We can notice that only the paths’ lowest level number keeps incrementing. If you import the 12 generated words into Metamask, you will find the exact addresses generated in your Metamask accounts. You can then reveal the private keys for those accounts in Metamask and compare with the results shown on the website.

We can also verify it locally with the following code snippet:

const { ethers } = require("ethers");

const mnemonic = "<REDACTED>";
const wallet = ethers.Wallet.fromMnemonic(mnemonic, "m/44'/60'/0'/0/0");

console.log(wallet.address, wallet.privateKey);

In the end, all the results will match.

Jan 16, 2022 by Smillence