Files
ccxt_with_mt5/ccxt/static_dependencies/starknet/hash/address.py
lz_db 0fab423a18 add
2025-11-16 12:31:03 +08:00

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