nimbus-eth1/nimbus/utils/address.nim

154 lines
4.9 KiB
Nim

# Nimbus
# Copyright (c) 2018 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import strformat, strutils, encodings, keccak, padding
proc toText*(c: cstring): string =
($c).convert(destEncoding="iso-8859-1")
proc toCanonicalAddress*(address: string): string =
# TODO
address
# address.toNormalizedAddress.decodeHex
template toCanonicalAddress*(address: cstring): string =
address.toText.toCanonicalAddress
proc forceBytesToAddress*(address: string): string =
padLeft(address[^20..^1], 20, "\x00")
template forceBytesToAddress*(address: cstring): string =
address.toText.forceBytesToAddress
proc generateContractAddress*(address: string, nonce: string): string =
""
# keccak(rlp.encode(@[address, nonce]))[^20..^1]
# proc isNormalizedAddress*(value: string): bool =
# # Returns whether the provided value is an address in it's normalized form
# if not value.isAddress:
# false
# else:
# value == value.toNormalizedAddress
# proc toNormalizedAddress*(address: string): string =
# # Converts an address to it's normalized hexidecimal representation
# if address.isHexAddress:
# address.normalizeHexAddress
# elif address.isBinaryAddress:
# address.normalizeBinaryAddress
# elif address.is32byteaddress:
# address.normalize32byteAddress
# else:
# raise newException(ValueError, &"Unknown address format {address}")
# proc toNormalizedAddress*(address: cstring): string =
# toNormalizedAddress(address.toText)
# proc isAddress*(value: string): bool
# # Checks if the given string is an address in any of the known formats
# if value.isChecksumFormattedAddress:
# value.isChecksumAddress
# elif value.isHexAddress:
# true
# elif value.isBinaryAddress:
# true
# elif value.is32byteAddress:
# true
# else:
# false
# proc toCanonicalAddress*(address: cstring): string =
# address.toText.toNormalizedAddress.decodeHex
# proc toCanonicalAddress*(address: string): string =
# address.toNormalizedAddress.decodeHex
# proc isHexAddress(value: string): cstring =
# # Checks if the given string is an address in hexidecimal encoded form
# if value.len notin {42, 40}:
# false
# else:
# value.isHex:
# proc isBinaryAddress(value: string): bool =
# # Checks if the given string is an address in raw bytes form
# value.len == 20
# proc is32byteAddress(value: string): bool =
# # Checks if the given string is an address in hexidecimal encoded form padded to 32 bytes
# let valueAsHex = ""
# if value.len == 32:
# valueAsHex = value.encodeHex
# elif value.len in {66, 64}:
# valueAsHex = value.add0xprefix
# else:
# return false
# if valueAsHex.isPrefixed("0x000000000000000000000000"):
# try:
# return valueAsHex.parseHexInt > 0
# except ValueError:
# false
# else:
# return false
# proc normalizeHexAddress(address: string): string =
# # Returns a hexidecimal address in its normalized hexidecimal representation
# address.toLowerAscii.add0xPrefix
# proc normalizeBinaryAddress(address: string): string =
# # Returns a raw binary address in its normalized hexidecimal representation
# address.encodeHex.normalizeHexAddress
# proc normalize32byteAddress(address: string): string =
# if address.len == 32:
# address[^20..^1].normalizeBinaryAddress
# elif address.len in {66, 64}:
# address[^40..^1].normalizeHexAddress
# else:
# raise newException(ValueError, "Invalid address(must be 32 byte value)")
# proc isCanonicalAddress(value: string): bool =
# if not value.isAddress
# false
# else:
# value == value.toCanonicalAddress
# proc isSameAddress(left: string, right: string): bool =
# # Checks if both addresses are same or not
# if not left.isAddress or not right.isAddress:
# raise newException(ValueError, "Both values must be valid addresses")
# else:
# left.toNormalizedAddress == right.toNormalizedAddress
# proc toChecksumAddress*(address: string): string =
# # Makes a checksum address
# let normAddress = address.toNormalizedAddress
# let addressHash = normAddress.remove0xPrefix.keccak.encodeHex
# var s = ""
# for z in 2 ..< 42:
# s.add(if addressHash[z].parseHexInt > 7: normAddress[z].toUpperAscii() else: normAddress[z])
# result = s.join("").add0xPrefix
# proc toChecksumAddress*(address: cstring): string =
# address.toText.toChecksumAddress
# proc isChecksumAddress(value: string): bool =
# if not value.isHexAddress:
# false
# else:
# value == value.toChecksumAddress
# proc isChecksumFormattedAddress*(value: string): bool =
# if not value.isHexAddress:
# false
# else:
# let r = value.remove0xPrefix
# r != r.toLowerAscii and r != r.toUpperAscii