Example #1
0
def main():

    cloneaddr = 0x123456789A123456789A123456789A123456789A

    g = genesis.Genesis()
    g.setConfigMetropolis()
    g.add({
        'address': hex(cloneaddr),
        'nonce': 0,
        'code': "0x1337",
        'balance': 0
    })
    (geth_g, parity_g) = g.export()

    initcode = generateInitcode(cloneaddr)

    #geth = vm.GethVM("/home/martin/go/src/github.com/ethereum/go-ethereum/build/bin/evm")
    geth = vm.GethVM("holiman/gethvm", docker=True)
    print("Bytecode: ", initcode)

    g_out = geth.execute(code=initcode,
                         genesis=geth_g,
                         json=True,
                         gas=0xFFFF,
                         memory=True)

    for i in g_out:
        obj = json.loads(i)
        if 'stack' in obj.keys():
            print("{}  {}".format(obj['opName'], obj['stack']))
        else:
            print(i)
Example #2
0
def main():
    g = genesis.Genesis()

    g.setConfigMetropolis()

    (geth_g, parity_g) = g.export()
    print(parity_g)

    geth = vm.GethVM(
        "/home/martin/go/src/github.com/ethereum/go-ethereum/build/bin/evm")
    par = vm.ParityVM(executable="holiman/std-parityvm", docker=True)
    print("Bytecode: ")
    print(generateCall())

    g_out = geth.execute(code=generateCall(),
                         genesis=geth_g,
                         json=True,
                         gas=0xFFFF,
                         memory=True)
    p_out = par.execute(code=generateCall(),
                        genesis=parity_g,
                        json=True,
                        gas=0xFFFF,
                        memory=True)
    l = len(g_out)
    if len(p_out) < l:
        l = len(p_out)

    for i in range(0, l):
        print(g_out[i])
        print("g:" + vm.toText(json.loads(g_out[i])))
        print("p:" + vm.toText(json.loads(p_out[i])))
Example #3
0
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)
Example #4
0
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)
Example #5
0
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()
Example #6
0
def main():
    g = genesis.Genesis()
    g.setConfigMetropolis()
    (geth_g, parity_g) = g.export()

    geth = vm.GethVM(
        "/home/martin/go/src/github.com/ethereum/go-ethereum/build/bin/evm")
    outp = geth.execute(code=generateCall(), genesis=geth_g, json=True)
    prev = 0
    for l in outp:
        obj = json.loads(l)
        if 'gas' in obj.keys():
            g = int(obj['gas'], 16)
            print(l)
            print("Gas: %d (delta: %d)" % (g, (g - prev)))
            prev = g
Example #7
0
def main():
    g = genesis.Genesis()
    
    g.setConfigConstantinople()
    bytecode = generateCall()
    #print("code:", bytecode)
#    g.addPrestateAccount({'address':'0x0000000000000000000000000000000000000000', 'code': '0x'+bytecode, 'balance':"0x00",'nonce':"0x01"})

    (geth_g, parity_g) = g.export()
    print(parity_g)
    print(geth_g)

    geth = vm.GethVM("/home/martin/go/src/github.com/ethereum/go-ethereum/build/bin/evm")

    g_out = geth.execute(code = bytecode, receiver="0x0000000000000000000000000000000000000000", genesis = geth_g, json=True, gas=100000, memory=False)
    #print(geth.lastCommand)
    print("")
    l = len(g_out)
    for i in range(0,l):
        print(vm.toText(json.loads(g_out[i])))
def startGeth(test_case, test_tx):
    logger.info("running state test in geth.")
    genesis = gen.Genesis()
    for account_key in test_case['pre']:
        account = test_case['pre'][account_key]
        account['address'] = account_key
        genesis.addPrestateAccount(account)
    genesis.setCoinbase(test_case['env']['currentCoinbase'])
    genesis.setTimestamp(test_case['env']['currentTimestamp'])
    genesis.setGasLimit(test_case['env']['currentGasLimit'])
    genesis.setDifficulty(test_case['env']['currentDifficulty'])
    genesis.setBlockNumber(test_case['env']['currentNumber'])

    if cfg['FORK_CONFIG'] == 'Metropolis' or cfg['FORK_CONFIG'] == 'Byzantium':
        genesis.setConfigMetropolis()
    if cfg['FORK_CONFIG'] == 'Homestead':
        genesis.setConfigHomestead()

    geth_genesis = genesis.geth()
    g_path = genesis.export_geth()
    if sys.platform == "darwin":
        # OS X workaround for https://github.com/docker/for-mac/issues/1298 "The path /var/folders/wb/d8qys65575g8m2691vvglpmm0000gn/T/tmpctxz3buh.json is not shared from OS X and is not known to Docker."
        g_path = "/private" + g_path

    input_data = test_tx['data']
    if input_data[0:2] == "0x":
        input_data = input_data[2:]

    tx_to = test_tx['to']
    tx_value = parse_int_or_hex(test_tx['value'])
    gas_limit = parse_int_or_hex(test_tx['gasLimit'])
    gas_price = parse_int_or_hex(test_tx['gasPrice'])
    block_gaslimit = parse_int_or_hex(test_case['env']['currentGasLimit'])

    if gas_limit > block_gaslimit:
        logger.info("Tx gas limit exceeds block gas limit. not calling geth")
        return []

    sender = '0x' + getTxSender(test_tx)
    sender_balance = parse_int_or_hex(test_case['pre'][sender]['balance'])
    balance_required = (gas_price * gas_limit) + tx_value

    if balance_required > sender_balance:
        logger.info("Insufficient balance. not calling geth")
        return []

    intrinsic_gas = getIntrinsicGas(test_tx)
    if tx_to == "":
        # create contract cost not included in getIntrinsicGas
        intrinsic_gas += 32000

    if gas_limit < intrinsic_gas:
        logger.info("Insufficient startgas. not calling geth")
        return []

    if tx_to == "" and input_data == "":
        logger.info("no init code. not calling geth")
        return []

    if tx_to in test_case['pre']:
        if 'code' in test_case['pre'][tx_to]:
            if test_case['pre'][tx_to]['code'] == '':
                logger.info(
                    "To account in prestate has no code. not calling geth")
                return []

    vm = VMUtils.GethVM(executable=cfg['GETH_DOCKER_NAME'], docker=True)

    return vm.start(genesis=g_path,
                    gas=gas_limit,
                    price=gas_price,
                    json=True,
                    sender=sender,
                    receiver=tx_to,
                    input=input_data,
                    value=tx_value)
Example #9
0
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()
Example #10
0
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()
Example #11
0
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()