Skip to content

Commit 02335af

Browse files
authoredMay 8, 2024··
Merge pull request #1772 from eth-brownie/fix-from-explorer
Fall back to ABI when `Contract.from_explorer` compilation fails
2 parents d6ab613 + 8f126dd commit 02335af

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed
 

‎brownie/network/contract.py

+51-40
Original file line numberDiff line numberDiff line change
@@ -998,11 +998,12 @@ def from_explorer(
998998
raise exc
999999
abi = json.loads(data_abi["result"].strip())
10001000
name = "UnknownContractName"
1001-
warnings.warn(
1002-
f"{address}: Was able to fetch the ABI but not the source code. "
1003-
"Some functionality will not be available.",
1004-
BrownieCompilerWarning,
1005-
)
1001+
if not silent:
1002+
warnings.warn(
1003+
f"{address}: Was able to fetch the ABI but not the source code. "
1004+
"Some functionality will not be available.",
1005+
BrownieCompilerWarning,
1006+
)
10061007

10071008
if as_proxy_for is None:
10081009
# always check for an EIP1967 proxy - https://eips.ethereum.org/EIPS/eip-1967
@@ -1084,40 +1085,49 @@ def from_explorer(
10841085
evm_version = None
10851086

10861087
source_str = "\n".join(data["result"][0]["SourceCode"].splitlines())
1087-
if source_str.startswith("{{"):
1088-
# source was verified using compiler standard JSON
1089-
input_json = json.loads(source_str[1:-1])
1090-
sources = {k: v["content"] for k, v in input_json["sources"].items()}
1091-
evm_version = input_json["settings"].get("evmVersion", evm_version)
1092-
remappings = input_json["settings"].get("remappings", [])
1093-
1094-
compiler.set_solc_version(str(version))
1095-
input_json.update(
1096-
compiler.generate_input_json(
1097-
sources, optimizer=optimizer, evm_version=evm_version, remappings=remappings
1088+
try:
1089+
if source_str.startswith("{{"):
1090+
# source was verified using compiler standard JSON
1091+
input_json = json.loads(source_str[1:-1])
1092+
sources = {k: v["content"] for k, v in input_json["sources"].items()}
1093+
evm_version = input_json["settings"].get("evmVersion", evm_version)
1094+
remappings = input_json["settings"].get("remappings", [])
1095+
1096+
compiler.set_solc_version(str(version))
1097+
input_json.update(
1098+
compiler.generate_input_json(
1099+
sources, optimizer=optimizer, evm_version=evm_version, remappings=remappings
1100+
)
10981101
)
1099-
)
1100-
output_json = compiler.compile_from_input_json(input_json)
1101-
build_json = compiler.generate_build_json(input_json, output_json)
1102-
else:
1103-
if source_str.startswith("{"):
1104-
# source was submitted as multiple files
1105-
sources = {k: v["content"] for k, v in json.loads(source_str).items()}
1102+
output_json = compiler.compile_from_input_json(input_json)
1103+
build_json = compiler.generate_build_json(input_json, output_json)
11061104
else:
1107-
# source was submitted as a single file
1108-
if compiler_str.startswith("vyper"):
1109-
path_str = f"{name}.vy"
1105+
if source_str.startswith("{"):
1106+
# source was submitted as multiple files
1107+
sources = {k: v["content"] for k, v in json.loads(source_str).items()}
11101108
else:
1111-
path_str = f"{name}-flattened.sol"
1112-
sources = {path_str: source_str}
1113-
1114-
build_json = compiler.compile_and_format(
1115-
sources,
1116-
solc_version=str(version),
1117-
vyper_version=str(version),
1118-
optimizer=optimizer,
1119-
evm_version=evm_version,
1120-
)
1109+
# source was submitted as a single file
1110+
if compiler_str.startswith("vyper"):
1111+
path_str = f"{name}.vy"
1112+
else:
1113+
path_str = f"{name}-flattened.sol"
1114+
sources = {path_str: source_str}
1115+
1116+
build_json = compiler.compile_and_format(
1117+
sources,
1118+
solc_version=str(version),
1119+
vyper_version=str(version),
1120+
optimizer=optimizer,
1121+
evm_version=evm_version,
1122+
)
1123+
except Exception as e:
1124+
if not silent:
1125+
warnings.warn(
1126+
f"{address}: Compilation failed due to {type(e).__name__}. Falling back to ABI,"
1127+
" some functionality will not be available.",
1128+
BrownieCompilerWarning,
1129+
)
1130+
return cls.from_abi(name, address, abi, owner)
11211131

11221132
build_json = build_json[name]
11231133
if as_proxy_for is not None:
@@ -1126,10 +1136,11 @@ def from_explorer(
11261136
if not _verify_deployed_code(
11271137
address, build_json["deployedBytecode"], build_json["language"]
11281138
):
1129-
warnings.warn(
1130-
f"{address}: Locally compiled and on-chain bytecode do not match!",
1131-
BrownieCompilerWarning,
1132-
)
1139+
if not silent:
1140+
warnings.warn(
1141+
f"{address}: Locally compiled and on-chain bytecode do not match!",
1142+
BrownieCompilerWarning,
1143+
)
11331144
del build_json["pcMap"]
11341145

11351146
self = cls.__new__(cls)

0 commit comments

Comments
 (0)