Intelligent Contracts
Types
Address Type

Address Type

The Address type represents a 20-byte blockchain address, similar to Ethereum addresses. It's one of the most important types in Intelligent Contracts 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.

# 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.

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.

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.

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)