Understanding Ethereum Wallets, Addresses and Accounts.

Understanding Ethereum Wallets, Addresses and Accounts.

In the coming months, it is expected that the user experience on Ethereum will move away from the use of Externally Owned Accounts - EOA to Smart Contract Accounts - SCA. I have been on a personal study journey to understand how user interactions happen in the Ethereum world, as a background for learning more about Account Abstraction. In this article, I will explain the current state of generating Accounts in the Ethereum ecosystem.

Basically, to carry out activities i.e. transactions in Ethereum, a user needs an Ethereum Account. An Ethereum Account is a combination of the Private Key <> Public Address pair to denote identity and ownership. Hence the popular phrase “Not your keys? Not your wallet!” It is easy to think of Accounts in Ethereum, as an email address, and password combination. Where the Email Address is the Public Address, and the Password is the Private Key. Thus, anyone can send an email to you using your email address.

Your email address can be used to identify you, and you can also provide your email address to login into apps. You are the only one in possession of your password, thus, you are the only one that can sign into your email address using your password. For reiteration, your email which is public is your “Address”.

Wallets are essentially applications that are built to enable you to interact with your Ethereum account(s). Using the email analogy, you can think of The Company Google providing Gmail as a Wallet application. Thus, in the Ethereum ecosystem, wallet examples include, MetaMask, Trust Wallet, Wallet Connect etc.

There you have it, the basic difference between Wallets, Addresses and Accounts in Ethereum. Harping more on Accounts, which is the Private Key <> Public Address pair, it is important to understand how an Address is generated from an Account.

To access the Ethereum Ecosystem, you need an Account. The beauty of account creation in the Ethereum ecosystem is that it happens offline. All that is required is the running of various algorithms to create a Public Address.

According to the QuikNode docs here's how an Ethereum address is generated:

A random private key of 64 (hex) characters (256 bits / 32 bytes) is generated first. For example:

0xf4a2b939592564feb35ab10a8e04f6f2fe0943579fb3c9c33505298978b74893

A 128 (hex) character (64 bytes) public key is then derived from the generated private key using Elliptic Curve Digital Signature Algorithm (ECDSA). For example:

0x04345f1a86ebf24a6dbeff80f6a2a574d46efaa3ad3988de94aa68b695f09db9ddca37439f99548da0a1fe4acf4721a945a599a5d789c18a06b20349e803fdbbe3

The Keccak-256 hash function is then applied to (128 characters / 64 bytes) the public key to obtain a 64 character (32 bytes) hash string. The last 40 characters / 20 bytes of this string prefixed with 0x become the final Ethereum address. For example:

0xd5e099c71b797516c10ed0f0d895f429c2781142

Note: 0x in coding indicates that the number/string is written in hex.


We can use the Go-Ethereum Library Geth to generate an Ethereum Address. Geth provides us with a module clef that is used for account management. It goes without saying that you need to be running a client node to access this feature.

Given the complexities of running an Ethereum node, other options for generating an Ethereum Address include using Ethereum Libraries Web3JS or EthersJS.

WEB3JS

Web3JS contains the web3.eth.accounts method, which contains functions to generate Ethereum accounts and sign transactions and data.

Running this script in a NodeJS app

const web3 = require('web3');

const account = web3.eth.accounts.create();
console.log(account);

Will log the following response to the console

{
  address: '0xA588CE075A5ab367245c508FEDcAe799BDa80Fa1',
  privateKey: '0x-yourPrivateKeyString',
  signTransaction: [Function: signTransaction],
  sign: [Function: sign],
  encrypt: [Function: encrypt]
}

EthersJS

To create an Account in EthersJS, run this script:

var ethers = require('ethers');  
var crypto = require('crypto');

var id = crypto.randomBytes(32).toString('hex');
var privateKey = "0x"+id;
console.log("SAVE BUT DO NOT SHARE THIS:", privateKey);


var wallet = new ethers.Wallet(privateKey);
console.log("Address: " + wallet.address);

The crypto module which comes with NodeJS, provides cryptographic functionality that includes a set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions.

The result logged to the console:

SAVE BUT DO NOT SHARE THIS: 0xyourPrivateKeyString
Address: 0xd9e3bB87e6c77edC675D955718A6fE90c9d55815

You can take the Private Key, and import it into your MetaMask Wallet Address and test it!


Going down this path is important for me, as I needed to be certain that I can succinctly explain how Accounts in Ethereum are generated, and this in turn has led me to understand how transactions are signed in Ethereum. In due time, I hope to learn a lot more about Account Abstraction and how to create Smart Contract Accounts.

I like to receive feedback! Please, tweet at me @emma_odia Cheers!