crytic_compile.platform.standard
Standard crytic-compile export
1""" 2Standard crytic-compile export 3""" 4import json 5import os 6from collections import defaultdict 7from pathlib import Path 8from typing import TYPE_CHECKING, Dict, List, Tuple, Type, Any 9 10from crytic_compile.compilation_unit import CompilationUnit 11from crytic_compile.compiler.compiler import CompilerVersion 12from crytic_compile.platform import Type as PlatformType 13from crytic_compile.platform.abstract_platform import AbstractPlatform 14from crytic_compile.utils.naming import Filename 15 16# Cycle dependency 17from crytic_compile.utils.natspec import Natspec 18 19if TYPE_CHECKING: 20 from crytic_compile import CryticCompile 21 22 23def export_to_standard(crytic_compile: "CryticCompile", **kwargs: str) -> List[str]: 24 """Export the project to the standard crytic compile format 25 26 Args: 27 crytic_compile (CryticCompile): CryticCompile object to export 28 **kwargs: optional arguments. Used: "export_dir" 29 30 Returns: 31 List[str]: List of files generated 32 """ 33 # Obtain objects to represent each contract 34 35 output = generate_standard_export(crytic_compile) 36 37 export_dir = kwargs.get("export_dir", "crytic-export") 38 if not os.path.exists(export_dir): 39 os.makedirs(export_dir) 40 41 target = ( 42 "contracts" 43 if os.path.isdir(crytic_compile.target) 44 else Path(crytic_compile.target).parts[-1] 45 ) 46 47 path = os.path.join(export_dir, f"{target}.json") 48 with open(path, "w", encoding="utf8") as file_desc: 49 json.dump(output, file_desc) 50 51 return [path] 52 53 54class Standard(AbstractPlatform): 55 """ 56 Standard platform (crytic-compile specific) 57 """ 58 59 NAME = "Standard" 60 PROJECT_URL = "https://github.com/crytic/crytic-compile" 61 TYPE = PlatformType.STANDARD 62 63 HIDE = True 64 65 def __init__(self, target: str, **kwargs: str): 66 """Init the Standard platform 67 68 Args: 69 target (str): path to the target 70 **kwargs: optional arguments. Not used 71 72 """ 73 super().__init__(str(target), **kwargs) 74 self._underlying_platform: Type[AbstractPlatform] = Standard 75 self._unit_tests: List[str] = [] 76 77 def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None: 78 """Compile the file (load the file for the Standard platform) and populates the CryticCompile object 79 80 Args: 81 crytic_compile (CryticCompile): Associated CryticCompile 82 **_kwargs: optional arguments. Not used 83 84 """ 85 # pylint: disable=import-outside-toplevel 86 from crytic_compile.crytic_compile import get_platforms 87 88 with open(self._target, encoding="utf8") as file_desc: 89 loaded_json = json.load(file_desc) 90 (underlying_type, unit_tests) = load_from_compile(crytic_compile, loaded_json) 91 underlying_type = PlatformType(underlying_type) 92 platforms: List[Type[AbstractPlatform]] = get_platforms() 93 platform = next((p for p in platforms if p.TYPE == underlying_type), Standard) 94 self._underlying_platform = platform 95 self._unit_tests = unit_tests 96 97 def clean(self, **_kwargs: str) -> None: 98 """Clean compilation artifacts 99 100 Args: 101 **_kwargs: unused. 102 """ 103 return 104 105 @staticmethod 106 def is_supported(target: str, **kwargs: str) -> bool: 107 """Check if the target has the standard crytic-compile format 108 109 Args: 110 target (str): path to the target 111 **kwargs: optional arguments. Used: "standard_ignore" 112 113 Returns: 114 bool: True if the target is a crytic-compile generated project 115 """ 116 standard_ignore = kwargs.get("standard_ignore", False) 117 if standard_ignore: 118 return False 119 if not Path(target).parts: 120 return False 121 return Path(target).parts[-1].endswith("_export.json") 122 123 def is_dependency(self, path: str) -> bool: 124 """Check if the target is a dependency 125 This function always return false, the deps are handled by crytic_compile_dependencies 126 127 Args: 128 path (str): path to the target 129 130 Returns: 131 bool: Always False 132 """ 133 # handled by crytic_compile_dependencies 134 return False 135 136 def _guessed_tests(self) -> List[str]: 137 """Guess the potential unit tests commands 138 139 Returns: 140 List[str]: list of potential unit tests commands 141 """ 142 return self._unit_tests 143 144 @property 145 def platform_name_used(self) -> str: 146 """Return the name of the underlying platform used 147 148 Returns: 149 str: The name of the underlying platform used 150 """ 151 return self._underlying_platform.NAME 152 153 @property 154 def platform_project_url_used(self) -> str: 155 """Return the underlying platform project 's url 156 157 Returns: 158 str: Underlying platform project 's url 159 """ 160 return self._underlying_platform.PROJECT_URL 161 162 @property 163 def platform_type_used(self) -> PlatformType: 164 """Return the type of the underlying platform used 165 166 Returns: 167 PlatformType: Type of the underlying platform 168 """ 169 return self._underlying_platform.TYPE 170 171 172def _convert_filename_to_dict(filename: Filename) -> Dict: 173 """Convert the filename to a dict containing the four filename fields 174 175 Args: 176 filename (Filename): Filename to convert 177 178 Returns: 179 Dict: Dict with the four filenames fields 180 """ 181 return { 182 "absolute": filename.absolute, 183 "used": filename.used, 184 "short": filename.short, 185 "relative": filename.relative, 186 } 187 188 189def _convert_dict_to_filename(filename: Dict) -> Filename: 190 """Convert a dict to a Filename 191 This function should be called only on well formed json 192 193 Args: 194 filename (Dict): Json to convert 195 196 Returns: 197 Filename: Filename converted 198 """ 199 200 assert "absolute" in filename 201 assert "used" in filename 202 assert "short" in filename 203 assert "relative" in filename 204 205 return Filename( 206 absolute=filename["absolute"], 207 relative=filename["relative"], 208 short=filename["short"], 209 used=filename["used"], 210 ) 211 212 213def generate_standard_export(crytic_compile: "CryticCompile") -> Dict: 214 """Convert the CryticCompile object to a json 215 216 Args: 217 crytic_compile (CryticCompile): CryticCompile object to export 218 219 Returns: 220 Dict: CryticCompile converted to a json 221 """ 222 223 compilation_units = {} 224 libraries_to_update = crytic_compile.libraries 225 for key, compilation_unit in crytic_compile.compilation_units.items(): 226 source_unit_dict: Dict[str, Dict[str, Dict[str, Any]]] = {} 227 228 for filename, source_unit in compilation_unit.source_units.items(): 229 source_unit_dict[filename.relative] = defaultdict(dict) 230 source_unit_dict[filename.relative]["ast"] = source_unit.ast 231 for contract_name in source_unit.contracts_names: 232 libraries = source_unit.libraries_names_and_patterns(contract_name) 233 source_unit_dict[filename.relative]["contracts"][contract_name] = { 234 "abi": source_unit.abi(contract_name), 235 "bin": source_unit.bytecode_init(contract_name, libraries_to_update), 236 "bin-runtime": source_unit.bytecode_runtime(contract_name, libraries_to_update), 237 "srcmap": ";".join(source_unit.srcmap_init(contract_name)), 238 "srcmap-runtime": ";".join(source_unit.srcmap_runtime(contract_name)), 239 "filenames": _convert_filename_to_dict(filename), 240 "libraries": dict(libraries) if libraries else {}, 241 "is_dependency": crytic_compile.is_dependency(filename.absolute), 242 "userdoc": source_unit.natspec[contract_name].userdoc.export(), 243 "devdoc": source_unit.natspec[contract_name].devdoc.export(), 244 } 245 246 # Create our root object to contain the contracts and other information. 247 248 compiler: Dict = {} 249 if compilation_unit.compiler_version: 250 compiler = { 251 "compiler": compilation_unit.compiler_version.compiler, 252 "version": compilation_unit.compiler_version.version, 253 "optimized": compilation_unit.compiler_version.optimized, 254 } 255 256 compilation_units[key] = { 257 "compiler": compiler, 258 "source_units": source_unit_dict, 259 "filenames": [ 260 _convert_filename_to_dict(filename) for filename in compilation_unit.filenames 261 ], 262 } 263 264 output = { 265 "compilation_units": compilation_units, 266 "package": crytic_compile.package, 267 "working_dir": str(crytic_compile.working_dir), 268 "type": int(crytic_compile.platform.platform_type_used), 269 "unit_tests": crytic_compile.platform.guessed_tests(), 270 "crytic_version": "0.0.2", 271 } 272 return output 273 274 275def _load_from_compile_legacy1(crytic_compile: "CryticCompile", loaded_json: Dict) -> None: 276 """Load from old (old) export 277 278 Args: 279 crytic_compile (CryticCompile): CryticCompile object to populate 280 loaded_json (Dict): Json representation of the CryticCompile object 281 """ 282 compilation_unit = CompilationUnit(crytic_compile, "legacy") 283 compilation_unit.compiler_version = CompilerVersion( 284 compiler=loaded_json["compiler"]["compiler"], 285 version=loaded_json["compiler"]["version"], 286 optimized=loaded_json["compiler"]["optimized"], 287 ) 288 289 if "filenames" in loaded_json: 290 compilation_unit.filenames = [ 291 _convert_dict_to_filename(filename) for filename in loaded_json["filenames"] 292 ] 293 294 for path, ast in loaded_json["asts"].items(): 295 # The following might create lookup issue? 296 filename = crytic_compile.filename_lookup(path) 297 source_unit = compilation_unit.create_source_unit(filename) 298 source_unit.ast = ast 299 300 for contract_name, contract in loaded_json["contracts"].items(): 301 filename = _convert_dict_to_filename(contract["filenames"]) 302 compilation_unit.filename_to_contracts[filename].add(contract_name) 303 source_unit = compilation_unit.create_source_unit(filename) 304 305 source_unit.add_contract_name(contract_name) 306 source_unit.abis[contract_name] = contract["abi"] 307 source_unit.bytecodes_init[contract_name] = contract["bin"] 308 source_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"] 309 source_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";") 310 source_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(";") 311 source_unit.libraries[contract_name] = contract["libraries"] 312 313 userdoc = contract.get("userdoc", {}) 314 devdoc = contract.get("devdoc", {}) 315 source_unit.natspec[contract_name] = Natspec(userdoc, devdoc) 316 317 if contract["is_dependency"]: 318 compilation_unit.crytic_compile.dependencies.add(filename.absolute) 319 compilation_unit.crytic_compile.dependencies.add(filename.relative) 320 compilation_unit.crytic_compile.dependencies.add(filename.short) 321 compilation_unit.crytic_compile.dependencies.add(filename.used) 322 323 324def _load_from_compile_legacy2(crytic_compile: "CryticCompile", loaded_json: Dict) -> None: 325 """Load from old (old) export 326 327 Args: 328 crytic_compile (CryticCompile): CryticCompile object to populate 329 loaded_json (Dict): Json representation of the CryticCompile object 330 """ 331 332 for key, compilation_unit_json in loaded_json["compilation_units"].items(): 333 compilation_unit = CompilationUnit(crytic_compile, key) 334 compilation_unit.compiler_version = CompilerVersion( 335 compiler=compilation_unit_json["compiler"]["compiler"], 336 version=compilation_unit_json["compiler"]["version"], 337 optimized=compilation_unit_json["compiler"]["optimized"], 338 ) 339 340 if "filenames" in compilation_unit_json: 341 compilation_unit.filenames = [ 342 _convert_dict_to_filename(filename) 343 for filename in compilation_unit_json["filenames"] 344 ] 345 346 for path, ast in loaded_json["asts"].items(): 347 # The following might create lookup issue? 348 filename = crytic_compile.filename_lookup(path) 349 source_unit = compilation_unit.create_source_unit(filename) 350 source_unit.ast = ast 351 352 for contract_name, contract in compilation_unit_json["contracts"].items(): 353 354 filename = Filename( 355 absolute=contract["filenames"]["absolute"], 356 relative=contract["filenames"]["relative"], 357 short=contract["filenames"]["short"], 358 used=contract["filenames"]["used"], 359 ) 360 compilation_unit.filename_to_contracts[filename].add(contract_name) 361 362 source_unit = compilation_unit.create_source_unit(filename) 363 source_unit.add_contract_name(contract_name) 364 source_unit.abis[contract_name] = contract["abi"] 365 source_unit.bytecodes_init[contract_name] = contract["bin"] 366 source_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"] 367 source_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";") 368 source_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(";") 369 source_unit.libraries[contract_name] = contract["libraries"] 370 371 userdoc = contract.get("userdoc", {}) 372 devdoc = contract.get("devdoc", {}) 373 source_unit.natspec[contract_name] = Natspec(userdoc, devdoc) 374 375 if contract["is_dependency"]: 376 crytic_compile.dependencies.add(filename.absolute) 377 crytic_compile.dependencies.add(filename.relative) 378 crytic_compile.dependencies.add(filename.short) 379 crytic_compile.dependencies.add(filename.used) 380 381 382def _load_from_compile_0_0_1(crytic_compile: "CryticCompile", loaded_json: Dict) -> None: 383 for key, compilation_unit_json in loaded_json["compilation_units"].items(): 384 compilation_unit = CompilationUnit(crytic_compile, key) 385 compilation_unit.compiler_version = CompilerVersion( 386 compiler=compilation_unit_json["compiler"]["compiler"], 387 version=compilation_unit_json["compiler"]["version"], 388 optimized=compilation_unit_json["compiler"]["optimized"], 389 ) 390 391 compilation_unit.filenames = [ 392 _convert_dict_to_filename(filename) for filename in compilation_unit_json["filenames"] 393 ] 394 395 for path, ast in compilation_unit_json["asts"].items(): 396 # The following might create lookup issue? 397 filename = crytic_compile.filename_lookup(path) 398 source_unit = compilation_unit.create_source_unit(filename) 399 source_unit.ast = ast 400 401 for contracts_data in compilation_unit_json["contracts"].values(): 402 for contract_name, contract in contracts_data.items(): 403 404 filename = Filename( 405 absolute=contract["filenames"]["absolute"], 406 relative=contract["filenames"]["relative"], 407 short=contract["filenames"]["short"], 408 used=contract["filenames"]["used"], 409 ) 410 compilation_unit.filename_to_contracts[filename].add(contract_name) 411 source_unit = compilation_unit.create_source_unit(filename) 412 source_unit.add_contract_name(contract_name) 413 source_unit.abis[contract_name] = contract["abi"] 414 source_unit.bytecodes_init[contract_name] = contract["bin"] 415 source_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"] 416 source_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";") 417 source_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(";") 418 source_unit.libraries[contract_name] = contract["libraries"] 419 420 userdoc = contract.get("userdoc", {}) 421 devdoc = contract.get("devdoc", {}) 422 source_unit.natspec[contract_name] = Natspec(userdoc, devdoc) 423 424 if contract["is_dependency"]: 425 crytic_compile.dependencies.add(filename.absolute) 426 crytic_compile.dependencies.add(filename.relative) 427 crytic_compile.dependencies.add(filename.short) 428 crytic_compile.dependencies.add(filename.used) 429 430 431def _load_from_compile_current(crytic_compile: "CryticCompile", loaded_json: Dict) -> None: 432 for key, compilation_unit_json in loaded_json["compilation_units"].items(): 433 compilation_unit = CompilationUnit(crytic_compile, key) 434 compilation_unit.compiler_version = CompilerVersion( 435 compiler=compilation_unit_json["compiler"]["compiler"], 436 version=compilation_unit_json["compiler"]["version"], 437 optimized=compilation_unit_json["compiler"]["optimized"], 438 ) 439 440 compilation_unit.filenames = [ 441 _convert_dict_to_filename(filename) for filename in compilation_unit_json["filenames"] 442 ] 443 444 for filename_str, source_unit_data in compilation_unit_json["source_units"].items(): 445 filename = compilation_unit.filename_lookup(filename_str) 446 source_unit = compilation_unit.create_source_unit(filename) 447 448 for contract_name, contract in source_unit_data.get("contracts", {}).items(): 449 compilation_unit.filename_to_contracts[filename].add(contract_name) 450 451 source_unit = compilation_unit.create_source_unit(filename) 452 source_unit.add_contract_name(contract_name) 453 source_unit.abis[contract_name] = contract["abi"] 454 source_unit.bytecodes_init[contract_name] = contract["bin"] 455 source_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"] 456 source_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";") 457 source_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(";") 458 source_unit.libraries[contract_name] = contract["libraries"] 459 460 userdoc = contract.get("userdoc", {}) 461 devdoc = contract.get("devdoc", {}) 462 source_unit.natspec[contract_name] = Natspec(userdoc, devdoc) 463 464 if contract["is_dependency"]: 465 crytic_compile.dependencies.add(filename.absolute) 466 crytic_compile.dependencies.add(filename.relative) 467 crytic_compile.dependencies.add(filename.short) 468 crytic_compile.dependencies.add(filename.used) 469 470 source_unit.ast = source_unit_data["ast"] 471 472 473def load_from_compile(crytic_compile: "CryticCompile", loaded_json: Dict) -> Tuple[int, List[str]]: 474 """Load from a standard crytic compile json 475 This function must be called on well-formed json 476 477 Args: 478 crytic_compile (CryticCompile): CryticCompile object to populate 479 loaded_json (Dict): Json to load 480 481 Returns: 482 Tuple[int, List[str]]: (underlying platform types, guessed unit tests) 483 """ 484 crytic_compile.package_name = loaded_json.get("package", None) 485 if "compilation_units" not in loaded_json: 486 _load_from_compile_legacy1(crytic_compile, loaded_json) 487 488 elif "crytic_version" not in loaded_json: 489 _load_from_compile_legacy2(crytic_compile, loaded_json) 490 491 elif loaded_json["crytic_version"] == "0.0.1": 492 _load_from_compile_0_0_1(crytic_compile, loaded_json) 493 else: 494 _load_from_compile_current(crytic_compile, loaded_json) 495 496 crytic_compile.working_dir = loaded_json["working_dir"] 497 498 return loaded_json["type"], loaded_json.get("unit_tests", [])
24def export_to_standard(crytic_compile: "CryticCompile", **kwargs: str) -> List[str]: 25 """Export the project to the standard crytic compile format 26 27 Args: 28 crytic_compile (CryticCompile): CryticCompile object to export 29 **kwargs: optional arguments. Used: "export_dir" 30 31 Returns: 32 List[str]: List of files generated 33 """ 34 # Obtain objects to represent each contract 35 36 output = generate_standard_export(crytic_compile) 37 38 export_dir = kwargs.get("export_dir", "crytic-export") 39 if not os.path.exists(export_dir): 40 os.makedirs(export_dir) 41 42 target = ( 43 "contracts" 44 if os.path.isdir(crytic_compile.target) 45 else Path(crytic_compile.target).parts[-1] 46 ) 47 48 path = os.path.join(export_dir, f"{target}.json") 49 with open(path, "w", encoding="utf8") as file_desc: 50 json.dump(output, file_desc) 51 52 return [path]
Export the project to the standard crytic compile format
Args: crytic_compile (CryticCompile): CryticCompile object to export **kwargs: optional arguments. Used: "export_dir"
Returns: List[str]: List of files generated
55class Standard(AbstractPlatform): 56 """ 57 Standard platform (crytic-compile specific) 58 """ 59 60 NAME = "Standard" 61 PROJECT_URL = "https://github.com/crytic/crytic-compile" 62 TYPE = PlatformType.STANDARD 63 64 HIDE = True 65 66 def __init__(self, target: str, **kwargs: str): 67 """Init the Standard platform 68 69 Args: 70 target (str): path to the target 71 **kwargs: optional arguments. Not used 72 73 """ 74 super().__init__(str(target), **kwargs) 75 self._underlying_platform: Type[AbstractPlatform] = Standard 76 self._unit_tests: List[str] = [] 77 78 def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None: 79 """Compile the file (load the file for the Standard platform) and populates the CryticCompile object 80 81 Args: 82 crytic_compile (CryticCompile): Associated CryticCompile 83 **_kwargs: optional arguments. Not used 84 85 """ 86 # pylint: disable=import-outside-toplevel 87 from crytic_compile.crytic_compile import get_platforms 88 89 with open(self._target, encoding="utf8") as file_desc: 90 loaded_json = json.load(file_desc) 91 (underlying_type, unit_tests) = load_from_compile(crytic_compile, loaded_json) 92 underlying_type = PlatformType(underlying_type) 93 platforms: List[Type[AbstractPlatform]] = get_platforms() 94 platform = next((p for p in platforms if p.TYPE == underlying_type), Standard) 95 self._underlying_platform = platform 96 self._unit_tests = unit_tests 97 98 def clean(self, **_kwargs: str) -> None: 99 """Clean compilation artifacts 100 101 Args: 102 **_kwargs: unused. 103 """ 104 return 105 106 @staticmethod 107 def is_supported(target: str, **kwargs: str) -> bool: 108 """Check if the target has the standard crytic-compile format 109 110 Args: 111 target (str): path to the target 112 **kwargs: optional arguments. Used: "standard_ignore" 113 114 Returns: 115 bool: True if the target is a crytic-compile generated project 116 """ 117 standard_ignore = kwargs.get("standard_ignore", False) 118 if standard_ignore: 119 return False 120 if not Path(target).parts: 121 return False 122 return Path(target).parts[-1].endswith("_export.json") 123 124 def is_dependency(self, path: str) -> bool: 125 """Check if the target is a dependency 126 This function always return false, the deps are handled by crytic_compile_dependencies 127 128 Args: 129 path (str): path to the target 130 131 Returns: 132 bool: Always False 133 """ 134 # handled by crytic_compile_dependencies 135 return False 136 137 def _guessed_tests(self) -> List[str]: 138 """Guess the potential unit tests commands 139 140 Returns: 141 List[str]: list of potential unit tests commands 142 """ 143 return self._unit_tests 144 145 @property 146 def platform_name_used(self) -> str: 147 """Return the name of the underlying platform used 148 149 Returns: 150 str: The name of the underlying platform used 151 """ 152 return self._underlying_platform.NAME 153 154 @property 155 def platform_project_url_used(self) -> str: 156 """Return the underlying platform project 's url 157 158 Returns: 159 str: Underlying platform project 's url 160 """ 161 return self._underlying_platform.PROJECT_URL 162 163 @property 164 def platform_type_used(self) -> PlatformType: 165 """Return the type of the underlying platform used 166 167 Returns: 168 PlatformType: Type of the underlying platform 169 """ 170 return self._underlying_platform.TYPE
Standard platform (crytic-compile specific)
66 def __init__(self, target: str, **kwargs: str): 67 """Init the Standard platform 68 69 Args: 70 target (str): path to the target 71 **kwargs: optional arguments. Not used 72 73 """ 74 super().__init__(str(target), **kwargs) 75 self._underlying_platform: Type[AbstractPlatform] = Standard 76 self._unit_tests: List[str] = []
Init the Standard platform
Args: target (str): path to the target **kwargs: optional arguments. Not used
78 def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None: 79 """Compile the file (load the file for the Standard platform) and populates the CryticCompile object 80 81 Args: 82 crytic_compile (CryticCompile): Associated CryticCompile 83 **_kwargs: optional arguments. Not used 84 85 """ 86 # pylint: disable=import-outside-toplevel 87 from crytic_compile.crytic_compile import get_platforms 88 89 with open(self._target, encoding="utf8") as file_desc: 90 loaded_json = json.load(file_desc) 91 (underlying_type, unit_tests) = load_from_compile(crytic_compile, loaded_json) 92 underlying_type = PlatformType(underlying_type) 93 platforms: List[Type[AbstractPlatform]] = get_platforms() 94 platform = next((p for p in platforms if p.TYPE == underlying_type), Standard) 95 self._underlying_platform = platform 96 self._unit_tests = unit_tests
Compile the file (load the file for the Standard platform) and populates the CryticCompile object
Args: crytic_compile (CryticCompile): Associated CryticCompile **_kwargs: optional arguments. Not used
98 def clean(self, **_kwargs: str) -> None: 99 """Clean compilation artifacts 100 101 Args: 102 **_kwargs: unused. 103 """ 104 return
Clean compilation artifacts
Args: **_kwargs: unused.
106 @staticmethod 107 def is_supported(target: str, **kwargs: str) -> bool: 108 """Check if the target has the standard crytic-compile format 109 110 Args: 111 target (str): path to the target 112 **kwargs: optional arguments. Used: "standard_ignore" 113 114 Returns: 115 bool: True if the target is a crytic-compile generated project 116 """ 117 standard_ignore = kwargs.get("standard_ignore", False) 118 if standard_ignore: 119 return False 120 if not Path(target).parts: 121 return False 122 return Path(target).parts[-1].endswith("_export.json")
Check if the target has the standard crytic-compile format
Args: target (str): path to the target **kwargs: optional arguments. Used: "standard_ignore"
Returns: bool: True if the target is a crytic-compile generated project
124 def is_dependency(self, path: str) -> bool: 125 """Check if the target is a dependency 126 This function always return false, the deps are handled by crytic_compile_dependencies 127 128 Args: 129 path (str): path to the target 130 131 Returns: 132 bool: Always False 133 """ 134 # handled by crytic_compile_dependencies 135 return False
Check if the target is a dependency This function always return false, the deps are handled by crytic_compile_dependencies
Args: path (str): path to the target
Returns: bool: Always False
145 @property 146 def platform_name_used(self) -> str: 147 """Return the name of the underlying platform used 148 149 Returns: 150 str: The name of the underlying platform used 151 """ 152 return self._underlying_platform.NAME
Return the name of the underlying platform used
Returns: str: The name of the underlying platform used
154 @property 155 def platform_project_url_used(self) -> str: 156 """Return the underlying platform project 's url 157 158 Returns: 159 str: Underlying platform project 's url 160 """ 161 return self._underlying_platform.PROJECT_URL
Return the underlying platform project 's url
Returns: str: Underlying platform project 's url
163 @property 164 def platform_type_used(self) -> PlatformType: 165 """Return the type of the underlying platform used 166 167 Returns: 168 PlatformType: Type of the underlying platform 169 """ 170 return self._underlying_platform.TYPE
Return the type of the underlying platform used
Returns: PlatformType: Type of the underlying platform
Inherited Members
214def generate_standard_export(crytic_compile: "CryticCompile") -> Dict: 215 """Convert the CryticCompile object to a json 216 217 Args: 218 crytic_compile (CryticCompile): CryticCompile object to export 219 220 Returns: 221 Dict: CryticCompile converted to a json 222 """ 223 224 compilation_units = {} 225 libraries_to_update = crytic_compile.libraries 226 for key, compilation_unit in crytic_compile.compilation_units.items(): 227 source_unit_dict: Dict[str, Dict[str, Dict[str, Any]]] = {} 228 229 for filename, source_unit in compilation_unit.source_units.items(): 230 source_unit_dict[filename.relative] = defaultdict(dict) 231 source_unit_dict[filename.relative]["ast"] = source_unit.ast 232 for contract_name in source_unit.contracts_names: 233 libraries = source_unit.libraries_names_and_patterns(contract_name) 234 source_unit_dict[filename.relative]["contracts"][contract_name] = { 235 "abi": source_unit.abi(contract_name), 236 "bin": source_unit.bytecode_init(contract_name, libraries_to_update), 237 "bin-runtime": source_unit.bytecode_runtime(contract_name, libraries_to_update), 238 "srcmap": ";".join(source_unit.srcmap_init(contract_name)), 239 "srcmap-runtime": ";".join(source_unit.srcmap_runtime(contract_name)), 240 "filenames": _convert_filename_to_dict(filename), 241 "libraries": dict(libraries) if libraries else {}, 242 "is_dependency": crytic_compile.is_dependency(filename.absolute), 243 "userdoc": source_unit.natspec[contract_name].userdoc.export(), 244 "devdoc": source_unit.natspec[contract_name].devdoc.export(), 245 } 246 247 # Create our root object to contain the contracts and other information. 248 249 compiler: Dict = {} 250 if compilation_unit.compiler_version: 251 compiler = { 252 "compiler": compilation_unit.compiler_version.compiler, 253 "version": compilation_unit.compiler_version.version, 254 "optimized": compilation_unit.compiler_version.optimized, 255 } 256 257 compilation_units[key] = { 258 "compiler": compiler, 259 "source_units": source_unit_dict, 260 "filenames": [ 261 _convert_filename_to_dict(filename) for filename in compilation_unit.filenames 262 ], 263 } 264 265 output = { 266 "compilation_units": compilation_units, 267 "package": crytic_compile.package, 268 "working_dir": str(crytic_compile.working_dir), 269 "type": int(crytic_compile.platform.platform_type_used), 270 "unit_tests": crytic_compile.platform.guessed_tests(), 271 "crytic_version": "0.0.2", 272 } 273 return output
Convert the CryticCompile object to a json
Args: crytic_compile (CryticCompile): CryticCompile object to export
Returns: Dict: CryticCompile converted to a json
474def load_from_compile(crytic_compile: "CryticCompile", loaded_json: Dict) -> Tuple[int, List[str]]: 475 """Load from a standard crytic compile json 476 This function must be called on well-formed json 477 478 Args: 479 crytic_compile (CryticCompile): CryticCompile object to populate 480 loaded_json (Dict): Json to load 481 482 Returns: 483 Tuple[int, List[str]]: (underlying platform types, guessed unit tests) 484 """ 485 crytic_compile.package_name = loaded_json.get("package", None) 486 if "compilation_units" not in loaded_json: 487 _load_from_compile_legacy1(crytic_compile, loaded_json) 488 489 elif "crytic_version" not in loaded_json: 490 _load_from_compile_legacy2(crytic_compile, loaded_json) 491 492 elif loaded_json["crytic_version"] == "0.0.1": 493 _load_from_compile_0_0_1(crytic_compile, loaded_json) 494 else: 495 _load_from_compile_current(crytic_compile, loaded_json) 496 497 crytic_compile.working_dir = loaded_json["working_dir"] 498 499 return loaded_json["type"], loaded_json.get("unit_tests", [])
Load from a standard crytic compile json This function must be called on well-formed json
Args: crytic_compile (CryticCompile): CryticCompile object to populate loaded_json (Dict): Json to load
Returns: Tuple[int, List[str]]: (underlying platform types, guessed unit tests)