Skip to content

Instantly share code, notes, and snippets.

@laalaguer
Last active February 28, 2022 09:23
Show Gist options
  • Save laalaguer/0cee317aae7892be60bbf5638911502f to your computer and use it in GitHub Desktop.
Save laalaguer/0cee317aae7892be60bbf5638911502f to your computer and use it in GitHub Desktop.
Find block that one account has code
''' Python script to find the earliest block that an account has code.
python3 find.py [node_url] [address]
'''
import sys
from typing import Union
from thor_requests.connect import Connect
def account_has_code(connector: Connect, account_address: str, block_number: int) -> bool:
''' Fill your judgment function here, return True/False '''
account = connector.get_account(account_address, str(block_number))
return account['hasCode']
def get_best_block_number(connector: Connect) -> int:
''' Fill in your logic of : get "best" block, return the number of the block'''
block = connector.get_block("best", True)
return int(block["number"])
def binary_search(connector: Connect, account_address: str, start_n: int, end_n: int) -> Union[int, None]:
''' Find the first block number, that this account DOES NOT "hasCode"
This ensures we find it within log2(N) times, where N = end_n - start_n
N = 1 million, find it in 19.9 times
'''
print(f'Search blocks: {start_n} till {end_n}')
pivot = int((start_n + end_n) / 2)
if pivot == start_n or pivot == end_n:
return pivot
if account_has_code(connector, account_address, pivot):
return binary_search(connector, account_address, start_n, pivot)
else:
return binary_search(connector, account_address, pivot, end_n)
def earliest_block_that_account_does_not_have_code(connector: Connect, account_address: str):
''' Wrapper function to cover some edge cases '''
# Set up boundary
latest_block_n = get_best_block_number(connector)
first_block_n = 1
# Anti stupid
if not account_has_code(connector, account_address, latest_block_n):
raise Exception(f"Wow, this account {account_address} doesn't have code at all till now!")
# Anti stupid
if account_has_code(connector, account_address, first_block_n):
raise Exception(f"Wow, this account already has code before #{first_block_n} block, try go more way back!!")
# Now we sure to find the n in the between start and end
return binary_search(connector, account_address, first_block_n, latest_block_n)
if __name__ == "__main__":
node_url = sys.argv[1]
address = sys.argv[2]
connector = Connect(node_url)
result = earliest_block_that_account_does_not_have_code(connector, address)
print(result + 1) # This is the time when the account first "HAS" code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment