def main(args): vm = None fname = args.file api = utils.getApi(args.web3) if not fname: if not args.hash: parser.error('hash is required to reproduce the tx if a trace file is not provided') #reproduce the tx if args.parity_evm: vm = VMUtils.ParityVM(args.parity_evm, not args.no_docker) else: vm = VMUtils.GethVM(args.geth_evm, not args.no_docker) artefacts, vm_args = reproduce.reproduceTx(args.hash, vm, api) saved_files = utils.saveFiles(OUTPUT_DIR, artefacts) fname = os.path.join(saved_files['json-trace']['path'], saved_files['json-trace']['name']) ops = loadJsonDebugStackTrace(fname) if ops == None: # Usually, each line is a json-object try: ops = loadJsonObjects(fname) except Exception as e: print("Error loading json:") traceback.print_exc() print("Trying alternate loader") ops = loadWeirdJson(fname) contexts = None if args.json: if not args.hash: parser.error('hash is required if contract json is provided') contracts = [] with open(args.json) as f: combined = json.load(f) sourceList = [os.path.join(args.source, s) for s in combined['sourceList']] for contract in combined['contracts'].keys(): val = combined['contracts'][contract] c = Contract(sourceList, val) contracts.append(c) contexts = buildContexts(ops, api, contracts, args.hash) if vm: print("\nTo view the generated trace:\n") cmd = "python3 opviewer.py -f %s" % fname if args.json: cmd += " --web3 %s -s %s -j %s --hash %s" % (args.web3, args.source, args.json, args.hash) print(cmd) DebugViewer().setTrace(ops, contexts)
def execute(code, gas=0xFFFF, verbose=False): from evmlab import vm from evmlab.genesis import Genesis gvm = VMUtils.GethVM("holiman/std-gethvm", docker=True) pvm = VMUtils.ParityVM("holiman/std-parityvm", docker=True) intrinsic_geth_gas = VMUtils.getIntrinsicGas(code) print("Intrinsic gas: %s" % str(intrinsic_geth_gas)) # sys.exit(0) g_out = gvm.execute(code=code, gas=gas, json=True, genesis=Genesis().export_geth()) p_out = pvm.execute(code=code, gas=gas, json=True, genesis=Genesis().export_parity()) g_canon = VMUtils.GethVM.canonicalized(g_out) p_canon = VMUtils.ParityVM.canonicalized(p_out) g_txt = [toText(x) for x in g_canon] p_txt = [toText(x) for x in p_canon] import logging logger = logging.getLogger() diff_found = vm.compare_traces([g_txt, p_txt], ['Geth', 'Par']) return (diff_found, [], gvm.lastCommand, pvm.lastCommand)
def main(args): if args.parity_evm: vm = VMUtils.ParityVM(args.parity_evm, not args.no_docker) else: vm = VMUtils.GethVM(args.geth_evm, not args.no_docker) parsed_web3 = urlparse(args.web3) if not parsed_web3.hostname: #User probably omitted 'http://' parsed_web3 = urlparse("http://%s" % args.web3) ssl = (parsed_web3.scheme == 'https') port = parsed_web3.port if not port: #Not explicitly defined if ssl: port = 443 else: port = 80 web3 = Web3(RPCProvider(host=parsed_web3.hostname, port=port, ssl=ssl)) api = multiapi.MultiApi(web3=web3, etherchain=etherchain.EtherChainAPI()) if args.test: artefacts = test(vm, api) import pprint pprint.PrettyPrinter().pprint(artefacts) sys.exit(0) if app and args.www: app.debug = args.debug app.api = api app.vm = vm app.run(host=args.www) elif args.hash: artefacts, vm_args = reproduce.reproduceTx(args.hash, vm, api) saved_files = saveFiles(artefacts) #Some tricks to get the right command for local replay p_gen = saved_files['parity genesis']['name'] g_gen = saved_files['geth genesis']['name'] vm_args['genesis'] = g_gen vm_args['dontExecuteButReturnCommand'] = True command = vm.execute(**vm_args) print("") print("Command to execute locally (geth):") print("") print("\t %s" % " ".join(command)) print("") (zipfilepath, zipfilename) = zipFiles(saved_files, args.hash[:8]) print("Zipped files into %s%s" % (zipfilepath, zipfilename)) else: parser.print_usage()
def main(args): if args.parity_evm: vm = VMUtils.ParityVM(args.parity_evm, not args.no_docker) else: vm = VMUtils.GethVM(args.geth_evm, not args.no_docker) api = utils.getApi(args.web3) if args.test: artefacts = test(vm, api) import pprint pprint.PrettyPrinter().pprint(artefacts) sys.exit(0) if app and args.www: if ':' in args.www: host, port = args.www.split(':') else: host = args.www port = 5000 app.debug = args.debug app.api = api app.vm = vm app.run(host=host, port=port) elif args.hash: artefacts, vm_args = reproduce.reproduceTx(args.hash, vm, api) saved_files = utils.saveFiles(OUTPUT_DIR, artefacts) #Some tricks to get the right command for local replay p_gen = saved_files['parity genesis']['name'] g_gen = saved_files['geth genesis']['name'] vm_args['genesis'] = "%s/%s" % (OUTPUT_DIR, g_gen) print("\nCommand to execute locally (geth):\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nWith memory:\n") vm_args['memory'] = True print("%s" % " ".join(vm.makeCommand(**vm_args))) vm_args.pop('json', None) vm_args.pop('memory', None) vm_args['statdump'] = "true" print("\nFor benchmarking:\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nFor opviewing:\n") print("python3 opviewer.py -f %s/%s" % (saved_files['json-trace']['path'], saved_files['json-trace']['name'])) print("\nFor opviewing with sources:\n") print( "python3 opviewer.py -f %s/%s --web3 '%s' -s path_to_contract_dir -j path_to_solc_combined_json --hash %s" % (saved_files['json-trace']['path'], saved_files['json-trace']['name'], args.web3, args.hash)) (zipfilepath, zipfilename) = zipFiles(saved_files, args.hash[:8]) print("\nZipped files into %s%s" % (zipfilepath, zipfilename)) else: parser.print_usage()
def main(): description = """ Tool to reproduce on-chain events locally. This can run either as a command-line tool, or as a webapp using a built-in flask interface. """ examples = """ Examples # Reproduce a tx with a local evm binary python3 reproducer.py --no-docker -g ~/go/src/github.com/ethereum/go-ethereum/build/bin/evm --hash 0xd6d519043d40691a36c9e718e47110309590e6f47084ac0ec00b53718e449fd3 # Reproduce a tx with a docker evm python3 reproducer.py -g holiman/gethvm --hash 0xd6d519043d40691a36c9e718e47110309590e6f47084ac0ec00b53718e449fd3 # Start the reproducer webapp using the default geth docker image: python3 reproducer.py -w localhost Unfinished: * This does not _quite_ work with parity, yet, because parity does not load the code in genesis for the 'to' -account, it expects the code to be given as an argument. """ parser = argparse.ArgumentParser( description=description, epilog=examples, formatter_class=argparse.RawDescriptionHelpFormatter) evmchoice = parser.add_mutually_exclusive_group() evmchoice.add_argument('-g', '--geth-evm', type=str, help="Geth EVM binary or docker image name", default="holiman/gethvm") evmchoice.add_argument('-p', '--parity-evm', type=str, default=None, help="Parity EVM binary or docker image name") parser.add_argument( "--no-docker", action="store_true", help="Set to true if using a local binary instead of a docker image") web_or_direct = parser.add_mutually_exclusive_group() web_or_direct.add_argument('-x', '--hash', type=str, help="Don't run webapp, just lookup hash") if app: web_or_direct.add_argument( '-w', '--www', type=str, help="Run webapp on given interface (interface:port)") parser.add_argument( '-d', '--debug', action="store_true", default=False, help= "Run flask in debug mode (WARNING: debug on in production is insecure)" ) parser.add_argument('-t', '--test', action="store_true", default=False, help="Dont run webapp, only local tests") web3settings = parser.add_argument_group( 'Web3', 'Settings about where to fetch information from (default infura)') web3settings.add_argument( "--web3", type=str, default="https://mainnet.infura.io/", help= "Web3 API url to fetch info from (default 'https://mainnet.infura.io/'" ) args = parser.parse_args() # end of arg handling if args.parity_evm: vm = VMUtils.ParityVM(args.parity_evm, not args.no_docker) else: vm = VMUtils.GethVM(args.geth_evm, not args.no_docker) api = utils.getApi(args.web3) if args.test: artefacts = test(vm, api) import pprint pprint.PrettyPrinter().pprint(artefacts) sys.exit(0) if app and args.www: if ':' in args.www: host, port = args.www.split(':') port = port else: host = args.www port = 5000 app.debug = args.debug app.api = api app.vm = vm app.run(host=host, port=port) elif args.hash: artefacts, vm_args = reproduce.reproduceTx(args.hash, vm, api) saved_files = utils.saveFiles(OUTPUT_DIR, artefacts) # Some tricks to get the right command for local replay p_gen = saved_files['parity genesis']['name'] g_gen = saved_files['geth genesis']['name'] vm_args['genesis'] = "%s/%s" % (OUTPUT_DIR, g_gen) print("\nCommand to execute locally (geth):\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nWith memory:\n") vm_args['memory'] = True print("%s" % " ".join(vm.makeCommand(**vm_args))) vm_args.pop('json', None) vm_args.pop('memory', None) vm_args['statdump'] = "true" print("\nFor benchmarking:\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nFor opviewing:\n") print("python3 opviewer.py -f %s/%s" % (saved_files['json-trace']['path'], saved_files['json-trace']['name'])) print("\nFor opviewing with sources:\n") print( "python3 opviewer.py -f %s/%s --web3 '%s' -s path_to_contract_dir -j path_to_solc_combined_json --hash %s" % (saved_files['json-trace']['path'], saved_files['json-trace']['name'], args.web3, args.hash)) logger.debug("creating zip archive for artefacts") prefix = args.hash[:8] output_archive = os.path.join(OUTPUT_DIR, "%s.zip" % prefix) # create a list of files to pack with zipFiles input_files = [(os.path.join(saved_files[v]['path'], saved_files[v]['name']), saved_files[v]['name']) for v in saved_files] create_zip_archive(input_files=input_files, output_archive=output_archive) print("\nZipped files into %s" % output_archive) else: parser.print_usage()
def main(args): if args.parity_evm: vm = VMUtils.ParityVM(args.parity_evm, not args.no_docker) else: vm = VMUtils.GethVM(args.geth_evm, not args.no_docker) parsed_web3 = urlparse(args.web3) if not parsed_web3.hostname: #User probably omitted 'http://' parsed_web3 = urlparse("http://%s" % args.web3) ssl = (parsed_web3.scheme == 'https') port = parsed_web3.port if not port: #Not explicitly defined if ssl: port = 443 else: port = 80 web3 = Web3(RPCProvider(host = parsed_web3.hostname,port= port ,ssl= ssl)) api = multiapi.MultiApi(web3 = web3, etherchain = etherchain.EtherChainAPI()) if args.test: artefacts = test(vm, api) import pprint pprint.PrettyPrinter().pprint(artefacts) sys.exit(0) if app and args.www: app.debug = args.debug app.api = api app.vm = vm app.run(host=args.www) elif args.hash: artefacts, vm_args = reproduce.reproduceTx(args.hash, vm, api) saved_files = saveFiles(artefacts) #Some tricks to get the right command for local replay p_gen = saved_files['parity genesis']['name'] g_gen = saved_files['geth genesis']['name'] vm_args['genesis'] = "%s/%s" % (OUTPUT_DIR, g_gen) print("\nCommand to execute locally (geth):\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nWith memory:\n") vm_args['memory'] = True print("%s" % " ".join(vm.makeCommand(**vm_args))) vm_args.pop('json', None) vm_args.pop('memory', None) vm_args['statdump'] = "true" print("\nFor benchmarking:\n") print("%s" % " ".join(vm.makeCommand(**vm_args))) print("\nFor opviewing:\n") print("python3 opviewer.py -f %s/%s" % (saved_files['json-trace']['path'],saved_files['json-trace']['name'])) (zipfilepath, zipfilename) = zipFiles(saved_files, args.hash[:8]) print("\nZipped files into %s%s" % (zipfilepath, zipfilename)) else: parser.print_usage()