Skip to content

Instantly share code, notes, and snippets.

@019ec6e2
Created March 19, 2023 15:30
Show Gist options
  • Save 019ec6e2/3a001df0a6d0739843d1f8656c4e6b80 to your computer and use it in GitHub Desktop.
Save 019ec6e2/3a001df0a6d0739843d1f8656c4e6b80 to your computer and use it in GitHub Desktop.
Use this to parse smart contract source code downloaded from Etherscan API
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