---
title: "Address Type"
description: "Address Type covers 20-byte blockchain addresses in Intelligent Contracts, including users, contracts, and interactions"
source: https://docs.genlayer.com/developers/intelligent-contracts/types/address
last_updated: 2026-06-11
---

# Address Type

The `Address` type is a 20-byte blockchain address type for Intelligent Contracts, similar to Ethereum addresses. It is one of the most important types for handling user accounts, contract addresses, and cross-contract interactions.

## Creating Address Instances

Use these patterns to instantiate an `Address` from different encodings. Choose the one that matches your source data. Construction validates size and normalizes the value so later comparisons and serializations are consistent.

```python
# Constructing Address values from common encodings
# From hex string (most common)
address1 = Address("0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6")
address2 = Address("0x0000000000000000000000000000000000000000")  # Zero address (useful as a sentinel/null)

# From base64 encoded string (handy when integrating with systems that emit base64)
address3 = Address("WzjaanAcVoVF3PywP8uHX1a+3cQ=")

# From bytes (20 bytes, useful for low-level calls or pre-parsed data)
address4 = Address(b'\x5b\x38\xda\x6a\x70\x1c\x56\x85\x45\xdc\xfc\xb0\x3f\xcb\x87\x5f\x56\xbe\xdd\xc4')
```

## Address Properties and Conversions

`Address` exposes multiple read-only views for common encodings. Use these when you need a specific serialization for UI, storage, hashing, or interop with external systems.

```python
class AddressConverter(gl.Contract):
    # Demonstrates converting a stored Address into several representations and when to use them
    stored_address: Address
    
    def __init__(self, initial_address: str):
        # Store as Address (not string) so the value is validated and normalized once
        self.stored_address = Address(initial_address)
    
    @gl.public.view
    def get_address_hex(self) -> str:
        # Get EIP-55 checksum hex; ideal for UI display, logs, and user input round-trips
        return self.stored_address.as_hex
    
    @gl.public.view
    def get_address_bytes(self) -> bytes:
        # Get raw 20-byte representation; efficient for hashing and compact storage
        return self.stored_address.as_bytes
    
    @gl.public.view
    def get_address_b64(self) -> str:
        # Get base64 representation; useful for URLs and systems that prefer base64
        return self.stored_address.as_b64
    
    @gl.public.view
    def get_address_string(self) -> str:
        # Default string representation (same as as_hex)
        return str(self.stored_address)
    
    @gl.public.view
    def format_address(self, fmt: str) -> str:
        # Format with a specifier for consistent serialization across callers
        if fmt == "x":
            return f"{self.stored_address:x}"  # hex (checksummed)
        elif fmt == "b64":
            return f"{self.stored_address:b64}"  # base64 string
        elif fmt == "cd":
            return f"{self.stored_address:cd}"  # calldata/ABI-friendly format
        else:
            return str(self.stored_address)
```

## Address in Contract State

Store `Address` values directly in contract state for role management and registries. Collections like `DynArray[Address]` and `TreeMap[key, Address]` help model allowlists and name-to-address lookups safely.

```python
class AddressStorage(gl.Contract):
    # Store owner/admin roles and registries using Address-typed fields and collections
    # Single address storage
    owner: Address
    admin: Address
    
    # Address collections
    authorized_users: DynArray[Address]
    contract_registry: TreeMap[str, Address]
    
    def __init__(self):
        # Initialize roles to the transaction sender to establish initial permissions
        self.owner = gl.message.sender_address
        self.admin = gl.message.sender_address
    
    @gl.public.write
    def add_authorized_user(self, user_address: str):
        # Convert input to Address so membership checks use a normalized value
        address = Address(user_address)
        self.authorized_users.append(address)
    
    @gl.public.write
    def register_contract(self, name: str, contract_address: str):
        # Keep a normalized Address in the registry for consistent lookups
        address = Address(contract_address)
        self.contract_registry[name] = address
    
    @gl.public.view
    def is_authorized(self, user_address: str) -> bool:
        # Membership check with Address ensures exact, normalized equality semantics
        address = Address(user_address)
        return address in self.authorized_users
```

## Address in Method Parameters and Returns

Methods often accept human-friendly strings and return normalized `Address` data. Convert inputs at the boundary to keep state consistent and make API responses easy for clients to consume.

```python
class AddressOperations(gl.Contract):
    # Use Address as the key to guarantee consistent equality and map behavior
    balances: TreeMap[Address, u256]
    
    def __init__(self):
        # Start with an empty map; balances default to zero for missing keys
        pass    
        
    
    @gl.public.write
    def set_balance_from_hex(self, account_hex: str, amount: int):
        # Convert caller-provided hex into Address to validate and normalize before use
        account = Address(account_hex)
        self.balances[account] = amount
    
    @gl.public.view
    def get_my_balance(self) -> int:
        # Look up the balance associated with the message sender's Address
        return self.balances.get(gl.message.sender_address)

    @gl.public.view
    def get_balance(self, account_hex: str) -> int:
        # Convert external input to Address so lookups match normalized keys
        account = Address(account_hex)
        return self.balances.get(account)
    
    @gl.public.view
    def get_my_address(self) -> str:
        # Return the sender's address as a string; convenient for clients/UI
        return str(gl.message.sender_address)
    
```
