class Eth::Address

def all_lowercase?

def all_lowercase?
  address.match(/(?:0[xX])[a-f0-9]{40}/)
end

def all_uppercase?

def all_uppercase?
  address.match(/(?:0[xX])[A-F0-9]{40}/)
end

def checksum

def checksum
  Utils.bin_to_hex(Utils.keccak256 unprefixed.downcase)
end

def checksum_matches?

def checksum_matches?
  address == checksummed
end

def checksummed

def checksummed
  raise "Invalid address: #{address}" unless matches_any_format?
  cased = unprefixed.chars.zip(checksum.chars).map do |char, check|
    check.match(/[0-7]/) ? char.downcase : char.upcase
  end
  Utils.prefix_hex(cased.join)
end

def initialize(address)

def initialize(address)
  @address = Utils.prefix_hex(address)
end

def matches_any_format?

def matches_any_format?
  address.match(/\A(?:0[xX])[a-fA-F0-9]{40}\z/)
end

def not_checksummed?

def not_checksummed?
  all_uppercase? || all_lowercase?
end

def unprefixed

def unprefixed
  Utils.remove_hex_prefix address
end

def valid?

def valid?
  if !matches_any_format?
    false
  elsif not_checksummed?
    true
  else
    checksum_matches?
  end
end