Skip to content

Instantly share code, notes, and snippets.

@nedondev
Last active April 27, 2023 18:17
Show Gist options
  • Save nedondev/b5f6fc4526bcfdb65082aaebf3adae8c to your computer and use it in GitHub Desktop.
Save nedondev/b5f6fc4526bcfdb65082aaebf3adae8c to your computer and use it in GitHub Desktop.
Script to separate an etherscan verify contract to each file. Example contract: https://arbiscan.io/address/0x321f653eed006ad1c29d174e17d96351bde22649#code.
import sys
import os
import re
def get_object_identifier(identifier_words, content):
match_pattern = "\n("
for word in identifier_words:
match_pattern += "" + word + "|"
match_pattern = match_pattern[:-1] + ")(.+?)(\\s|\\})"
# print(match_pattern)
result = re.findall(match_pattern, content)
# print(result)
return result[0][1].strip()
def create_file_get_content_list(content):
file_content_list = []
# create path and get file content
for file in content.split("// File ")[1:]:
print("-"*80)
file_path = file.split("\n")[0]
file_dirs = "/".join(file_path.split("/")[:-1])
print(file_dirs)
print("File path:", file_path)
if not os.path.exists(file_dirs):
os.makedirs(file_dirs)
file_content = "\n".join(file.split("\n")[1:])
file_content_list.append([file_path, file_content])
return file_content_list
def gather_path_map(content_list):
path_map = {}
for content_index in range(len(content_list)):
# [0] = file_path
# [1] = content
# find library, interfac and contract
object_identifier = get_object_identifier(
["library", "interface", "contract"], content_list[content_index][1])
path_map[object_identifier] = content_list[content_index][0]
content_list[content_index].append(object_identifier)
return path_map
# get relative path from a to b
def get_relative_path(path_a, path_b):
path_a_split = path_a.split("/")
path_b_split = path_b.split("/")
match = 0
for b_split, a_split in zip(path_b_split, path_a_split):
if b_split == a_split:
match += 1
# import_unmatch_count = len(import_path_split) - match
current_unmatch_count = len(path_a_split) - match
head_path = ""
if current_unmatch_count == 1:
head_path = "./"
else:
head_path = "../" * (current_unmatch_count - 1)
tail_path = "/".join(path_b_split[match:])
return head_path + tail_path
def main(argv):
if len(argv) > 1:
filename = argv[1]
if not os.path.exists(filename):
sys.exit("Error: file not exist")
f = open(filename, "r")
content = f.read()
default_license = "".join(re.findall(
"(// SPDX-License-Identifier)(.+)(\n)", content)[0])
# print(content)
file_content_list = create_file_get_content_list(content)
path_map = gather_path_map(file_content_list)
# import dependencies
for file_content_index in range(len(file_content_list)):
# import object from path_map
import_list = []
path_map_temp = path_map.copy()
path_map_temp.pop(file_content_list[file_content_index][2])
# print(file_content[2])
# print("+"*80)
for identifier in path_map_temp:
result = re.search(
identifier, file_content_list[file_content_index][1])
if result:
import_list.append(path_map_temp[identifier])
for import_index in range(len(import_list)):
import_list[import_index] = get_relative_path(
file_content_list[file_content_index][0], import_list[import_index])
# print(import_list)
file_content_split = file_content_list[file_content_index][1].split(
"\n")
for split_index in range(len(file_content_split)):
if re.search("^pragma", file_content_split[split_index]):
file_content_list[file_content_index][1] = \
"\n".join(file_content_split[:split_index+1]
+ [""]
+ ["import \"" + import_path +
"\";" for import_path in import_list]
+ file_content_split[split_index + 1:])
break
# remove duplicate new line
file_content_split = file_content_list[file_content_index][1].split(
"\n")
previous_line = ""
result_lines = []
for split_index in range(len(file_content_split)):
if previous_line != file_content_split[split_index] or previous_line != "":
result_lines.append(file_content_split[split_index])
previous_line = file_content_split[split_index]
file_content_list[file_content_index][1] = "\n".join(result_lines)
# write to file
for file_content in file_content_list:
# [0] = file_path
# [1] = content
# [2] = object_identifier
fw = open(file_content[0], "w+")
if not re.findall("(// SPDX-License-Identifier)(.+)(\n)", file_content[1]):
file_content[1] = default_license + file_content[1]
# print("File content:", file_content[1])
fw.write(file_content[1])
fw.close()
# for path in path_map:
# print(path, path_map[path])
f.close()
pass
if __name__ == "__main__":
main(sys.argv)
else:
print("Executed when imported")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment