import asyncio
import aiohttp
import re
import requests

bscscan_api_key = '<TRUFFLEHOG_REDACTED_BSCSCAN>'
BASE_URL = "https://api.bscscan.com/api"

# Create a semaphore with a limit of n
semaphore = asyncio.Semaphore(5)


def remove_comments(source_code):
    source_code = re.sub(r"//.", "", source_code)
    source_code = re.sub(r" / *[\s\S]? * / ", "", source_code)
    return source_code


def get_contract_source_code(address):
    params = {
    "module": "contract",
    "action": "getsourcecode",
    "address": address,
    "apiKey": bscscan_api_key
    }
    response = requests.get(BASE_URL, params=params)
    data = response.json()

    if data["status"] == "1":
        source_code = data["result"][0]["SourceCode"]
        return remove_comments(source_code)
    else:
        return None


def find_similar_contracts(reference_addresses, candidate_addresses):
    reference_source_codes = {}
    for reference_address in reference_addresses:
        source_code = get_contract_source_code(reference_address)
        if source_code is not None:
            reference_source_codes[reference_address] = source_code

    if not reference_source_codes:
        print("No source code found for reference contracts")
        return []

    similar_contracts = {}
    for address in candidate_addresses:
        candidate_source_code = get_contract_source_code(address)
        if candidate_source_code is not None:
            for reference_address, reference_source_code in reference_source_codes.items():
                if candidate_source_code == reference_source_code:
                    if reference_address not in similar_contracts:
                        similar_contracts[reference_address] = [address]
                    else:
                        similar_contracts[reference_address].append(address)

    return similar_contracts


async def get_external_transactions(block_number):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            url = f'https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag={block_number}&boolean=true&apikey={bscscan_api_key}'

            try:
                async with session.get(url) as response:
                    data = await response.json()
            except Exception as e:
                print(f'Error in API request: {e}')
                return []

            if data['result'] is None or isinstance(data['result'], str):
                print(f"Error: Cannot find the block")
                return []

            return data['result'].get('transactions', [])

async def get_contract_address(tx_hash):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            url = f'https://api.bscscan.com/api?module=proxy&action=eth_getTransactionReceipt&txhash={tx_hash}&apikey={bscscan_api_key}'

            try:
                async with session.get(url) as response:
                    data = await response.json()
            except Exception as e:
                print(f'Error in API request: {e}')
                return None

            if data['result'] is None or not isinstance(data['result'], dict):
                return None

            return data['result'].get('contractAddress')

def check_method_id(input_data):
    method_id = input_data[:10]
    return method_id[-4:] == '6040'

async def display_transactions(block_start, block_end):
    async def process_block(block_number_int):
        block_number = hex(block_number_int)
        transactions = await get_external_transactions(block_number)

        if not transactions:
            print(f'No transactions found in block {block_number_int}')
        else:
            print(f'Transactions in block {block_number_int}:')
            for tx in transactions:
                if tx['to'] is None:
                    if check_method_id(tx['input']):
                        contract_address = await get_contract_address(tx['hash'])
                        if contract_address:
                            print(f'New contract creation: Contract Address: {contract_address}')
                            contract_addresses.append(contract_address)
            print("\n")  # Print an empty line between blocks

    tasks = [process_block(block_number) for block_number in range(block_start, block_end + 1)]
    await asyncio.gather(*tasks)

    return contract_addresses

async def main():
    block_start = 28466587  # Replace with your desired starting block number
    block_end = 28466640  # Replace with your desired ending block number

    contract_addresses = await display_transactions(block_start, block_end)

    return contract_addresses

contract_addresses = asyncio.run(main())

# … (The first code remains the same)

if __name__ == "main":
    # Replace this list with a list of reference contract addresses to check
    reference_addresses = ["0xEb275100cfe7B47bEAF38a2Dfef267B9006cA108"]

    # Replace this list with a list of candidate contract addresses to check
    candidate_addresses = contract_addresses

    similar_contracts = find_similar_contracts(reference_addresses, candidate_addresses)
    print("Contracts with similar source code (ignoring comments):")
    for reference_address, similar_addresses in similar_contracts.items():
        print(f"Reference contract: {reference_address}")
        for address in similar_addresses:
            print(f"Similar contract: {address}")

The code above throws an error

C:\Users\AshotxXx\PycharmProjects\Classes\venv\Scripts\python.exe C:\Users\AshotxXx\PycharmProjects\Classes\main.py 
Transactions in block 28466590:


Transactions in block 28466589:


Transactions in block 28466591:


Transactions in block 28466588:


Transactions in block 28466587:
Transactions in block 28466593:


Transactions in block 28466592:
Transactions in block 28466595:
Transactions in block 28466596:


Transactions in block 28466594:
Transactions in block 28466597:


Transactions in block 28466598:
Transactions in block 28466599:


Transactions in block 28466600:


Transactions in block 28466601:


Transactions in block 28466602:


Transactions in block 28466605:


Transactions in block 28466603:


Transactions in block 28466604:


Transactions in block 28466606:


Transactions in block 28466607:


Transactions in block 28466608:


Transactions in block 28466609:


Transactions in block 28466610:


Transactions in block 28466611:


Transactions in block 28466612:


Transactions in block 28466613:


Transactions in block 28466614:


Transactions in block 28466615:
Transactions in block 28466616:


Transactions in block 28466617:


Transactions in block 28466618:


Transactions in block 28466619:
Transactions in block 28466620:


Transactions in block 28466621:


Transactions in block 28466622:
Transactions in block 28466623:


Transactions in block 28466624:


Transactions in block 28466625:


Transactions in block 28466626:


Transactions in block 28466627:


Transactions in block 28466628:


Transactions in block 28466629:


Transactions in block 28466630:


Transactions in block 28466631:


Transactions in block 28466632:


Transactions in block 28466633:
Transactions in block 28466635:


Transactions in block 28466634:
Transactions in block 28466636:


Transactions in block 28466637:


Transactions in block 28466638:


Transactions in block 28466639:


Transactions in block 28466640:


New contract creation: Contract Address: 0x42ee2ae7f02694c73a5a5e10ca20a1cf8dba8e0f
Traceback (most recent call last):
  File "C:\Users\AshotxXx\PycharmProjects\Classes\main.py", line 131, in <module>
    contract_addresses = asyncio.run(main())
                         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AshotxXx\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\AshotxXx\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AshotxXx\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\AshotxXx\PycharmProjects\Classes\main.py", line 127, in main
    contract_addresses = await display_transactions(block_start, block_end)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\AshotxXx\PycharmProjects\Classes\main.py", line 119, in display_transactions
    await asyncio.gather(*tasks)
  File "C:\Users\AshotxXx\PycharmProjects\Classes\main.py", line 115, in process_block
    contract_addresses.append(contract_address)
    ^^^^^^^^^^^^^^^^^^
NameError: name 'contract_addresses' is not defined. Did you mean: 'contract_address'?

Process finished with exit code 1

Fix it