The logic behind Ethereum Wallets

Moe Elsharif
Neufund
Published in
7 min readDec 11, 2018

--

Ethereum Wallets come in different shapes and sizes, some are hardware wallets, you can hold them in your hand, others are programs on your laptop, extensions in your browser or a complete stand-alone browser.

They are all so different, yet they mostly operate and interact with the Ethereum network as if they were the same. More interestingly you can use the same key inside different wallets and successfully conduct transactions. How is it possible that you can have so many different implementations and types of wallets and still everything works in concert(to an extent)?

Before jumping to conclusions lets have a look at what is what.

The logic behind

Bitcoin transactions work with what is known as public/private key cryptography. I will spare you the math voodoo involved but what is important, is that there are two parts of generated keys or what you commonly refer to as a wallet. One is your secret the other one is public.

  • The private part or the “Private Key” should at all times kept by you as a secret.
  • The public part or the “Public Key” can be shared with anyone publicly without the fear of losing your private key.

With a private key, you can sign a transaction and prove that you signed it with your public key. Anyone can check the validity of this claim by taking your signed message and your public key to crosscheck the results.

This means with a:

  • private key: You can sign messages or transactions and generate public keys which derive more private keys.
  • public key: You can validate if a message or a transaction was indeed signed by the private part of this public key and mathematically prove it.

Ethereum and Smart Contracts

The logic mentioned works very similar in Ethereum in the sense that a user can create a wallet by generating a random private key. This private key gives you access to your account. From this private key, you can generate a public key. If a user wants to send you funds they will send them via your public key. But for you to access them and send them to someone else you need your private key.

However, it gets more interesting when dealing with smart contracts where you have many possibilities of transactions and logical approaches which you can implement with your specific private key. Let's say a smart contract has a rule where a specific user has administrator abilities and can delete users from a given list in this smart contract. The smart contract can cross check if the deleted instructions were indeed coming from the user with correct access rights by validating if the message was actually signed by the user with the public key that represents this user.

Now the question is how do you generate these public/private key pairs? How is it possible that I can use the same account in the ledger nano, light wallet and Metamask at the same time?

Standards

STANDARDS! Yes, it's not magic, there are a couple of standards that define the behavior of these wallets and how they should generate keys. Many of these standards are driven by the community but in general, the basic standards for most Ethereum compatible wallets are BIP32, BIP39, BIP44.

Initially they were Bitcoin Improvement Proposals that became EIPs Ethereum Improvement Proposals and accepted at a later point. Even though the way accounts work in Ethereum and Bitcoin is different, the public/private key generation is similar.

BIP32

BIP32 is a standard that explains the way Hierarchy Deterministic wallets should function. It describes the operation as follows. You have a parent master key and from this parent key, you derive many child keys based on a specific derivation path. The derivation path defines how to derive the child key from the master key. You can imagine the derivation path as a street address and the master key is the starting point. For this simple visualization to work we need to set some rules as you can’t take any steps back but you can always go forward.

As a simple example, let's imagine that in the derivation path can only have 3 (in reality 2*32) digits so 0 1 2 where

0 = NORTH/WEST
1 = NORTH
2 = NORTH/EAST

Whenever you are at a crossroad that can go in any of these directions you can move as long as it is towards the North.

So the parent key is the starting point or the GPS starting coordinates, let’s say:

xprv9s21ZrQH143K2JZkgkQ9HiUy1vrNVUswN6XjH6Yjj8oNBWYjmbrdPq5WF1ceZ21Sw7M13sHr9mqy7xokssxRTNdS8ZZP6YSLyXpiUBbFiBY

and the derivation path to the correct child key is

m/1/0/2/0

As a Hierarchy Deterministic Wallet basically you can:

  • Start from the Master Key or the initial Coordinates.
  • Follow the instructions of the derivations’ path. The first being North then on the next turn you can move towards NORTH/WEST and at the next one towards NORTH/EAST
  • At each crossroad, the child key changes and becomes the parent of the next child key until you reach the final point.
  • Once all the derivation paths are followed you arrive at your child key.

What is interesting is that if you start from the same point the same street combinations will always generate the same key. In turn, you can also never go back. So if you have a destination address and a path you will never find the source address.

This is important because it means that starting from a specific random point (A private key), you can always generate the same child keys given the same derivation path. And this is why no matter where you store your private key — on paper, in metamask, on a ledger, or in your head — you will always safely generate the same keys.

Take into account though, that with any given parent key you can generate a number of child keys, these child keys can also become parent keys for other child keys, creating a very large number of keys. Exposing child keys around will not compromise parent keys, however, exposing parent keys even if they were public will expose child keys except if a child key is hardened. Generating a hardened key adds an extra process to the key generation which makes it impossible to expose the child key from the parent.

BIP39

Storing and dealing with keys that look like this isn’t an easy task.

xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi

How would you make sure you didn’t make a mistake copying this code correctly to paper? Or how can you make sure that everything was entirely copied? BIP39 tries to solve this problem by transforming this alien language looking key into something like this:

pride lock access sting marriage ignore raven nut mistake twelve cousin smoke march blind episode

Nice some English. this way it is easier for someone to memorize these words and to make sure that the seed was copied correctly. This was done in order to make things more robust and less error-prone. If you are annoyed that the words are in English and somehow English doesn't really appeal to you don’t worry! There are dictionaries for Japanese, Korean, Spanish, Chinese (Simplified), Chinese (Traditional), French, Italian and, well, English.

There are a couple of rules that you need to follow when implementing BIP39:

  • The number of generated words must be a multiplier of 32either 12, 15 ,18, 21 or 24
  • The words taken from a word list should be different. Tor example woman and women shouldn’t exist.
  • The sequence of words should fulfill a checksum check.

The checksum is very useful in the sense that it helps eliminate the simple word copying mistakes. So you can’t just randomly choose 12 or 24 words and call it a day. The words have to fulfill a special checksum.

YES! Nothing is left to chance.

BIP44

Still, with the improved user experience of BIP39, BIP32 allows for too much freedom. Many implementations of BIP32 wallets can be broken, for example, how a general derivation path is chosen. BIP44 propose that instead of starting from the beginning and choosing randomly street directions, it it better to save the first two derivations of the derivation path for the purpose and coin type. That looks like this:

m / purpose' / coin_type' / account' / change / address_index

For example :

44/60/0/0/1

44 Indicates that this derivation path follows the BIP44 Standard and 60 indicates that the purpose is for Ethereum and 0 indicates that this address is for the main net. In other words, it makes it easier to know what’s going on or let’s say which city to start from instead of having the whole world as a choice.

Sounds Good

Still, with defined proposals, it's not easy to create a wallet that can fit in many places as not everyone follows these standards. Also, the more users you have on your platform the more you need to look at different implementations. Consensys’ Light Wallet only takes 12 words, the ledger Nano only takes 24 words. Bitcore Library had a case where the generated words were different than in another library. In the end, it all comes down to what is important: portability, features etc.

Join our telegram chat if you have questions or want to meet the Neufund community and team. You can also submit a question here. Or visit our subreddit to join the conversation. Our Freshdesk is a great resource to learn the Neufund basics.

--

--