80 lines
2.2 KiB
Python
80 lines
2.2 KiB
Python
from typing import Sequence
|
|
|
|
from ..constants import CONTRACT_ADDRESS_PREFIX, L2_ADDRESS_UPPER_BOUND
|
|
from .utils import (
|
|
HEX_PREFIX,
|
|
_starknet_keccak,
|
|
compute_hash_on_elements,
|
|
encode_uint,
|
|
get_bytes_length,
|
|
)
|
|
|
|
|
|
def compute_address(
|
|
*,
|
|
class_hash: int,
|
|
constructor_calldata: Sequence[int],
|
|
salt: int,
|
|
deployer_address: int = 0,
|
|
) -> int:
|
|
"""
|
|
Computes the contract address in the Starknet network - a unique identifier of the contract.
|
|
|
|
:param class_hash: class hash of the contract
|
|
:param constructor_calldata: calldata for the contract constructor
|
|
:param salt: salt used to calculate contract address
|
|
:param deployer_address: address of the deployer (if not provided default 0 is used)
|
|
:return: Contract's address
|
|
"""
|
|
|
|
constructor_calldata_hash = compute_hash_on_elements(data=constructor_calldata)
|
|
raw_address = compute_hash_on_elements(
|
|
data=[
|
|
CONTRACT_ADDRESS_PREFIX,
|
|
deployer_address,
|
|
salt,
|
|
class_hash,
|
|
constructor_calldata_hash,
|
|
],
|
|
)
|
|
|
|
return raw_address % L2_ADDRESS_UPPER_BOUND
|
|
|
|
|
|
def get_checksum_address(address: str) -> str:
|
|
"""
|
|
Outputs formatted checksum address.
|
|
|
|
Follows implementation of starknet.js. It is not compatible with EIP55 as it treats hex string as encoded number,
|
|
instead of encoding it as ASCII string.
|
|
|
|
:param address: Address to encode
|
|
:return: Checksum address
|
|
"""
|
|
if not address.lower().startswith(HEX_PREFIX):
|
|
raise ValueError(f"{address} is not a valid hexadecimal address.")
|
|
|
|
int_address = int(address, 16)
|
|
string_address = address[2:].zfill(64)
|
|
|
|
address_in_bytes = encode_uint(int_address, get_bytes_length(int_address))
|
|
address_hash = _starknet_keccak(address_in_bytes)
|
|
|
|
result = "".join(
|
|
(
|
|
char.upper()
|
|
if char.isalpha() and (address_hash >> 256 - 4 * i - 1) & 1
|
|
else char
|
|
)
|
|
for i, char in enumerate(string_address)
|
|
)
|
|
|
|
return f"{HEX_PREFIX}{result}"
|
|
|
|
|
|
def is_checksum_address(address: str) -> bool:
|
|
"""
|
|
Checks if provided string is in a checksum address format.
|
|
"""
|
|
return get_checksum_address(address) == address
|