Created
March 19, 2023 15:30
-
-
Save 019ec6e2/3a001df0a6d0739843d1f8656c4e6b80 to your computer and use it in GitHub Desktop.
Use this to parse smart contract source code downloaded from Etherscan API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
def is_single_file_contract(source_code: str) -> bool: | |
return ( | |
source_code.startswith("pragma") or | |
source_code.startswith("//") or | |
source_code.startswith("\r\n") or | |
source_code.startswith("/*") | |
) | |
def is_symbol_object(network: str) -> bool: | |
return "bsc" in network | |
def is_json_string(s: str) -> bool: | |
try: | |
json.loads(s) | |
except Exception: | |
return False | |
return True | |
def parse_source_code_object(source_code: str, network: str): | |
if is_symbol_object(network): | |
double_curly_braces_pattern = r'^\{\{(.|\r\n)*\}\}$' | |
if re.match(double_curly_braces_pattern, source_code): | |
source_code = source_code[1:-1] | |
return json.loads(source_code)["sources"] | |
return json.loads(source_code) | |
elif is_json_string(source_code): | |
return json.loads(source_code) | |
return json.loads(source_code[1:-1]) | |
def get_sources_object(parsed_source_code: dict, network: str): | |
if is_symbol_object(network): | |
return parsed_source_code.items() | |
if "sources" in parsed_source_code: | |
return parsed_source_code["sources"].items() | |
return parsed_source_code.items() | |
def get_contract_content_list(source_codes: list, network: str) -> list: | |
contract_content = [] | |
for source_code in source_codes: | |
if is_single_file_contract(source_code["SourceCode"]): | |
contract_content.append({ | |
"path": "contract.sol", | |
"content": source_code["SourceCode"] | |
}) | |
else: | |
parsed_source_code = parse_source_code_object( | |
source_code["SourceCode"], network | |
) | |
source_objects = [ | |
{"path": path, "content": content["content"]} | |
for path, content in get_sources_object(parsed_source_code, network) | |
] | |
contract_content.extend(source_objects) | |
return contract_content | |
def copy_to_clipboard(data: str): | |
import pyperclip | |
pyperclip.copy(data) | |
def cn(*classes: str) -> str: | |
return " ".join(filter(bool, classes)) | |
contract = 'contract_address' | |
api_key = 'your_etherscan_apikey' | |
url = f'https://api.etherscan.io/api?module=contract&action=getsourcecode&address={contract}&apikey={api_key}' | |
result = rs.get(url) | |
contracts = result.json()['result'][0]['SourceCode'] | |
parse_source_code_object(contracts, 'mainnet')['sources'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment