From 937bceb7d3ec3d25b0f5bf2d003d3c0f39a55692 Mon Sep 17 00:00:00 2001 From: seventh-dawn Date: Thu, 10 Nov 2022 19:02:44 +0100 Subject: [PATCH] Insert libraries data in the standard_json --- CHANGELOG.md | 1 + brownie/network/contract.py | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbd72a310..aa01f3326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This changelog format is based on [Keep a Changelog](https://keepachangelog.com/ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased](https://github.com/eth-brownie/brownie) +- Support the validation of contracts that include unlinked libraries ## [1.19.2](https://github.com/eth-brownie/brownie/tree/v1.19.2) - 2022-10-16 ### Added diff --git a/brownie/network/contract.py b/brownie/network/contract.py index 0d28b1996..5292c8258 100644 --- a/brownie/network/contract.py +++ b/brownie/network/contract.py @@ -425,13 +425,17 @@ def publish_source(self, contract: Any, silent: bool = False) -> bool: else: constructor_arguments = "" + standard_input_json_with_libraries = self._flatten_libraries_for_file( + self._flattener.standard_input_json + ) + # Submit verification payload_verification: Dict = { "apikey": api_key, "module": "contract", "action": "verifysourcecode", "contractaddress": address, - "sourceCode": io.StringIO(json.dumps(self._flattener.standard_input_json)), + "sourceCode": io.StringIO(json.dumps(standard_input_json_with_libraries)), "codeformat": "solidity-standard-json-input", "contractname": f"{self._flattener.contract_file}:{self._flattener.contract_name}", "compilerversion": f"v{contract_info['compiler_version']}", @@ -502,6 +506,36 @@ def _slice_source(self, source: str, offset: list) -> str: offset_start = max(0, offset_start) return source[offset_start : offset[1]].strip() + def _get_stripped_library(self, library_source_name, sources): + library_source = sources[library_source_name]["content"].split("\n") + lines = [] + for line in library_source: + if "pragma" in line: + continue + if "license" in line.lower(): + continue + lines.append(line) + return "\n".join(lines) + + def _flatten_libraries_for_file(self, standard_validation_json): + sources = standard_validation_json["sources"] + libraries = standard_validation_json["settings"]["libraries"] + files_requiring_libraries = list(libraries.keys()) + file_to_flatten = files_requiring_libraries[0] + libraries_files = [name.replace(".sol", "") + ".sol" for name in libraries[file_to_flatten]] + processed_lines = [] + contract_source = sources[file_to_flatten]["content"].split("\n") + for line in contract_source: + if "import" in line and any(file_name in line for file_name in libraries_files): + file_name = [name for name in libraries_files if name in line][0] + line = self._get_stripped_library(file_name, sources) + processed_lines.append(line) + new_source = "\n".join(processed_lines) + standard_validation_json["sources"][file_to_flatten] = {"content": new_source} + for library_name in libraries_files: + standard_validation_json["sources"].pop(library_name) + return standard_validation_json + class ContractConstructor: