Last active
June 27, 2022 12:45
-
-
Save gosuto-inzasheru/f1be00d6b487f4faa585b00d23f805f1 to your computer and use it in GitHub Desktop.
generates a clean .sol interface file for any solidity contract address verified on etherscan
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 os | |
import re | |
import requests | |
import sys | |
from dotenv import load_dotenv | |
# https://etherscan.io/contract-license-types | |
# https://spdx.org/licenses/ | |
ETHERSCAN_TO_SPDX= { | |
'Unlicense': 'Unlicense', | |
'MIT': 'MIT', | |
'GNU GPLv2': 'GPL-2.0', | |
'GNU GPLv3': 'GPL-3.0', | |
'GNU LGPLv2.1': 'LGPL-2.1', | |
'GNU LGPLv3': 'LGPL-3.0', | |
'BSD-2-Clause': 'BSD-2-Clause', | |
'BSD-3-Clause': 'BSD-3-Clause', | |
'MPL-2.0': 'MPL-2.0', | |
'OSL-3.0': 'OSL-3.0', | |
'Apache-2.0': 'Apache-2.0', | |
'GNU AGPLv3': 'AGPL-3.0', | |
'BSL 1.1': 'BUSL-1.1', | |
} | |
def get_from_etherscan(address): | |
r = requests.get('https://api.etherscan.io/api', params={ | |
'module': 'contract', | |
'action': 'getsourcecode', | |
'address': address, | |
'apikey': os.getenv('ETHERSCAN_TOKEN'), | |
}).json() | |
if r['status'] != '1': | |
raise Exception(r['result']) | |
result = r['result'][0] | |
if result['Proxy'] != '0': | |
return get_from_etherscan(result['Implementation']) | |
contract = {} | |
contract['name'] = result['ContractName'] | |
try: | |
contract['license'] = ETHERSCAN_TO_SPDX[result['LicenseType']] | |
except KeyError: | |
contract['license'] = None | |
contract['version'] = re.findall( | |
r'v(\d+\.\d+\.\d+)\+', result['CompilerVersion'] | |
)[0] | |
contract['abi'] = result['ABI'] | |
return contract | |
def main(address): | |
load_dotenv() | |
dump_dir = 'interfaces/autogenerated/' | |
os.makedirs(dump_dir, exist_ok=True) | |
contract = get_from_etherscan(address) | |
dump_tmp = f'{dump_dir}I{contract["name"]}.tmp' | |
with open(dump_tmp, 'w') as f: | |
f.write(contract['abi']) | |
command = f'cat {dump_tmp} | abi-to-sol --validate -S -A' | |
if contract['license']: | |
command += f' -L={contract["license"]}' | |
if contract['version']: | |
command += f' -V=^{contract["version"]}' | |
command += f' I{contract["name"]} > {dump_dir}I{contract["name"]}.sol' | |
print(command) | |
os.system(command) | |
os.remove(dump_tmp) | |
if __name__ == '__main__': | |
main(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
INSTALLATION
generate_interface.py
to your brownie dirabi-to-sol
:prettier
and its solidity plugin alongsideabi-to-sol
:USAGE
it will generate a clean
.sol
interface file ininterfaces/autogenerated/
.TODO
0x1Ba86c33509013c937344f6e231DA2E63ea45197
)