{ "info": { "author": "Martin Holst Swende", "author_email": "martin.swende@ethereum.org", "bugtrack_url": null, "classifiers": [], "description": "# EVM lab utilities\n\nThis package contains various tools to interact with the Ethereum virtual machine.\n\n## Project Structure\n\n| Folder | Description |\n| ------------ | ------------- |\n| docs | Project documentation |\n| evmlab | The evmlab package |\n| utilities | Example utilities and proof-of-concepts |\n| files | Sample trace files and trace logs |\n| output | output directory for artefacts |\n| templates | Web application templates (currently used with reproducer) |\n| containers | Docker container files |\n\n## Installation\n\n#### From source:\n\nConsider creating a virtualenv.\n\n #> virtualenv -p python3 .env3\n #> . .env3/bin/activate\n #> python3 -m pip install -r requirements.txt\n #> python3 setup.py install\n #> python3 -m evmlab # verify installation\n\n#### From PIP:\n\nTODO: publish to pip!\n\n #> python3 -m pip install evmlab\n #> python3 -m evmlab[consolegui,abidecoder,docker] # verify installation\n\nEVMLab comes with a commandline utility that can be invoked by calling `python3 -m evmlab `\n\n## Compiler\n\nThe 'compiler' is a tool to build evm binaries, using a pythonic way to construct the programs using assembly. \n\nHere's an example that tests `ecdsaRecover`:\n\n```python\n\n\tp = compiler.Program()\n\tp.mstore(0 ,0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)\n\tv = 0x000000000000000000000000000000000000000000000000000000000000001b\n\tp.mstore(32 , v)\n\tp.mstore(64 ,0x723841761d213b60ac1cbf063207cbeba6c2725bcaf7c189e63f13d93fc1dc07)\n\tp.mstore(96 ,0x789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02)\n\tp.call(0xfff,1,0,0,0x80,0x80,0x20)\n\tp.rreturn(140,20)\n\tcode = p.bytecode()\n```\n\nHere's an example of stuffing `JUMPDEST` into a program: \n\n```python\n\n\tp = compiler.Program()\n\tp.jump(0x3)\n\tp.jumpdest()\n\tp.rreturn()\n\tfor i in range(0,20000):\n\t\tp.op(JUMPDEST)\n\n\treturn p.bytecode()\n\n```\n\n## VM\n\nThe vm module contais some abstractions to run arbitrary virtual machines, primarily geth `evm` and parity's `parity-evm`. \n\n\n## Etherchain\n\nThe `etherchain` package contains an API for interacting with the Etherchain API.\n\n## Reproduce\n\nAn example app is `reproduce.py` which can reproduce an on-chain transaction as a totally local event, and run it in the `evm`. \n\nThe app takes a `txhash`, and \n\n1. Fetch the transaction data from an API. \n2. Mark (source, destination) as need-to-fetch\n3. Fetch balance and nonce at source, add to `genesis`\n4. Execute transaction on the `evm`\n5. If transaction has any externally reaching ops (BALANCE, EXTCODECOPY, CALL etc), \n * Add those accounts as need-to-fetch\n6. Go back to 3 until the execution does not result in any more accounts to be fetched. \n7. Save the transaction trace and genesis\n\n## Opviewer\n\nThe 'opviewer.py' is a simple debugger-like trace-viewer. It can be used against an `evm`-trace and navigate the data in a bit more friendly manner than raw json. \nInvoke via e.g. `python opviewer.py -f example2.json`\n\n![screenshot](https://raw.githubusercontent.com/holiman/evmlab/master/docs/example2.png)\n\n# Running it\n\nThe easiest way to get it working is to use a docker image. \n\n```\ndocker build . -t evmlab && docker run -it evmlab\n```\n\nThe docker image should also be available at hub.docker.com, as an automated build:\n\n```\ndocker pull holiman/evmlab && docker run -it holiman/evmlab\n```\n\n\n# EVM \n\n## EVM format\n\nHere's what to think about if you want to add an `evm` to evmlab. \n\n\n### Input\n\nThe `evm` should take the following inputs: \n\n* `--code ` - code to be executed.\n* `--codeFile ` - file containing code to be executed. Sometimes really large chunks of input cannot be passed through bash. \n* `--gas ` \n* `--price ` \n* `--sender
` - address of `ORIGIN`\n* `--receiver ` : `CALLDATA` \n* `--value `\n* `--json` - boolean flag, output json output for each opcode or not (it's useful to disable json when benchmarking)\n* `--nomemory` - disable showing the full memory output for each op\n* `--create` - if specified, it's executed as initcode\n* `--prestate` - a chain specification, the same one that the client normally would use. \n\nBasically, the `evm` should be able to run things very simply, like so: \n\n```bash\n$evm --code 6040 --json run\n{\"pc\":0,\"op\":96,\"gas\":\"0x2540be400\",\"gasCost\":\"0x3\",\"memory\":\"0x\",\"memSize\":0,\"stack\":[],\"depth\":1,\"error\":null,\"opName\":\"PUSH1\"}\n{\"pc\":2,\"op\":0,\"gas\":\"0x2540be3fd\",\"gasCost\":\"0x0\",\"memory\":\"0x\",\"memSize\":0,\"stack\":[\"0x40\"],\"depth\":1,\"error\":null,\"opName\":\"STOP\"}\n{\"output\":\"\",\"gasUsed\":\"0x3\",\"time\":141485}\n``` \n\nBut it should also be able to reconstruct an actual on-chain transaction, with complex options including prestate, where no `code` is passed, since it's already been showed into the `prestate`: \n\n```bash\n$evm --prestate /home/martin/workspace/evmlab/output//0xd6d519-genesis-geth_wq38zsy5.json --gas 150000 --sender 0x69ea6b31ef305d6b99bb2d4c9d99456fa108b02a --receiver 0xb97048628db6b661d4c2aa833e95dbe1a905b280 --input a9059cbb0000000000000000000000008eef795fd9150f118bddeca556a5a2a2438ab865000000000000000000000000000000000000000000000081ebd8ffd6b2a58000 --json run\n\n``` \n\n### Output\n\nThe `evm` should output a `json` object for each operation. Example: \n```\n{\"pc\":0,\"op\":96,\"gas\":\"0x2540be400\",\"gasCost\":\"0x3\",\"memory\":\"0x\",\"memSize\":0,\"stack\":[],\"depth\":1,\"error\":null,\"opName\":\"PUSH1\"}\n```\n\nRequired: `pc`, `op`, `gas`, `stack`, `depth`\nOptional: `opName`, `gasCost`, `error`\n\nThe `stack`, `memory` and `memSize` are the values _before_ execution of the op. \n\nAt the end of execution, some summarical info is good, e.g. \n```\n{\"output\":\"\",\"gasUsed\":\"0x3\",\"time\":141485}\n```\n\nWhen errors occur, geth and parity handles them differently. \n\nMinor changes to how things work is ok, we can handle discrepancies in format and minor quirks. \n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/ethereum/evmlab/tarball/v0.3.0.0.1", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ethereum/evmlab/", "keywords": "ethereum,transaction,debugger", "license": "GPLv3", "maintainer": "", "maintainer_email": "", "name": "Evmlab", "package_url": "https://pypi.org/project/Evmlab/", "platform": "", "project_url": "https://pypi.org/project/Evmlab/", "project_urls": { "Download": "https://github.com/ethereum/evmlab/tarball/v0.3.0.0.1", "Homepage": "https://github.com/ethereum/evmlab/" }, "release_url": "https://pypi.org/project/Evmlab/0.3.0.0.1/", "requires_dist": [ "requests", "web3", "eth-hash[pycryptodome]", "rlp (>=1.0)", "ethereum-input-decoder; extra == 'abidecoder'", "urwid; extra == 'consolegui'", "docker (==3.0.0); extra == 'docker'" ], "requires_python": "", "summary": "Ethereum EVM utilities", "version": "0.3.0.0.1" }, "last_serial": 4162259, "releases": { "0.3.0.0.1": [ { "comment_text": "", "digests": { "md5": "754eb6ca11bda07f2097f390a6ad1dbd", "sha256": "1b7e91ea48e8372bbf4acdf2cdeb25c033de28a59167af49579346145b357553" }, "downloads": -1, "filename": "Evmlab-0.3.0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "754eb6ca11bda07f2097f390a6ad1dbd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 48878, "upload_time": "2018-08-10T18:15:42", "url": "https://files.pythonhosted.org/packages/fd/52/eb6cf263afe4dd6d1e039e03def838b2c4968d56003e16c59d88969f6956/Evmlab-0.3.0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "75befb7e053f651ffe9a5685cb789a14", "sha256": "c94f2dd67fd1a43e69af5eb36d74d7404bc0259910d049df768f8d4d3991b436" }, "downloads": -1, "filename": "Evmlab-0.3.0.0.1.tar.gz", "has_sig": false, "md5_digest": "75befb7e053f651ffe9a5685cb789a14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42902, "upload_time": "2018-08-10T18:15:44", "url": "https://files.pythonhosted.org/packages/f8/45/c77563be448382270b0b9b44de13bb3eb0ddd4a29f9f62bca0dfe408e085/Evmlab-0.3.0.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "754eb6ca11bda07f2097f390a6ad1dbd", "sha256": "1b7e91ea48e8372bbf4acdf2cdeb25c033de28a59167af49579346145b357553" }, "downloads": -1, "filename": "Evmlab-0.3.0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "754eb6ca11bda07f2097f390a6ad1dbd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 48878, "upload_time": "2018-08-10T18:15:42", "url": "https://files.pythonhosted.org/packages/fd/52/eb6cf263afe4dd6d1e039e03def838b2c4968d56003e16c59d88969f6956/Evmlab-0.3.0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "75befb7e053f651ffe9a5685cb789a14", "sha256": "c94f2dd67fd1a43e69af5eb36d74d7404bc0259910d049df768f8d4d3991b436" }, "downloads": -1, "filename": "Evmlab-0.3.0.0.1.tar.gz", "has_sig": false, "md5_digest": "75befb7e053f651ffe9a5685cb789a14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42902, "upload_time": "2018-08-10T18:15:44", "url": "https://files.pythonhosted.org/packages/f8/45/c77563be448382270b0b9b44de13bb3eb0ddd4a29f9f62bca0dfe408e085/Evmlab-0.3.0.0.1.tar.gz" } ] }