Mastering Addresses In Ethereum

Oluwatosin Serah
15 min readJun 1, 2023

--

Welcome 👋 to another article series on mastering Ethereum addresses. In this article, we will explore the fundamental aspects of Ethereum addresses and their crucial role within the Ethereum ecosystem. We will simplify complex concepts, provide practical examples, and share best practices to help you understand and utilize Ethereum addresses effectively.

By the end of this article, you will have a comprehensive understanding of Ethereum addresses, enabling you to confidently handle transactions, interact with smart contracts, and secure your assets within the Ethereum ecosystem. Let’s dive in and master addresses in Ethereum!

What is an Ethereum address?

Just like our traditional bank account used for making transactions. An Ethereum address is a 20-byte hexadecimal number that is used to identify an account on the Ethereum blockchain. They are unique identifiers used to send, receive, and store Ether (ETH), tokens, and access decentralized applications on the Ethereum blockchain. They serve as a digital representation of a participant or entity within the Ethereum ecosystem. Each Ethereum address is composed of a string of alphanumeric characters and typically starts with “0x” to indicate its hexadecimal format.

Types of Accounts in Ethereum

There are two types of Ethereum accounts each with its address:

  • Externally owned accounts (EOAs) are accounts that are controlled by users. EOAs can hold and manage Ether (ETH) and other tokens on the Ethereum blockchain. They are primarily used for initiating transactions, such as sending ether or tokens to other addresses. EOAs can be created by generating a new Ethereum account using wallet software like MetaMask.
  • Contract accounts are owned by smart contracts and can be used to interact with the Ethereum blockchain. Contract addresses are unique addresses that are associated with smart contracts deployed on the Ethereum blockchain.

A smart contract is a self-executing program that runs on the Ethereum Virtual Machine (EVM) and performs predefined functions when triggered by certain conditions.

When a smart contract is deployed, it is assigned a contract address, which serves as its identifier on the Ethereum network. Contract addresses are used to interact with smart contracts by sending transactions to invoke their functions,access their data, modify the contract’s state, or produce specific outputs.

So basically we have Externally Owned Addresses, and Contract Addresses.

Difference Between EOAs and Contract Account

  • Creation: EOAs are created by users. In contrast, contract accounts are created by deploying a smart contract to the Ethereum blockchain.
  • Key Pair: EOAs have a private-public key pair. The private key is used to sign transactions and provide proof of ownership. Unlike EOAs, there are no public or private keys associated with a contract account.
  • Control: EOAs are controlled by users, meaning that users have control over the private keys associated with their EOAs. In contrast, contract accounts are controlled by the logic of the smart contract code. The code defines the rules and behavior of the contract account.
  • Transaction Signing: Only EOAs can sign transactions because they have a private key. The signature generated using the private key ensures the authenticity and integrity of the transaction. Contract accounts, however, cannot sign transactions since they lack a private key.
  • Interactions: EOAs can interact with the Ethereum blockchain through transactions. They can send ether (ETH) or interact with other smart contracts by invoking their functions, while contract accounts can interact with the Ethereum blockchain through transactions and events, which are logged on the blockchain and can be observed by external parties.
  • Actions: EOAs can perform actions explicitly allowed by the user. They can transfer funds, interact with contracts, and initiate various transactions based on the user’s intentions. On the other hand, contract accounts can perform actions explicitly allowed by the code. The behavior of a contract account is defined in the smart contract code, and it can only execute functions and actions that have been programmed into it.

Similarities between EOAs and Contract Accounts

  • They both have addresses. EOAs and contract addresses are both 20-byte hexadecimal strings that identify the account on the Ethereum blockchain.
  • They can both hold Ether and ERC-20 tokens. EOAs and contract accounts can both hold ether and tokens.
  • They can both interact with the Ethereum blockchain. EOAs and contract accounts can both send and receive ether, and they can both interact with decentralized applications (DApps).

How Addresses are generated

Ethereum addresses are generated using a process called the Elliptic Curve Digital Signature Algorithm (ECDSA). ECDSA is a cryptographic algorithm that uses a pair of keys, a public key and a private key, to sign and verify digital signatures.

