def test_expand_token(project: Project): """Expand import statement in a Solidity source file, using Token contract.""" expanded, imported_files = expand_contract_imports(project, "CrowdsaleToken.sol") assert "contract CrowdsaleToken" in expanded assert 'import "' not in expanded assert "import '" not in expanded
def test_expand_crowdsale_contract(project: Project): """Expand import statement in a Solidity source file.""" expanded, imported_files = expand_contract_imports(project, "Crowdsale.sol") assert "contract Crowdsale" in expanded assert 'import "' not in expanded
def verify_contract(project: Project, chain_name: str, address: str, contract_name, contract_filename: str, constructor_args: str, libraries: dict, optimization=True, compiler: str = "v0.4.8+commit.60cc1668", browser_driver="chrome") -> str: """Semi-automated contract verified on Etherscan. Uses a web browser + Selenium auto fill to verify contracts. See the page in action: https://etherscan.io/verifyContract?a=0xcd111aa492a9c77a367c36e6d6af8e6f212e0c8e :return: Contract expanded source code """ try: from splinter import Browser except ImportError: raise RuntimeError( "Splinter package must be installed for verification automation") src, imported_files = expand_contract_imports(project, contract_filename) if chain_name == "mainnet": url = "https://etherscan.io/verifyContract" elif chain_name == "ropsten": url = "https://ropsten.etherscan.io/verifyContract" elif chain_name == "kovan": url = "https://kovan.etherscan.io/verifyContract" else: raise RuntimeError("Unknown chain: ".format(chain_name)) # Etherscan does not want 0x prefix if constructor_args.startswith("0x"): constructor_args = constructor_args[2:] with Browser(driver_name=browser_driver) as browser: browser.visit(url) browser.fill("ctl00$ContentPlaceHolder1$txtContractAddress", address) browser.fill("ctl00$ContentPlaceHolder1$txtContractName", contract_name) browser.select("ctl00$ContentPlaceHolder1$ddlCompilerVersions", compiler) browser.select("ctl00$ContentPlaceHolder1$ddlOptimization", "1" if optimization else "0") #browser.fill("ctl00$ContentPlaceHolder1$txtSourceCode", src) #browser.find_by_name("ctl00$ContentPlaceHolder1$txtSourceCode").first.value = src _fill_in_textarea_value( browser, browser.find_by_name("ctl00$ContentPlaceHolder1$txtSourceCode"), src) _fill_in_textarea_value( browser, browser.find_by_name( "ctl00$ContentPlaceHolder1$txtConstructorArguements"), constructor_args) #browser.fill("ctl00$ContentPlaceHolder1$txtConstructorArguements", constructor_args) idx = 1 for library_name, library_address in libraries.items(): browser.fill( "ctl00$ContentPlaceHolder1$txtLibraryAddress{}".format(idx), library_address) browser.fill( "ctl00$ContentPlaceHolder1$txtLibraryName{}".format(idx), library_name) idx += 1 browser.find_by_name("ctl00$ContentPlaceHolder1$btnSubmit").click() deadline = time.time() + 60 print("Waiting EtherScan to process the contract verification") while time.time() < deadline: if browser.is_text_present( "Successfully generated ByteCode and ABI for Contract Address", wait_time=1): return src if browser.is_text_present("already been verified"): print("The contract has already been verified") return src time.sleep(1.0) print("Contract verification failed. Check the browser for details.") input("Press enter to continue") return src
def verify_contract(project: Project, chain_name: str, address: str, contract_name, contract_filename: str, constructor_args: str, libraries: dict, optimization=True, optimizer_runs=200, compiler: str="v0.4.8+commit.60cc1668", browser_driver="chrome") -> str: """Semi-automated contract verified on Etherscan. Uses a web browser + Selenium auto fill to verify contracts. See the page in action: https://etherscan.io/verifyContract2 :return: Contract expanded source code """ try: from splinter import Browser except ImportError: raise RuntimeError("Splinter package must be installed for verification automation") src, imported_files = expand_contract_imports(project, contract_filename) if chain_name == "mainnet": url = "https://etherscan.io/verifyContract2" elif chain_name == "rinkeby": url = "https://rinkeby.etherscan.io/verifyContract2" elif chain_name == "ropsten": url = "https://ropsten.etherscan.io/verifyContract2" elif chain_name == "kovan": url = "https://kovan.etherscan.io/verifyContract2" else: raise RuntimeError("Unknown chain: ".format(chain_name)) # Etherscan does not want 0x prefix if constructor_args.startswith("0x"): constructor_args = constructor_args[2:] with Browser(driver_name=browser_driver) as browser: browser.visit(url) browser.fill("ctl00$ContentPlaceHolder1$txtContractAddress", address) browser.fill("ctl00$ContentPlaceHolder1$txtContractName", contract_name) browser.select("ctl00$ContentPlaceHolder1$ddlCompilerVersions", compiler) browser.select("ctl00$ContentPlaceHolder1$ddlOptimization", "1" if optimization else "0") browser.fill("ctl00$ContentPlaceHolder1$txtRuns", optimizer_runs) _fill_in_textarea_value(browser, browser.find_by_name("ctl00$ContentPlaceHolder1$txtSourceCode"), src) _fill_in_textarea_value(browser, browser.find_by_name("ctl00$ContentPlaceHolder1$txtConstructorArguements"), constructor_args) idx = 1 for library_name, library_address in libraries.items(): browser.fill("ctl00$ContentPlaceHolder1$txtLibraryAddress{}".format(idx),library_address) browser.fill("ctl00$ContentPlaceHolder1$txtLibraryName{}".format(idx), library_name) idx += 1 # Give the contract deployment some time to propagate so that Etherscan will find it time.sleep(30) browser.find_by_name("ctl00$ContentPlaceHolder1$btnSubmit").click() deadline = time.time() + 60 print("Waiting EtherScan to process the contract verification") while time.time() < deadline: if browser.is_text_present("Successfully generated ByteCode and ABI for Contract Address", wait_time=1): return src if browser.is_text_present("already been verified"): print("The contract has already been verified") return src time.sleep(1.0) print("Contract verification failed. Check the browser for details.") print("Make sure solc_version in your YAML file matches solc --version output.") print("Make sure solc optimization settings are the same as what EtherScan thinks.") input("Press enter to continue") return src