Last active
April 27, 2023 18:17
-
-
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.
This file contains hidden or 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 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