Digital signatures use cryptographic algorithms to generate a unique digital fingerprint, or hash, of a document or message. The hash is then encrypted using the signer’s private key to create a signature. The recipient can verify the authenticity of the signature by using the signer’s public key to decrypt the hash and comparing it to the hash of the original document or message. If the hashes match, the signature is valid.

A digital signature can be created to sign any message. For Ethereum transactions, the details of the transaction itself are used as the message. The mathematics of cryptography in this case, elliptic curve cryptography provides a way for the message (i.e., the transaction details) to be combined with the private key to create a code that can only be produced with knowledge of the private key. That code is called the digital signature.

Externally Owned Address Generation

The public key is calculated from the private key using elliptic curve multiplication, which is practically irreversible: K = k * G, where k is the private key, G is a constant point called the generator point, K is the resulting public key, and * is the special elliptic curve “multiplication” operator.
Note that elliptic curve multiplication is not like normal multiplication.

Arithmetic on the elliptic curve is different from “regular” integer arithmetic. A point (G) can be multiplied by an integer (k) to produce another point (K). But there is no such thing as division, so it is not possible to simply “divide” the public key K by the point G to calculate the private key k. This is a one-way mathematical function.

A private key can be converted into a public key, but a public key cannot be converted back into a private key, because the math only works one way. The private key is used to sign transactions and prove ownership of an address.

🚨Never share your private key with anyone!!! Sharing your private key can lead to unauthorized access and control over your Ethereum account, including the ability to transfer or manipulate funds.

Here are some other tips for keeping your Ethereum address and private key safe:

  • Store your private key in a secure offline location.
  • Use a strong password to protect your wallet.
  • Keep your software up to date.
  • Be careful of phishing attacks.

Private keys should never be shared or disclosed with anyone, as they are the primary means of proving ownership and control over Ethereum addresses and the associated assets.

Externally Owned Address are generated using the following steps:

  • Random Private Key: Let’s assume we generate a random private key: 0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
  • Public Key Generation: Using the private key, we generate a corresponding public key using elliptic curve cryptography (specifically, the secp256k1 curve).
  • Hash Generation: We generate a hash of the public key using the Keccak-256 hashing algorithm. Public Key Hash: 0x4b6f5a3dfc911e992c3d8f38c6bb9d1563b5e9a526260ee1a83693a8e56f4f48
  • Address Derivation: From the Keccak-256 hash of the public key, we take the last 20 bytes (160 bits) to obtain the EOA address. EOA Address: 0x4b6f5a3dfc911e992c3d8f38c6bb9d1563b5e9a5
  • Prefixing: Finally, we prefix the 20-byte EOA address with “0x” to signify its hexadecimal format. Prefixed EOA Address: 0x4b6f5a3dfc911e992c3d8f38c6bb9d1563b5e9a5

This is a simplified example to demonstrate the process of generating an EOA address. In reality, there are additional considerations such as key pair generation algorithms and encoding formats, but the basic concept remains the same.

Contract Address Generation

Contract addresses are generated using a combination of the deploying account’s address and a nonce value, which represents the number of transactions sent from that account.

The contract address is derived by RLP encoding the deploying account’s address and the nonce using the Keccak-256 hashing algorithm.

Contract addresses are deterministic, meaning that the same contract deployed from the same account with the same nonce will always result in the same address.

Here is a more detailed explanation of the process:

  • The deploying account’s address is obtained. Let’s assume the deployer’s account’s address is: 0x0123456789abcdef0123456789abcdef0123456
  • The nonce value is obtained. Let’s assume the nonce value is 5
  • The deploying account’s address and the nonce value are concatenated. We concatenate the deploying account’s address and the nonce value: 0x0123456789abcdef0123456789abcdef01234565
  • The concatenation is then RLP encoded.
    Keccak-256 Hash: 0x4b6f5a3dfc911e992c3d8f38c6bb9d1563b5e9a526260ee1a83693a8e56f4f48
  • The first 20 bytes of the hash are used as the contract address.
    Following our example, the Contract Address is prefixed with the “0x” character.: 0x4b6f5A3dFc911E992c3D8F38C6bb9D1563B5e9A5

Note that this is a simplified example for illustration purposes, and in practice, additional steps and considerations might be involved in the deployment process.

Features of Ethereum Addresses

  • Ethereum addresses are 20 bytes long or 160 bits.
  • Ethereum addresses are represented in hexadecimal format, using base 16 notation. Each character in the address corresponds to 4 bits. An Ethereum address consists of exactly 40 characters, chosen from the range of 0–9 and a-f (a total of 16 possible values per character).
  • Ethereum addresses are always prefixed with “0x” to indicate the hexadecimal format. This prefix is necessary for distinguishing Ethereum addresses from other types of data. Hence, the total length of an Ethereum address, including the prefix, is 42 characters.

By understanding the length, format, and prefix of Ethereum addresses, you can accurately identify and work with them in Solidity and other Ethereum-related applications.

Solidity is the programming language used in writing Smart Contract on EVM compatible chains

It is important to note that Ethereum addresses are case-insensitive, meaning that capitalization does not affect their interpretation. All wallets and systems within the Ethereum ecosystem are designed to accept Ethereum addresses expressed in either capital or lowercase characters without any distinction.

For example, the addresses

"0x4b6f5a3dfc911e992c3d8f38c6bb9d1563b5e9a5" and 
"0x4B6F5A3DFC911E992C3D8F38C6BB9D1563B5E9A5"

would be considered the same address and refer to the same Ethereum account.

Significance of hexadecimal representation in Ethereum addresses

  • Compactness: Hexadecimal is a base-16 number system, which means that each digit can represent one of 16 values (0–9 and A-F). This makes hexadecimal addresses much more compact than decimal addresses, which would require 32 digits to represent the same information.
  • Uniqueness: Hexadecimal addresses are unique, which is important for preventing fraud and errors. For example, if a decimal address were to be entered incorrectly, it could easily be mistaken for another address.
  • Compatibility: Hexadecimal addresses are compatible with other blockchains that use hexadecimal addresses, such as Bitcoin and others. This makes it easy to transfer funds between different blockchains.

Significance of checksum feature in Ethereum addresses

  • Error prevention: The checksum feature helps to prevent errors when entering Ethereum addresses. If an error is made, the checksum will not match, and the transaction will fail. This helps protect users from losing funds due to typos or other errors.
  • Security: The checksum feature also adds an extra layer of security to Ethereum addresses. If an attacker were to try to create a fake address, the checksum would not match, and the transaction would fail. This helps protect users from fraud and theft.

The hexadecimal representation and the checksum feature are both important features of Ethereum addresses. They help to ensure that addresses are compact, unique, compatible, error-proof, and secure. Check out EIP55 for more details on checksums.

Addresses in Solidity Smart Contract

In Solidity, addresses are a primitive type. This means that they can be used in expressions and statements just like other primitive types, such as integers and strings.

Here are some of the things you can do with addresses in Solidity:

Declaring an address variable in Solidity
You can declare an address variable by using the address keyword. For example:

address myAddress;

Assigning an address to a variable
You can assign an address to a variable by using the = operator. For example:

myAddress = 0x2e504C9c22089cE75a600fF113e891d2c2D53d57;

Comparing addresses in Solidity
You can compare addresses using the == and != operators. For example:

if (myAddress == 0x2e504C9c22089cE75a600fF113e891d2c2D53d57) {
// Do something
}

Accessing a smart contract address
You can access a smart contract’s address using the address(this) method. For example:

address contractAddr = address(this);

Getting the balance of a smart contract address
You can get the Ether balance of a smart contract using the address(this).balance method. For example:

uint256 balance = address(this).balance;

Explicit address conversion in Solidity
It is important to note that not all addresses are payable, and if you try to send ethers to a non-payable address, the transaction will fail. The conversion to “address payable” can be done using payable(address(x)). The conversion from address to “address payable” is done to enable sending ether to the address.

This conversion is used when calling a contract function that has the “payable” modifier, which allows it to receive ether. The “payable” keyword makes the function accept ether and increases the balance of the contract by the amount of ether received.
Check out my article on Payable and Nonpayable function to learn more.

//address payable provides the transfer function
address payable payableAddress;

Sending Ether from a smart contract
You can send Ether from a smart contract using the send , transferor callmethod. For example:

contract SendEther {
function sendViaTransfer(address payable _to) public payable {
// This function is no longer recommended for sending Ether.
_to.transfer(msg.value);
}

function sendViaSend(address payable _to) public payable {
// Send returns a boolean value indicating success or failure.
// This function is not recommended for sending Ether.
bool sent = _to.send(msg.value);
require(sent, "Failed to send Ether");
}

function sendViaCall(address payable _to) public payable {
// Call returns a boolean value indicating success or failure.
// This is the current recommended method to use.
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}

Interacting with a smart contract
When it comes to interacting with a smart contract on the Ethereum blockchain, there are various methods available. One common way is to use the function call, delegatecall, or similar functions. For example:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

// NOTE: Deploy this contract first
contract B {
// NOTE: storage layout must be the same as contract A
uint public num;
address public sender;
uint public value;

function setVars(uint _num) public payable {
num = _num;
sender = msg.sender;
value = msg.value;
}
}

contract A {
uint public num;
address public sender;
uint public value;

function setVars(address _contract, uint _num) public payable {
// A's storage is set, B is not modified.
(bool success, bytes memory data) = _contract.delegatecall(
abi.encodeWithSignature("setVars(uint256)", _num)
);
}
}

The contract above consists of two contracts: contract A and contract B.

Contract B is designed to store three variables: num (an unsigned integer), sender (an address), and value (an unsigned integer). The setVars function in contract B allows these variables to be set with the provided values.

Contract A also has the same three variables: num, sender, and value. The setVars function in contract A is used to interact with contract B. It takes an address parameter _contract that represents the address of contract B and a uint parameter _num. Inside the setVars function in contract A, a delegatecall is made to contract B, passing the _num value to its setVars function.

The purpose of this contract is to demonstrate how a delegatecall can be used to interact with another contract and modify its storage. By making a delegatecall to contract B, contract A can modify its own storage variables using the setVars function of contract B. This can be useful in certain scenarios where you want to reuse or extend the functionality of another contract while maintaining the storage layout.

Check out my article on Delegatecall to learn more.

Returning an address type
When working with smart contracts on Ethereum, it is common to have methods that return values for the address type. Here are a few examples of how you can handle methods that return an address:

  • Mapping Access: If the method returns an address within a mapping, you can access it using the corresponding key. For example:
mapping(uint256 => address) addressesMapping;

address myAddress = addressesMapping[key];
  • Function Call: You can directly call the method and use the returned address value in subsequent operations. For example:
mapping(uint256 => address) addressesMapping;

function returnAddress(uint256 _key) external view returns(address){
return addressesMapping[_key];
}
  • Array Access: If the method returns an address within an array, you can access it using the index. For example:
address myAddress = myArray[index];

Zero Address
The zero address, also known as the null address or the zero account, refers to the Ethereum address:

0x0000000000000000000000000000000000000000

It is a special address in the Ethereum ecosystem that is hard-coded to have the value of all zeros. It is a special address that has no balance and cannot be used to send or receive transactions.

The zero address is used in a few different ways in Ethereum:

  • To create new contracts: When a new contract is created, it is assigned the zero address. The contract’s address is then updated once the transaction is mined.
  • To burn tokens: When tokens are burned, they are sent to the zero address. This makes them permanently unavailable.

Here are some of the things you cannot do with the zero address:

  • Send Ether to the zero address: Any ether sent to the zero address is permanently lost.
  • Create a contract at the zero address: Any transaction that attempts to create a contract at the zero address will fail.
  • Interact with a contract at the zero address: Any transaction that attempts to interact with a contract at the zero address will fail.

The zero address is a special address that should not be used for any purpose other than those listed above. If you send Ether to the zero address or attempt to create a contract or interact with a contract at the zero address, you will lose your funds or your transaction will fail.

How Addresses are stored In the EVM

Addresses are stored in the EVM’s state trie. The state trie is a data structure that stores all of the state information on the Ethereum blockchain. This includes the balances of all accounts, the code of all contracts, and the data of all storage variables.

The state trie is a Merkle tree, which is a type of data structure that is very efficient for storing and retrieving data. The state trie is organized by address, with each address having its own branch in the tree.

Merkle Patricia Tree

When an address is stored in the EVM, it is first hashed using the Keccak-256 hashing algorithm. The hash is then used to find the corresponding branch in the state trie. The balance of the address, the code of any contracts at the address, and the data of any storage variables are all stored in this branch.

Addresses are stored in the EVM in a decentralized manner. This means that no single entity has control over the storage of addresses. This helps to ensure the security and reliability of the Ethereum network.

Address obfuscation

Address obfuscation is a technique that aims to hide or obfuscate the true ownership or identity associated with an Ethereum address. These techniques can be used to enhance privacy and prevent address-based tracking or analysis. This can be done by using a variety of techniques, such as:

  • Hashing: An Ethereum address can be hashed to create a shorter, more anonymous identifier.
  • Nonce: A nonce is a random number that can be used to obfuscate an Ethereum address.
  • Mixing: Multiple Ethereum addresses can be mixed together to create a single, anonymous address.

Here are a few commonly employed address obfuscation techniques:

  1. Address Reuse Avoidance: To avoid address-based tracking, users can generate a new address for each transaction or interaction, ensuring that no two transactions are associated with the same address.
  2. Coin Mixing: Coin mixing services (also known as coin tumblers or mixers) allow users to pool their funds with other users and then redistribute them to different addresses, making it difficult to trace the flow of funds.
  3. Hierarchical Deterministic (HD) Wallets: HD wallets generate a hierarchical tree of addresses from a single master seed. By using different child addresses for each transaction, users can obfuscate their transaction history and ownership.
  4. Stealth Addresses: Stealth addresses enable the recipient to generate a unique one-time address for each transaction. The sender encrypts the payment with the recipient’s stealth address, ensuring that only the intended recipient can decipher it.

Zero-knowledge proofs(ZKPs)

Zero-knowledge proofs are a cryptographic technique that allows two parties to verify information about each other without revealing any confidential information. This can be used to protect user privacy on the Ethereum blockchain by allowing users to prove that they have certain assets without revealing the specific amounts or addresses.

Benefits of using address obfuscation and Zero-knowledge proofs

  • Increased privacy: Address obfuscation and ZKPs can help protect user privacy by making it difficult to associate an Ethereum address with a real-world identity.
  • Reduced risk of fraud: Address obfuscation and ZKPs can help reduce the risk of fraud by making it more difficult for attackers to track user activity and steal funds.
  • Improved user experience: Address obfuscation and ZKPs can help improve the user experience by making it easier for users to participate in decentralized applications without fear of their privacy being compromised.

Some of the drawbacks of using address obfuscation and ZKPs

  • Reduced transparency: Address obfuscation and ZKPs can reduce transparency by making it more difficult to track the flow of funds on the Ethereum blockchain.
  • Potential for abuse: Address obfuscation and ZKPs can be used to facilitate illegal activity.

These privacy-focused solutions leverage advanced cryptographic techniques to protect user privacy, enhance transactional anonymity, and provide stronger privacy guarantees within the Ethereum ecosystem. They offer users more control over their personal information and mitigate the risks associated with address-based tracking and analysis.

Conclusion

Mastering Ethereum addresses is crucial for navigating the Ethereum ecosystem effectively. By mastering Ethereum addresses, you gain confidence in transactions, smart contract interactions, and asset security. Understanding best practices empowers participation in the decentralized revolution. Thank you for taking the time to read this article. I hope you found it informative and helpful in understanding Ethereum addresses. Stay tuned for my next article!

References and Tools

Solidity Documentation on Addresses
Mastering Delegatecall in Solidity
Mastering Payable and Non payable functions in Solidity
EIP55 on Checksum
Ethereum Explorer
Ethereum Yellowpaper
Metamask Extension

--

--

Oluwatosin Serah

Smart Contract Developer || Blockchain Educator || Technical Writer || Researcher